Skip to content

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.

ModeWhat 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 bucketYour 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.
  1. In Account Settings, open Custom StorageConnect.
  2. Pick your provider: AWS S3, Cloudflare R2, or any S3-compatible service (MinIO, DigitalOcean Spaces…).
  3. Fill in the credentials (see provider examples below), bucket name, and an optional folder path (defaults to renders).
  4. 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_url returned by the API.
  5. 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.

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.

  1. Create an R2 API token with Object Read & Write scoped to your bucket.
  2. Use the S3 endpoint https://<account-id>.r2.cloudflarestorage.com, region auto.
  3. R2 buckets have no public URL by default. Connect a custom domain to the bucket and set it as the Public Base URL.

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. null when custom storage is not connected or the delivery failed (Templated’s copy always survives a failed delivery).
  • With Store only in my bucket, url also points to your bucket after delivery.