Skip to content
Start free

AWS S3 Integration Guide

Open in ClaudeOpen in ChatGPT

This guide walks you through setting up AWS S3 integration to automatically upload generated PDFs and Word documents to your own S3 bucket.

DocSpring supports two methods of authentication for AWS S3:

Uses AWS Security Token Service (STS) to assume an IAM role in your AWS account. This is the recommended approach as it’s more secure than sharing access keys.

  1. In the IAM console, create a role. For the trusted entity, choose another AWS account and enter the DocSpring AWS account ID: 691950705664. Leave Require external ID unchecked, because DocSpring doesn’t send an external ID when it assumes the role.
  2. Give the role a permissions policy that only allows s3:PutObject on your bucket:
IAM Role Permissions
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": ["arn:aws:s3:::YOUR_BUCKET_NAME/*"]
}
]
}
  1. Name your role (must include docspring in lowercase)
  2. After creating the role, edit its trust relationship (trust policy) so that only DocSpring’s S3 upload user can assume it:
Trust Relationship
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::691950705664:user/service/docspring-s3-cross-account"
},
"Action": "sts:AssumeRole"
}
]
}
  1. Copy the role’s ARN. You’ll enter it in DocSpring as the AWS Role ARN.
  1. In DocSpring, go to Integrations → Manage S3 connections (US, EU)
  2. Click Create S3 Integration (or Create a new S3 integration if you don’t have one yet)
  3. Fill in the configuration:
  • Storage Provider: Amazon S3 (the default). For other providers, see S3-compatible storage
  • Authentication Type: Choose “Access Key” or “Role-based Authentication”
  • Bucket Name: Your S3 bucket name
  • Region: The AWS region where your bucket is located (e.g., “us-east-1”)

For access key authentication:

  • Access Key ID: Your AWS access key ID
  • Secret Access Key: Your AWS secret access key

For role-based authentication:

  • Role ARN: The ARN of the IAM role to assume
  • Submission Type: Choose which PDFs to upload:

    • Only Live (default)
    • Only Test
    • Both Live and Test

    Combined PDFs are uploaded with every setting.

  • Template IDs: Comma-separated list of template IDs. Only submissions for these templates are uploaded.

  • Folder IDs: Comma-separated list of folder IDs. Only submissions for templates in these folders (and their subfolders) are uploaded. When you set both Template IDs and Folder IDs, a submission is uploaded if its template matches either one. Leave both blank to upload submissions for every template. Combined PDFs aren’t filtered by template or folder.

  • API Token IDs: Comma-separated list to limit uploads to specific API tokens. Submissions created without an API token (for example from the dashboard or a web form) are still uploaded.

  • File Formats: Word documents (.docx), OpenDocument files (.odt), PDFs, or All files (default). A Word template’s submission has a Word document, an OpenDocument file or both, and a PDF too when the template makes one. A submission that made none of the chosen files uploads nothing. Combined PDFs are uploaded with PDFs and All files. An integration created before this setting was added uploads PDFs only: add {{ extension }} to its object key templates before you change it.

To stop uploading a kind of PDF, leave its path template blank. For example, leave Object Key Template for Combined PDFs blank to upload submissions but not combined PDFs.

Customize where files are stored in your bucket using Liquid templates.

  • account_id - Your DocSpring Account ID (e.g., acc_X3gQR5GN6tS6tcYgJs)
  • template_id - Template ID (e.g., tpl_eGc5CmFbPnCCmerqsx)
  • template_name - Template name (invalid characters replaced with underscore)
  • submission_id - Submission ID (e.g., sub_Gbxesk7Xf52Pq3KgT9)
  • timestamp - Processing time (e.g., 20180509094531)
  • date - Date (e.g., 20180509)
  • year - Year (e.g., 2018)
  • month - Month, not zero-padded (e.g., 5)
  • day - Day, not zero-padded (e.g., 9)
  • metadata.<key> - Any metadata values
  • extension - The file’s extension: pdf, docx for a Word template’s Word document, or odt for its OpenDocument file. With All files, use it in the submission templates so each file gets its own key.

For combined submissions, template_id, template_name, and submission_id aren’t available. Use this instead:

  • combined_submission_id - Combined submission ID (e.g., com_Zbetd3ayK4EK3J4Hf4)

New integrations start with these templates. A blank template skips that kind of upload.

submission_path_template: "live/templates/{{ template_id }}/{{ submission_id }}.{{ extension }}"
test_submission_path_template: "test/templates/{{ template_id }}/{{ submission_id }}.{{ extension }}"
combined_submission_path_template: "combined_submissions/{{ combined_submission_id }}.{{ extension }}"

Organize by date and template:

{{ year }}/{{ month }}/{{ template_name }}/{{ submission_id }}.{{ extension }}

Use metadata for organization:

clients/{{ metadata.client_id }}/{{ date }}_{{ submission_id }}.pdf
  1. Create a live submission through the API or web interface (or set Submission Type to include test submissions first)
  2. Check your S3 bucket for the uploaded PDF
  3. Check the submission’s actions array in the API response:
// The actions array will contain an aws_s3_upload entry
{
"actions": [{
"action_type": "aws_s3_upload",
"state": "processed", // "pending" before upload completes, "failed" or "error" if it failed
"error_message": null,
"result_data": {
"s3_region": "us-east-1",
"s3_bucket": "your-bucket",
"s3_key": "live/templates/tpl_123/sub_123.pdf",
"s3_url": "https://your-bucket.s3.amazonaws.com/live/templates/tpl_123/sub_123.pdf"
}
}]
}

Check if a PDF has been uploaded to S3:

const pdfHasBeenUploadedToS3Bucket = (submission) => {
if (submission["actions"].length === 0) return false;
const action = submission["actions"].find(
(a) => a.action_type === "aws_s3_upload",
);
return action && action.state === "processed";
};

If the upload fails because of your bucket or the integration’s settings, the action’s state is failed and its error_message explains why. Uploads that fail because access was denied are retried automatically, so they go through once you fix the policy. A timeout or an error at AWS sets the state to error, and DocSpring retries the upload. If uploads keep failing because of your settings, DocSpring emails you and eventually disables the integration (When an integration fails).

Set up S3 event notifications to receive webhooks when PDFs are uploaded to your bucket.

  • For access keys: Verify the IAM user has correct permissions
  • For roles: Check the role’s permissions and trust relationship
  • For roles: Ensure the role name includes docspring
  • For access keys: Ensure keys are correct and active
  • For roles: Verify the role ARN and trust relationship
  • Unknown or misspelled variables render as empty text instead of causing an error. Check the s3_key in the action’s result_data to see the key that was used
  • Ensure the template syntax is correct (use double curly braces)
  • Confirm the region matches your S3 bucket’s location

For additional help, contact DocSpring support.