Portal Community

Example 1 — Upload Invoice PDF

After generating an invoice PDF (base64-encoded), upload it to S3 with a structured key path and custom metadata.

PropertyValue
operationupload
credential_idaws-prod
bucketbizfirst-invoices
keyinvoices/$ctx.year/$ctx.month/$ctx.invoice_id.pdf
content$ctx.pdf_base64
content_encodingbase64
content_typeapplication/pdf
aclprivate
metadata{"invoice-id": "$ctx.invoice_id", "customer-id": "$ctx.customer_id"}
Success output includes object_url — store this in your database and include in the invoice email to the customer.

Example 2 — Generate Pre-Signed Download URL

Generate a 24-hour download link for a private contract PDF. The link is emailed to the customer for temporary access.

PropertyValue
operationgetPresignedUrl
credential_idaws-prod
bucketbizfirst-contracts
keycontracts/$ctx.contract_id/signed.pdf
url_actionget
expires_in86400 (24 hours)

The url field in the success output is sent via an Email node. When the 24-hour window expires, the link returns a 403 — enforcing the access window without any additional access management.

Example 3 — Customer Direct Upload URL

Generate a PUT pre-signed URL so a customer can upload a file directly to S3 from their browser — without the file passing through your servers.

PropertyValue
operationgetPresignedUrl
credential_idaws-prod
bucketbizfirst-uploads
keyuploads/$ctx.customer_id/$ctx.timestamp/$ctx.filename
url_actionput
expires_in900 (15 minutes)
content_typeapplication/pdf
// Downstream: return URL to the API caller for direct browser upload
{
  "upload_url": "$ctx.url",
  "expires_at": "$ctx.expires_at",
  "instructions": "PUT your file to this URL with Content-Type: application/pdf"
}

Example 4 — Partner File Ingestion Pipeline

A scheduled workflow lists new files in a partner's S3 prefix, downloads each one, processes the data, then moves the file to an archive prefix.

  1. ScheduledTrigger — runs every 15 minutes
  2. S3 (list) — bucket: partner-drops, prefix: incoming/, max_keys: 50
  3. Loop — iterates over $ctx.objects
  4. S3 (download) — key: $loop.key, output_format: text
  5. CodeExecute — parse CSV rows, validate, insert into database
  6. S3 (copy) — source_key: $loop.key, destination: archive/processed/
  7. S3 (delete) — delete original from incoming/ after copy
This idiomatic pattern ensures each file is processed exactly once and archived before deletion — preventing duplicate processing on retry and maintaining a full audit trail.

Example 5 — Backup Before Overwrite

Before overwriting an existing file (e.g. a configuration or template), copy the current version to a versioned backup path, then upload the new version. This gives you a complete history without needing S3 object versioning enabled.

  1. WebhookTrigger — receives new template file content
  2. S3 (copy) — back up the existing file:
    source_bucket: bizfirst-assets
    source_key: templates/email-welcome.html
    bucket: bizfirst-assets
    dest_key: templates/backups/email-welcome-$ctx.timestamp.html
  3. S3 (upload) — upload new version:
    key: templates/email-welcome.html
    file_data: $ctx.new_content
    content_type: text/html
  4. MongoDB (insert) — log the version event with backup key and author

Example 6 — Store AI-Generated Report

After a FlowAiAgent node generates a weekly business summary, upload it to S3, then generate a pre-signed URL and include it in a management email.

  1. ScheduledTrigger — Monday 08:00
  2. FlowAiAgent — generate weekly management summary (markdown format)
  3. S3 (upload):
    bucket: bizfirst-reports
    key: reports/$ctx.year/$ctx.month/weekly-summary-$ctx.date.md
    file_data: $node.reportAgent.result
    content_type: text/markdown
    acl: private
  4. S3 (getPresignedUrl):
    key: $node.uploadReport.key
    method: GET
    expires_in: 604800 (7 days)
  5. EmailSmtp — send to management team with download link
  6. Slack — post notification in #management channel with URL
// Email body snippet
Weekly summary is ready: Download Report
Generated: {@ $ctx.date } | Valid until: {@ $node.presign.expires_at }

IAM Policy for This Workflow (Principle of Least Privilege)

For a workflow that only needs to upload and generate pre-signed download URLs, use this minimal IAM policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:GetObject"],
      "Resource": "arn:aws:s3:::bizfirst-reports/*"
    }
  ]
}

Do not grant s3:* or bucket-level access. Scope permissions to the specific bucket and only the actions the workflow actually needs.

Key Pattern Summary

PatternOperations UsedNotes
Upload and shareupload → getPresignedUrlAlways store to private, share via time-limited URL
Customer uploadgetPresignedUrl (PUT)15-30 min expiry; enforce content-type to prevent arbitrary uploads
List and processlist → Loop → downloadUse continuation_token for buckets with >1000 objects
Archive and deletecopy → deleteAlways copy first — verify success before deleting source
Version before overwritecopy → uploadUse timestamp in backup key for a sortable version history