Custom Storage (Bring Your Own Storage)
Store your renders in your own bucket. When custom storage is connected, every completed render is delivered to your AWS S3, Cloudflare R2, or any S3-compatible bucket, and the API response and webhooks include the URL of your copy in a storage_url field.
Availability: Scale and Enterprise plans. Configured by a team owner or admin in Account Settings.
Storage modes
Section titled “Storage modes”| Mode | What happens |
|---|---|
| Keep a copy on Templated (default) | Your bucket receives a copy of every render; Templated keeps its own copy too. Dashboard previews, merges and zips keep working exactly as before. |
| Store only in my bucket | Your bucket is the only durable home of the render. Templated’s transient copy is deleted right after your copy is confirmed. The url field of the render points to your bucket. |
- In Account Settings, open Custom Storage → Connect.
- Pick your provider: AWS S3, Cloudflare R2, or any S3-compatible service (MinIO, DigitalOcean Spaces…).
- Fill in the credentials (see provider examples below), bucket name, and an optional folder path (defaults to
renders). - Optionally set a Public Base URL (the public host where your objects are reachable, CDN or public bucket). It is used to build the
storage_urlreturned by the API. - Choose the storage mode and hit Connect. The connection is tested automatically; you can re-run it anytime with Test Connection.
Objects are written as {folder}/{render_id}.{format} (or {folder}/{render_id}/{name}.{format} for named renders). Templated never reads or lists objects in your bucket, and never deletes your renders. The only delete Templated ever performs is removing its own connection-test probe object.
Minimal IAM policy (AWS S3)
Section titled “Minimal IAM policy (AWS S3)”Templated only needs to write objects, plus delete for the connection-test probe object:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:PutObject", "s3:DeleteObject"], "Resource": "arn:aws:s3:::YOUR_BUCKET/renders/*" } ]}No GetObject, no ListBucket, no ACL permissions: objects are written without an ACL header, so buckets with the modern Object Ownership default work as-is.
Cloudflare R2
Section titled “Cloudflare R2”- Create an R2 API token with Object Read & Write scoped to your bucket.
- Use the S3 endpoint
https://<account-id>.r2.cloudflarestorage.com, regionauto. - R2 buckets have no public URL by default. Connect a custom domain to the bucket and set it as the Public Base URL.
API response
Section titled “API response”When custom storage is connected, render responses and webhooks include your copy:
{ "id": "9f24ff01-a03e-42f5-88ba-7dbec2771231", "status": "COMPLETED", "url": "https://cdn.templated.media/render/9f24ff01.png", "storage_url": "https://assets.yourcompany.com/renders/9f24ff01.png"}storage_url: the confirmed URL of the copy in your bucket.nullwhen custom storage is not connected or the delivery failed (Templated’s copy always survives a failed delivery).- With Store only in my bucket,
urlalso points to your bucket after delivery.