Bring Your Own Bucket
Configure an S3-compatible bucket as the output destination for RenderIO commands.
Bring Your Own Bucket
Business accounts can send command outputs directly to an AWS S3 or S3-compatible bucket. RenderIO encrypts the supplied credentials, uses them only to create short-lived upload URLs, and does not copy externally stored outputs into RenderIO-managed storage.
1. Create least-privilege credentials
Grant access only to the bucket and optional prefix RenderIO will use. The connection test writes, verifies, and deletes a temporary object, while production uploads may use multipart upload.
For AWS S3, this policy is a suitable starting point. Replace the bucket and prefix before applying it:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload"
],
"Resource": "arn:aws:s3:::YOUR_BUCKET/renderio/*"
}
]
}The s3:GetObject and s3:DeleteObject actions are required by the connection test. If you skip the test, the upload path itself requires only s3:PutObject and s3:AbortMultipartUpload.
2. Create a destination
POST /api/v1/storage-destinationscurl -X POST https://renderio.dev/api/v1/storage-destinations \
-H "Content-Type: application/json" \
-H "X-API-KEY: ffsk_your_api_key_here" \
-d '{
"name": "production-outputs",
"endpoint_url": "https://s3.us-east-1.amazonaws.com",
"region": "us-east-1",
"bucket": "your-company-media",
"prefix": "renderio",
"path_style": false,
"credentials": {
"access_key_id": "YOUR_ACCESS_KEY_ID",
"secret_access_key": "YOUR_SECRET_ACCESS_KEY"
}
}'The response contains a storage_destination_id such as sd_0123456789abcdef0123456789abcdef. Save this value for command requests. Secret credentials are never returned; only a masked access key ID is shown.
For Cloudflare R2, use https://ACCOUNT_ID.r2.cloudflarestorage.com as endpoint_url, auto as region, and set path_style to true. Other S3-compatible providers may have different endpoint, region, and addressing requirements.
Destination fields
| Field | Required | Description |
|---|---|---|
name | Yes | Unique label for this destination. |
endpoint_url | Yes | HTTPS S3-compatible endpoint. Raw IP addresses are rejected. |
region | Yes | Signing region, such as us-east-1 or auto. |
bucket | Yes | Destination bucket name. |
prefix | No | Key prefix. Leading and trailing slashes are removed. |
public_base_url | No | Public or CDN base URL used to construct storage_url. Omit it for a private bucket. |
path_style | No | Whether the bucket belongs in the URL path instead of the hostname. Defaults to false. |
credentials | Yes | access_key_id, secret_access_key, and optional session_token. |
endpoint_url, region, and bucket are immutable. Create a new destination if any of them need to change.
3. Test the connection
POST /api/v1/storage-destinations/:storageDestinationId/testcurl -X POST \
https://renderio.dev/api/v1/storage-destinations/sd_0123456789abcdef0123456789abcdef/test \
-H "X-API-KEY: ffsk_your_api_key_here"A successful test returns:
{ "ok": true }An unsuccessful connection test still returns HTTP 200, with ok: false and a safe error message. This lets you distinguish an authenticated test request from a provider-side connectivity or permission failure.
4. Send a command output to the bucket
Add storage_destination_id at the top level of any FFmpeg or yt-dlp command request:
curl -X POST https://renderio.dev/api/v1/run-ffmpeg-command \
-H "Content-Type: application/json" \
-H "X-API-KEY: ffsk_your_api_key_here" \
-d '{
"input_files": {
"in_video": "https://example.com/input.mp4"
},
"output_files": {
"out_video": "output.mp4"
},
"ffmpeg_command": "-i {{in_video}} -c:v libx264 {{out_video}}",
"storage_destination_id": "sd_0123456789abcdef0123456789abcdef"
}'curl -X POST https://renderio.dev/api/v1/run-ffmpeg-command \
-H "Content-Type: application/json" \
-H "X-API-KEY: ffsk_your_api_key_here" \
-d '{
"input_files": {
"in_video": "https://example.com/input.mp4"
},
"output_files": {
"out_video": "output.mp4"
},
"ffmpeg_command": "-i <<in_video>> -c:v libx264 <<out_video>>",
"storage_destination_id": "sd_0123456789abcdef0123456789abcdef"
}'Objects use this key layout:
{prefix}/{command_id}/{filename}When the command reaches SUCCESS, each external output includes:
{
"file_id": "550e8400-e29b-41d4-a716-446655440000",
"filename": "output.mp4",
"status": "STORED",
"rendi_store_type": "OUTPUT",
"storage_location": "EXTERNAL",
"external_uri": "s3://your-company-media/renderio/COMMAND_ID/output.mp4",
"external_object_key": "renderio/COMMAND_ID/output.mp4",
"storage_url": null,
"is_deleted": false
}For a private bucket, storage_url is null; use external_object_key with your own S3 SDK or delivery layer. If public_base_url was configured, storage_url contains the corresponding public or CDN URL.
Manage destinations
| Method | Path | Description |
|---|---|---|
GET | /api/v1/storage-destinations | List destinations. |
POST | /api/v1/storage-destinations | Create a destination. |
GET | /api/v1/storage-destinations/:storageDestinationId | Get a destination. |
PATCH | /api/v1/storage-destinations/:storageDestinationId | Update its name, prefix, public URL, path style, or credentials. |
DELETE | /api/v1/storage-destinations/:storageDestinationId | Disable it for future jobs. Existing bucket objects are not deleted. |
POST | /api/v1/storage-destinations/:storageDestinationId/test | Test write, verification, and cleanup. |
All endpoints require X-API-KEY authentication and a Business account. A destination can only be used by the account that created it.