> ## Documentation Index
> Fetch the complete documentation index at: https://www.nexrender.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload Rendering Results

By default, Nexrender stores rendered outputs on its own infrastructure and returns a time-limited `outputUrl` pointing to that storage. If you need outputs in your own bucket - for data residency, CDN integration, or clean room operation - add an `upload` object to any job payload.

## How It Works

When `upload` is present on a job, Nexrender uploads the rendered file to your bucket as soon as rendering completes. The `outputUrl` in the job response reflects the path in your storage rather than Nexrender's.

## Fields

**upload.provider** `string`

Storage provider. Currently `"s3"` (works with any S3-compatible endpoint including AWS S3, Cloudflare R2, Google Cloud Storage, MinIO, and others).

**upload.prefix** `string`

Folder path prefix applied to the uploaded filename. Use this to organise outputs by project, campaign, or date. For example, `"renders/campaign-42/"` will place outputs at `renders/campaign-42/<filename>.mp4` inside the bucket.

**upload.outputUrl** `string`

Base URL used to construct the `outputUrl` returned in the job response. If your bucket is served through a CDN, set this to your CDN base URL so the returned link is immediately usable in your product.

**upload.params.endpoint** `string`

S3-compatible API endpoint. Defaults to `https://s3.amazonaws.com` (AWS). Set this for non-AWS providers - see examples below.

**upload.params.region** `string` *required*

Storage region (e.g. `us-east-1`, `auto`).

**upload.params.bucket** `string` *required*

Target bucket name.

**upload.params.acl** `string`

Canned ACL applied to uploaded objects. Common values: `public-read`, `private`. Omit if your bucket policy manages access.

**upload.params.accessKeyId** `string` *required*

Access key ID for the storage provider. Use a [secret reference](https://www.nexrender.com/docs/cloud/jobs/secrets.md) - e.g. `${secrets.S3_KEY_ID}`.

**upload.params.accessKeySecret** `string` *required*

Secret access key. Use a [secret reference](https://www.nexrender.com/docs/cloud/jobs/secrets.md) - e.g. `${secrets.S3_KEY_SECRET}`.

## Examples

```json AWS S3 theme={null}
{
  "template": { "id": "YOUR_TEMPLATE_ID", "composition": "main" },
  "upload": {
    "provider": "s3",
    "prefix": "renders/campaign-42/",
    "outputUrl": "https://cdn.yourcompany.com/media",
    "params": {
      "region": "us-east-1",
      "bucket": "your-render-outputs",
      "acl": "public-read",
      "accessKeyId": "${secrets.S3_KEY_ID}",
      "accessKeySecret": "${secrets.S3_KEY_SECRET}"
    }
  }
}
```

```json Cloudflare R2 theme={null}
{
  "template": { "id": "YOUR_TEMPLATE_ID", "composition": "main" },
  "upload": {
    "provider": "s3",
    "prefix": "renders/",
    "outputUrl": "https://pub.r2.dev/your-bucket",
    "params": {
      "endpoint": "https://<ACCOUNT_ID>.r2.cloudflarestorage.com",
      "region": "auto",
      "bucket": "your-bucket",
      "accessKeyId": "${secrets.R2_ACCESS_KEY_ID}",
      "accessKeySecret": "${secrets.R2_ACCESS_KEY_SECRET}"
    }
  }
}
```

```json Google Cloud Storage theme={null}
{
  "template": { "id": "YOUR_TEMPLATE_ID", "composition": "main" },
  "upload": {
    "provider": "s3",
    "prefix": "renders/",
    "params": {
      "endpoint": "https://storage.googleapis.com",
      "region": "auto",
      "bucket": "your-gcs-bucket",
      "accessKeyId": "${secrets.GCS_ACCESS_KEY_ID}",
      "accessKeySecret": "${secrets.GCS_ACCESS_KEY_SECRET}"
    }
  }
}
```

> [!WARNING]
>
> Never embed storage credentials directly in a job payload. Store them as Nexrender secrets and reference them with the `${secrets.NAME}` syntax. See [Secrets Management](https://www.nexrender.com/docs/cloud/jobs/secrets.md).

## The outputUrl Field

The `outputUrl` you provide is a base URL that Nexrender uses to build the public link returned in the job response. Nexrender appends the output filename to this base:

```text theme={null}
outputUrl: "https://cdn.yourcompany.com/media"
prefix:    "renders/campaign-42/"
filename:  "01JOB_ID.mp4"

→ returned outputUrl: "https://cdn.yourcompany.com/media/renders/campaign-42/01JOB_ID.mp4"
```

If `outputUrl` is omitted, the returned link points directly into the bucket using the endpoint URL.

## Clean Room Setup

For a fully zero-retention configuration, combine `upload` with `template.src` so that neither template files nor render outputs are stored on Nexrender's infrastructure. See [Clean Room Setup](https://www.nexrender.com/docs/cloud/clean_room.md) for the full guide.

> [card] [Secrets Management](https://www.nexrender.com/docs/cloud/jobs/secrets.md)
>
> Store and reference storage credentials securely

> [card] [Clean Room Setup](https://www.nexrender.com/docs/cloud/clean_room.md)
>
> Zero data retention with your own storage


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.