object/upload FormID 20504
Upload an object to an S3 bucket. Supports base64-encoded binary or plain text data.
When to Use
- Report archiving: Store generated PDF or CSV reports to S3 after a workflow produces them, using a date-partitioned key for organized retrieval.
- Document intake: Accept user-submitted documents from a form workflow and persist them to S3 before initiating a review process.
- Data export storage: Write processed data exports to S3 at the end of an ETL pipeline for downstream consumers or compliance archiving.
- Database backup offload: Upload compressed database dump files to S3 with
GLACIERstorage class for cost-efficient long-term retention. - Static asset publishing: Upload versioned HTML, CSS, or JS assets to an S3 bucket configured as a static website or CloudFront origin.
Configuration
Connection
Credentials and region are not fields on this operation. Wire an S3 Server satellite node into this node's input. The satellite holds the vault credential (
ApiKey type — Username = access key ID, Password = secret key), the target AWS region, and an optional Service URL override for S3-compatible backends. Its values are merged onto this node at execution time and take precedence over anything set locally. See S3 Server (satellite) for the full field reference.
Tenant-prefixed:
objectKey is auto-prepended with tenants/{tenantId}/ before the upload. The value you type is what other S3 nodes in this workflow should reuse; the output's effectiveObjectKey field carries the literal key actually written, for use with the AWS console, CLI, or other external tools.
Operation Fields
| Field | Required | Description |
|---|---|---|
bucketName | Required | Target S3 bucket name. |
objectKey | Required | Full key path including any prefix (e.g. uploads/2026/05/report.pdf). Forward slashes create logical folder hierarchy. |
dataMode | Optional | Content encoding mode. base64 (default) for binary files; text for plain text or JSON content. |
contentType | Optional | MIME type of the object. Default: application/octet-stream. Use application/pdf, text/csv, image/png etc. for better browser handling. |
storageClass | Optional | S3 storage class. Default: STANDARD. Options: INTELLIGENT_TIERING, STANDARD_IA, ONE_ZONE_IA, GLACIER, DEEP_ARCHIVE. |
serverSideEncryption | Optional | Encryption algorithm. Default: AES256. Options: aws:kms, none. |
kmsKeyId | Optional | KMS key ARN. Required when serverSideEncryption is aws:kms. |
cannedAcl | Optional | Object-level ACL. Default: private. Options: public-read. |
cacheControl | Optional | Cache-Control header value for CDN/browser caching (e.g. max-age=86400). |
metadata | Optional | JSON object of custom user-defined metadata key-value pairs attached to the object. |
tagging | Optional | JSON key-value object of S3 tags applied to the object (e.g. {"Environment":"prod","Owner":"billing"}). |
Sample Configuration
// Credentials + region resolved from the connected S3 Server satellite — see s3-server-satellite.html
{
"resource": "object",
"operation": "upload",
"bucketName": "acme-prod-reports",
"objectKey": "monthly/{{ $now | date: 'YYYY/MM' }}/billing-summary-{{ $now | date: 'YYYY-MM' }}.pdf",
"dataMode": "base64",
"contentType": "application/pdf",
"storageClass": "STANDARD",
"serverSideEncryption": "AES256",
"cannedAcl": "private",
"metadata": {
"generatedBy": "billing-workflow",
"tenantId": "{{ $node.BillingJob.output.tenantId }}"
},
"tagging": {
"Environment": "production",
"DataClass": "confidential"
}
}
Validation Errors
| Error Code | Cause & Resolution |
|---|---|
ObjectTooLarge | The object exceeds the 5 GB single-part upload limit. Use multipart upload orchestration for large files. |
AccessDenied | The IAM identity lacks s3:PutObject permission on the target bucket/key. Update the IAM policy. |
InvalidArgument | The metadata or tagging JSON is malformed, or a metadata key/value contains invalid characters. Validate JSON structure before passing. |
NoSuchBucket | The target bucket does not exist. Create it first using bucket/create or verify the bucket name. |
KMSDisabledException | The specified KMS key is disabled. Enable the key in AWS KMS before uploading. |
Output
Success Port
| Field | Type | Description |
|---|---|---|
status | string | success on successful upload. |
errorCode | string | Empty string on success. |
bucketName | string | Target bucket name. |
objectKey | string | Full key of the uploaded object. |
eTag | string | MD5 ETag of the uploaded object — use for integrity verification. |
size | long | Size of the uploaded object in bytes. |
uploadedAt | string | ISO 8601 timestamp of the upload. |
storageClass | string | Storage class applied to the object. |
Error Port
On failure, activates with errorCode, errorMessage, and httpStatusCode. Route to a retry or alerting node. For ObjectTooLarge, route to a multipart upload sub-workflow.
Sample Output
{
"status": "success",
"errorCode": "",
"bucketName": "acme-prod-reports",
"objectKey": "monthly/2026/05/billing-summary-2026-05.pdf",
"eTag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
"size": 204800,
"uploadedAt": "2026-05-26T11:30:15Z",
"storageClass": "STANDARD"
}
Expression Reference
| Expression | Result |
|---|---|
{{ $node.UploadReport.output.objectKey }} | Full S3 key — use to construct a presigned URL or pass to an email attachment node. |
{{ $node.UploadReport.output.eTag }} | ETag value — log for data integrity audit trail. |
{{ $node.UploadReport.output.size }} | Object size in bytes — include in upload confirmation logs. |
{{ $node.UploadReport.output.uploadedAt }} | Upload timestamp — store in database record alongside the object key. |
{{ $node.UploadReport.output.storageClass }} | Confirm the applied storage class for cost accounting. |
Node Policies & GuardRails
| Policy Area | Recommendation |
|---|---|
| Credential Storage | Store credentials in BizFirst Credentials Manager. Never hardcode. |
| IAM Permissions | Grant s3:PutObject scoped to the specific bucket ARN and prefix (e.g. arn:aws:s3:::my-bucket/uploads/*). |
| Object Key Expression | Always use deterministic, expression-generated keys. Never write to a key derived from user input without sanitization — prevent path traversal patterns. |
| Default ACL | Always default to private. Never use public-read for objects containing PII or business-sensitive data. |
| Encryption | Set serverSideEncryption: AES256 minimum on all uploads. Use aws:kms for regulated data. |
| Content Type | Always set the correct contentType MIME type — prevents browser security issues when serving objects via presigned URLs. |
| Tagging for Cost Allocation | Apply resource tags (Environment, CostCenter, DataClass) to enable accurate S3 cost allocation reports per team or tenant. |
| ETag Audit Logging | Log eTag and objectKey to the workflow execution audit trail for every upload to enable future integrity verification. |
Examples
Example 1: Monthly Billing Report Archival
After generating a billing PDF, a workflow uploads it to S3 under a date-partitioned prefix and records the S3 key in the database.
// Node: GenerateReport (Code Execute → produces base64 PDF)
// Node: UploadToBilling (S3 — object/upload)
{
"bucketName": "acme-billing-archive",
"objectKey": "invoices/{{ $node.BillingJob.output.tenantId }}/{{ $now | date: 'YYYY-MM' }}.pdf",
"dataMode": "base64",
"contentType": "application/pdf",
"storageClass": "STANDARD_IA",
"serverSideEncryption": "AES256",
"metadata": { "invoiceId": "{{ $node.BillingJob.output.invoiceId }}" }
}
// Next: UpdateInvoiceRecord → set s3Key = objectKey
Example 2: Form Submission Document Storage
A form workflow accepts user-uploaded documents and stores them in S3 under the submitter's tenant folder.
// Node: StoreDocument (S3 — object/upload)
{
"bucketName": "acme-tenant-uploads",
"objectKey": "{{ $node.FormData.output.tenantId }}/{{ $node.FormData.output.submissionId }}/{{ $node.FormData.output.fileName }}",
"dataMode": "base64",
"contentType": "{{ $node.FormData.output.mimeType }}",
"serverSideEncryption": "AES256",
"tagging": {
"TenantId": "{{ $node.FormData.output.tenantId }}",
"SubmissionId": "{{ $node.FormData.output.submissionId }}"
}
}
// Next: ApprovalWorkflow with objectKey reference
Example 3: Static Site Asset Deployment
A CI/CD workflow uploads versioned static assets to S3 with public-read ACL and Cache-Control headers for CDN delivery.
// Node: UploadAssets (S3 — object/upload, inside Loop)
{
"bucketName": "acme-static-assets",
"objectKey": "v{{ $node.BuildInfo.output.version }}/{{ $loop.currentItem.filename }}",
"dataMode": "base64",
"contentType": "{{ $loop.currentItem.mimeType }}",
"storageClass": "STANDARD",
"cannedAcl": "public-read",
"cacheControl": "max-age=31536000, immutable",
"serverSideEncryption": "none"
}