> ## 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.

# Batch Jobs

> Submit up to 1,000 render jobs in a single API request and track them as a group

A batch lets you submit up to 1,000 render jobs in one `POST /batches` request. Each job in the batch follows the same schema as a single job. The API returns a `batchId` you can use to track progress and cancel the whole group at once.

Batches support partial success - if some jobs fail validation, the rest still proceed. The response tells you exactly which succeeded and which failed, with per-job error details.

## Submit a Batch

```bash Request theme={null}
curl -X POST https://api.nexrender.com/api/v2/batches \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jobs": [
      {
        "template": {
          "id": "01JTGM9GCR71JV7EJYDF45QAFD",
          "composition": "main"
        },
        "assets": [
          {
            "type": "text",
            "layerName": "name",
            "value": "Alice Johnson"
          }
        ],
        "webhook": {
          "url": "https://yourdomain.com/webhooks/render-complete"
        }
      },
      {
        "template": {
          "id": "01JTGM9GCR71JV7EJYDF45QAFD",
          "composition": "main"
        },
        "assets": [
          {
            "type": "text",
            "layerName": "name",
            "value": "Bob Williams"
          }
        ],
        "webhook": {
          "url": "https://yourdomain.com/webhooks/render-complete"
        }
      }
    ]
  }'
```

```json Response theme={null}
{
  "batchId": "01BATCH_ID_HERE",
  "status": "created",
  "totalJobs": 2,
  "successCount": 2,
  "jobs": [
    {
      "index": 0,
      "id": "01JOB_A_ID_HERE",
      "status": "queued",
      "outputUrl": "https://nx1-outputs-eu.nexrender.com/.../job-a.mp4"
    },
    {
      "index": 1,
      "id": "01JOB_B_ID_HERE",
      "status": "queued",
      "outputUrl": "https://nx1-outputs-eu.nexrender.com/.../job-b.mp4"
    }
  ]
}
```

Each entry in `jobs` includes an `index` that maps back to its position in the original request array, so you can correlate results even when some fail.

## Batch Creation Response

| Field | Type | Description |
| - | - | - |
| `batchId` | string | Unique identifier for this batch |
| `status` | string | `"created"` if all jobs succeeded, `"partial"` if some failed or a retry created only the missing jobs, `"error"` if all failed, `"replayed"` if a retry found every job already created |
| `totalJobs` | integer | Total number of jobs in the request |
| `successCount` | integer | Number of successfully created jobs |
| `jobs` | array | Details for each successfully created job |
| `errors` | array | Details for each failed job (only present when `status` is `"partial"` or `"error"`) |

### Partial Success Example

If a job fails validation, its entry appears in `errors` with an `index` matching its position in the original request. Successfully created jobs proceed normally.

```json theme={null}
{
  "batchId": "01BATCH_ID_HERE",
  "status": "partial",
  "totalJobs": 3,
  "successCount": 2,
  "jobs": [
    {
      "index": 0,
      "id": "01JOB_A_ID",
      "status": "queued",
      "outputUrl": "https://nx1-outputs-eu.nexrender.com/.../job-a.mp4"
    },
    {
      "index": 2,
      "id": "01JOB_C_ID",
      "status": "queued",
      "outputUrl": "https://nx1-outputs-eu.nexrender.com/.../job-c.mp4"
    }
  ],
  "errors": [
    {
      "index": 1,
      "error": "Template not found",
      "errorCode": "TEMPLATE_NOT_FOUND"
    }
  ]
}
```

## Retry a Batch Safely

A network error or timeout can leave you unsure whether a batch was created. To make a batch safe to resend, choose its `batchId` yourself: send a [ULID](https://github.com/ulid/spec) you generate in the request. Sending the batch again with the same `batchId` creates only the jobs that are not in it yet, so no job is rendered twice.

Give each job a `batchItemId` (up to 255 characters) so a retry can tell the jobs apart. Jobs without one are matched by their position in `jobs`, so if you leave it out, keep the order the same on every retry.

```json theme={null}
{
  "batchId": "01JZ8Q4V6T2M9X3K5R7B1N0C8D",
  "jobs": [
    {
      "batchItemId": "invite-alice",
      "template": { "id": "01JTGM9GCR71JV7EJYDF45QAFD", "composition": "main" },
      "assets": [{ "type": "text", "layerName": "name", "value": "Alice Johnson" }]
    },
    {
      "batchItemId": "invite-bob",
      "template": { "id": "01JTGM9GCR71JV7EJYDF45QAFD", "composition": "main" },
      "assets": [{ "type": "text", "layerName": "name", "value": "Bob Williams" }]
    }
  ]
}
```

A retry answers `200` instead of `201`:

| Status | Meaning |
| - | - |
| `replayed` | Every job was already in the batch. Nothing new was created. |
| `partial` | The jobs that were missing have been created now. |

The `jobs` array lists every job in the batch, with each `index` pointing to its position in the request you just sent.

Retries are recognised for 30 days, while the batch's jobs are kept. A retry after that, or a request without a `batchId`, creates a new batch.

> [!WARNING]
>
> Don't send two requests with the same `batchId` at the same time: if they overlap on the server, both can create jobs. A timeout on your side does not mean the server stopped working on the batch. After a timeout, poll `GET /batches/:batchId` until it stops changing, then retry.

### Retry Errors

| HTTP | `errorCode` | Meaning |
| - | - | - |
| `400` | `INVALID_BATCH_ID` | `batchId` is not a valid ULID. |
| `400` | `INVALID_BATCH_ITEM_ID` | A `batchItemId` is longer than 255 characters. |
| `400` | `DUPLICATE_BATCH_ITEM_ID` | Two jobs in the request have the same identifier. |
| `409` | `BATCH_ALREADY_PARTIAL` | The jobs already in the batch could not be matched with the request. Check `GET /batches/:batchId` before sending again. |
| `503` | `BATCH_RETRYABLE` | The service was briefly unavailable part-way through. The jobs created so far are listed. Wait for the `Retry-After` header's number of seconds, then retry with the same `batchId` to create the rest. |

## Check Batch Status

Poll `GET /batches/:batchId` to see aggregate progress across all jobs in the batch.

```bash Request theme={null}
curl -X GET https://api.nexrender.com/api/v2/batches/01BATCH_ID_HERE \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```json Response theme={null}
{
  "batchId": "01BATCH_ID_HERE",
  "status": "processing",
  "stats": {
    "total": 100,
    "finished": 67,
    "error": 2,
    "pending": 31
  },
  "jobs": [
    {
      "index": 0,
      "id": "01JOB_A_ID",
      "status": "finished",
      "outputUrl": "https://nx1-outputs-eu.nexrender.com/.../job-a.mp4"
    }
  ]
}
```

### Batch Status Values

| Status | Meaning |
| - | - |
| `processing` | At least one job is still running or queued |
| `finished` | All jobs have completed (some may have errored) |
| `error` | All jobs failed |

### Batch Stats Fields

| Field | Description |
| - | - |
| `total` | Total jobs in the batch |
| `finished` | Jobs that completed successfully |
| `error` | Jobs that failed |
| `pending` | Jobs still queued or rendering |

## Cancel a Batch

Cancel all remaining jobs in a batch with a single call. Jobs that have already finished are not affected.

```bash Request theme={null}
curl -X POST https://api.nexrender.com/api/v2/batches/01BATCH_ID_HERE/cancel \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```json Response theme={null}
{
  "batchId": "01BATCH_ID_HERE",
  "status": "cancelled",
  "totalJobs": 100,
  "cancelledCount": 33,
  "skippedCount": 67,
  "jobs": [
    {
      "index": 0,
      "id": "01JOB_A_ID",
      "result": "skipped",
      "status": "finished",
      "reason": "Job already in terminal state"
    },
    {
      "index": 5,
      "id": "01JOB_F_ID",
      "result": "cancelled",
      "status": "manually_cancelled"
    }
  ]
}
```

### Cancellation Response Status Values

| Status | Meaning |
| - | - |
| `cancelled` | Every cancellable job was cancelled |
| `partial` | Some jobs were cancelled, others were already in a terminal state |
| `unchanged` | No jobs were in a cancellable state |

Cancellation cascades to child jobs - if a batch job has nested children, they are cancelled too.

## When to Use Batches

* Rendering personalised videos for a large user list (event invites, product variants, certificates)
* Processing a bulk export where you want to submit all jobs upfront and track completion as a group
* Any workflow that needs atomic cancellation of many jobs at once

Each job in a batch is a full, independent job - it can include nested job assets, upload configuration, webhooks, and all other job options.

> [card] [Rendering Basics](https://www.nexrender.com/docs/cloud/jobs/rendering_basics.md)
>
> Learn the full job payload structure and asset types

> [card] [Nested Jobs](https://www.nexrender.com/docs/cloud/jobs/nested_jobs.md)
>
> Use nested job assets to render child compositions first


## OpenAPI

````yaml POST /batches
openapi: 3.0.4
info:
  title: Nexrender API
  version: '2.0'
  description: >
    REST API for the Nexrender cloud rendering platform, enabling programmatic
    control over After Effects template processing, job management, and asset
    handling.


    Features include:


    - Template upload and management (AEP, MOGRT, ZIP files)

    - Job creation and status monitoring with real-time progress

    - Job nesting for multi-composition renders (parent/child jobs)

    - Job stitching to combine multiple videos into one

    - Batch job creation for submitting up to 1000 jobs at once

    - Font library management for typography consistency

    - Secret management for secure API key storage

    - Webhook notifications for job lifecycle events

    - Asset injection for dynamic content replacement


    Authentication is required for all endpoints using Bearer token
    authorization.
servers:
  - url: https://api.nexrender.com/api/v2
    description: Production API server
security:
  - apiToken: []
paths:
  /batches:
    post:
      tags:
        - Batch Management
      summary: Create batch of jobs
      description: >-
        Submit multiple render jobs in a single request. Each job in the batch
        follows the same schema as a single job creation. Supports partial
        success - some jobs may succeed while others fail.
      operationId: createBatch
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchCreation'
      responses:
        '201':
          description: >-
            Batch created successfully. Check 'status' field: 'created' means
            all jobs succeeded, 'partial' means some failed (see 'errors'
            array).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchCreationResponse'
        '400':
          description: Invalid request or all jobs in the batch failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchCreationResponse'
        '401':
          description: Unauthorized - invalid or missing API token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Forbidden - license is not valid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    BatchCreation:
      type: object
      description: >-
        Configuration for creating a batch of render jobs in a single request (1
        to 1000 jobs)
      properties:
        jobs:
          type: array
          description: >-
            Array of job configurations to create as a batch. Each item follows
            the same schema as a single job creation request.
          items:
            $ref: '#/components/schemas/JobCreation'
          minItems: 1
          maxItems: 1000
      required:
        - jobs
    BatchCreationResponse:
      type: object
      description: >-
        Response after creating a batch of jobs, including per-job results and
        any errors
      properties:
        batchId:
          type: string
          description: Unique batch identifier in ULID format for tracking the entire batch
        status:
          type: string
          enum:
            - created
            - partial
            - error
          description: >-
            'created' if all jobs succeeded, 'partial' if some failed, 'error'
            if all failed
        totalJobs:
          type: integer
          description: Total number of jobs in the batch request
        successCount:
          type: integer
          description: Number of successfully created jobs
        jobs:
          type: array
          description: Array of successfully created job details
          items:
            type: object
            properties:
              index:
                type: integer
                description: Position of this job in the original request array
              id:
                type: string
                description: Unique job identifier
              status:
                type: string
                description: Initial job status ('queued' or 'pending' for parent jobs)
              outputUrl:
                type: string
                description: URL where the rendered output will be available
              children:
                type: array
                description: >-
                  Child job details (only present for jobs with nested job
                  assets)
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    status:
                      type: string
                    outputUrl:
                      type: string
                    missingFonts:
                      type: array
                      items:
                        type: string
              missingFonts:
                type: array
                items:
                  type: string
                description: >-
                  Fonts referenced in template but not found in team's font
                  library
        errors:
          type: array
          description: >-
            Array of errors for failed jobs (only present when status is
            'partial' or 'error')
          items:
            type: object
            properties:
              index:
                type: integer
                description: Position of the failed job in the original request array
              error:
                type: string
                description: Error message describing why the job failed
              errorCode:
                type: string
                description: Machine-readable error code
      required:
        - batchId
        - status
        - totalJobs
        - successCount
        - jobs
    ErrorResponse:
      type: object
      description: Standard error response format
      properties:
        error:
          type: string
          description: Human-readable error message explaining what went wrong
      required:
        - error
    JobCreation:
      type: object
      description: >-
        Configuration object for creating a new render job with template,
        assets, and options
      properties:
        template:
          $ref: '#/components/schemas/JobTemplate'
        preview:
          type: boolean
          default: false
          description: Generate a low-quality preview render instead of full quality output
        fonts:
          type: array
          items:
            type: string
          default: []
          description: List of font file names to include in the render environment
        assets:
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/JobAsset'
              - $ref: '#/components/schemas/JobAssetNested'
            discriminator:
              propertyName: type
              mapping:
                job: '#/components/schemas/JobAssetNested'
          default: []
          description: >-
            Collection of media assets (images, videos, audio, scripts, text) or
            nested job assets (type: 'job') to use in the render. Nested job
            assets render as child jobs first, with output injected into the
            parent composition. For supported NX layer functions,
            `params.layerName` can be a string or an array of strings; array
            values are expanded in place while preserving asset order.
        settings:
          type: object
          description: >-
            Render configuration settings for output format, quality, and frame
            selection
          properties:
            type:
              type: string
              enum:
                - video
                - image
                - aep
                - lottie
              description: >-
                Output render type - 'video' for MP4/MOV files, 'image' for
                PNG/JPG files, 'aep' for full archive, 'lottie' for a zip of a
                Lottie export (the team needs Lottie access)
            frames:
              oneOf:
                - type: integer
                  minimum: 0
                  description: Single frame number to render as image
                - type: array
                  items:
                    type: integer
                    minimum: 0
                  minItems: 2
                  maxItems: 2
                  description: Frame range [start, end] where end > start
              description: >-
                Frame specification - single frame number or [start, end] range.
                Required for image type.
            quality:
              type: string
              enum:
                - draft
                - full
              description: >-
                Render quality setting - 'draft' for faster low-quality preview,
                'full' for high-quality output
            codec:
              type: string
              description: >-
                Output codec specification (e.g., 'h264_vbr_15mbps',
                'prores_422', 'png', 'jpeg')
            engine:
              type: string
              enum:
                - ae2025
                - ae2026
              default: ae2026
              description: >-
                After Effects render engine version used when the job is picked
                up by a worker
            multiFrame:
              type: boolean
              description: >-
                Turn After Effects Multi-Frame Rendering on (true) or off
                (false) for this job. If omitted, the worker's own setting
                applies
            lottie:
              type: object
              description: >-
                Bodymovin settings for a 'lottie' job, e.g. export_modes,
                should_encode_images, rasterize_text. Only some settings can be
                changed; see the Lottie docs. Not allowed with other types.
              additionalProperties: true
          additionalProperties: false
        upload:
          type: object
          description: >-
            Custom upload configuration for output files to external storage
            providers
          properties:
            prefix:
              type: string
              description: >-
                Folder prefix/path where output files will be stored (e.g.,
                'my-project/outputs/')
            outputUrl:
              type: string
              description: Custom base URL for accessing uploaded files publicly
            provider:
              type: string
              enum:
                - s3
              default: s3
              description: Storage provider - 's3' for Amazon S3 compatible
            params:
              type: object
              description: Provider-specific upload parameters and credentials
              properties:
                endpoint:
                  type: string
                  default: https://s3.amazonaws.com
                  description: >-
                    Public HTTP(S) S3-compatible endpoint URL. Explicit customer
                    credentials are required; worker credentials are not used
                    for arbitrary endpoints.
                region:
                  type: string
                  description: AWS region or storage region identifier (required)
                bucket:
                  type: string
                  description: Target bucket name for file uploads (required)
                acl:
                  type: string
                  description: >-
                    Access control list setting for uploaded files (e.g.,
                    'public-read', 'private')
                accessKeyId:
                  type: string
                  description: AWS access key ID or equivalent credential (required)
                accessKeySecret:
                  type: string
                  description: AWS secret access key or equivalent credential (required)
              required:
                - region
                - bucket
                - accessKeyId
                - accessKeySecret
              additionalProperties: false
          additionalProperties: false
        webhook:
          $ref: '#/components/schemas/JobWebhook'
      required:
        - template
      additionalProperties: true
    JobTemplate:
      type: object
      description: >-
        Template configuration defining the After Effects project and
        composition to render
      properties:
        id:
          type: string
          pattern: ^[A-Z0-9]{26}$
          description: >-
            Unique template identifier in ULID format (26 characters, uppercase
            alphanumeric)
        src:
          type: string
          description: >-
            Public HTTP(S), native s3:/gs:, inline data:, or a file: URL inside
            the current job work directory for an After Effects template (.aep,
            .mogrt, or .zip file). The worker rejects paths and symlinks
            escaping that directory and non-public network destinations.
        composition:
          type: string
          description: >-
            Name of the specific composition within the template to render
            (optional for .mogrt)
          nullable: true
      required:
        - id
      additionalProperties: true
    JobAsset:
      type: object
      description: >-
        Asset to be used in job rendering, containing source information and
        target layer details. For function assets, provide the function
        identifier in `name` and arguments in `params`.
      properties:
        src:
          type: string
          description: >-
            Public HTTP(S), native s3:/gs:, inline data:, or a file: URL inside
            the current job work directory. The worker rejects local paths and
            symlinks escaping that directory. Other schemes and non-public
            network destinations are rejected.
        type:
          type: string
          description: Asset type (e.g., image, video, audio, text, data, script, job)
        layerName:
          type: string
          description: >-
            Target layer name in the After Effects composition where this asset
            will be applied
        name:
          type: string
          description: >-
            Human-readable name for the asset. For function assets (`type:
            function`), this should be the NX function name (for example,
            `nx:layer-autoscale`).
        conform:
          type: boolean
          description: >-
            When true for video, image, or audio assets, the worker normalizes
            the downloaded media to a render-engine-safe target format before
            assembly. If omitted, the API auto-enables conform for known risky
            inputs such as WebM, WebP, GIF, and OGG/OGA sources. GIF inputs are
            converted to a ProRes 4444 MOV file and treated as video.
        params:
          type: object
          description: >-
            Optional parameters for function assets. For supported NX layer
            functions (`nx:layer-autoscale`, `nx:layer-duration-set`,
            `nx:layer-start-set`, `nx:layer-state-set`, `nx:solid-color-set`,
            `nx:text-params-set`), `params.layerName` accepts a single string or
            an array of strings. When an array is provided, the API expands the
            function asset into multiple per-layer assets while preserving the
            original `assets` order.
          properties:
            layerName:
              description: Target layer name(s) for function assets
              oneOf:
                - type: string
                  description: Single target layer name
                - type: array
                  items:
                    type: string
                  minItems: 1
                  description: >-
                    Multiple target layer names (supported by selected NX layer
                    functions only)
          additionalProperties: true
      required:
        - type
      additionalProperties: true
    JobAssetNested:
      type: object
      description: >-
        A nested job asset that renders a child job first, then uses its output
        as a video/image asset in the parent composition. The child job's output
        URL is automatically injected into the parent's assets.
      properties:
        type:
          type: string
          enum:
            - job
          description: Must be 'job' to indicate this is a nested job asset
        layerName:
          type: string
          description: >-
            Target layer name in the parent composition where the child job's
            output will be placed (required)
        template:
          type: object
          description: Template configuration for the child job
          properties:
            id:
              type: string
              pattern: ^[A-Z0-9]{26}$
              description: Template ID for the child job (required)
            composition:
              type: string
              description: Composition name to render in the child job (required)
            name:
              type: string
              description: Template name (optional)
          required:
            - id
            - composition
        assets:
          type: array
          items:
            $ref: '#/components/schemas/JobAsset'
          description: Assets to inject into the child job
        preview:
          type: boolean
          default: false
          description: Generate preview quality for the child job
        settings:
          type: object
          description: Render settings for the child job
          properties:
            type:
              type: string
              enum:
                - video
                - image
              default: video
              description: Output type for the child job
            frames:
              oneOf:
                - type: integer
                - type: array
                  items:
                    type: integer
              description: Frame specification for image output
            quality:
              type: string
              enum:
                - draft
                - full
              description: Render quality
            codec:
              type: string
              description: Output codec
            engine:
              type: string
              enum:
                - ae2025
                - ae2026
              default: ae2026
              description: After Effects render engine version for the child job
            multiFrame:
              type: boolean
              description: >-
                Turn After Effects Multi-Frame Rendering on (true) or off
                (false) for the child job. If omitted, the worker's own setting
                applies
      required:
        - type
        - layerName
        - template
    JobWebhook:
      type: object
      description: Webhook configuration for job status notifications and callbacks
      properties:
        url:
          type: string
          description: Target webhook URL that will receive job status updates
        method:
          type: string
          enum:
            - GET
            - POST
            - PUT
            - DELETE
          description: HTTP method to use when calling the webhook endpoint
          default: POST
        headers:
          type: object
          description: Additional HTTP headers to include in webhook requests
          additionalProperties: true
        data:
          type: object
          description: Custom data payload to include with webhook notifications
          additionalProperties: true
        custom:
          type: boolean
          default: false
          description: >-
            Flag indicating if webhook should only include custom data provided
            by the user
      required:
        - url
  securitySchemes:
    apiToken:
      type: http
      scheme: bearer
      description: >
        Bearer token authentication using API tokens for team-based access
        control.


        You can generate your own API token at:
        https://app.nexrender.com/settings/api-tokens

````

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