---
title: "Create Asset Upload Batch"
method: POST
path: "/v3/assets/direct-uploads/batches"
tags: ["Asset Batches"]
---

# Create Asset Upload Batch

`POST /v3/assets/direct-uploads/batches`

Request up to 100 presigned direct-to-S3 upload URLs in a single call. Returns a batch_id and one upload slot per file (asset_id + presigned upload_url + required headers). PUT each file's bytes to its upload_url, then call POST /v3/assets/complete/batches to finalize the whole batch. This is synchronous — no bytes flow through the API. Pass an Idempotency-Key header to make retries safe (the same key returns the same batch).

## Headers

- `Idempotency-Key` string

## Request body

- CreateAssetUploadBatchRequest
  - `title` string, nullable — Display name for the batch, shown in the HeyGen app.
  - `callback_url` string, nullable — Reserved for parity with the other batch APIs; asset completion does not emit a webhook.
  - `files` AssetUploadItem[], required — Files to presign, same shape as POST /v3/assets/direct-uploads. Max 100 per batch.
    - `filename` string, required — Original filename for reference/metadata. The stored object's extension is derived from content_type.
    - `content_type` string, required — Declared MIME type (e.g. 'video/mp4', 'image/png', 'audio/mpeg', 'application/pdf'). Verified against the stored bytes when the batch is completed.
    - `size_bytes` integer, required — Exact byte size of the file. Signed into the upload URL so it cannot be exceeded.
    - `checksum_sha256` string, nullable — Optional SHA256 of the file as hex. When provided, S3 enforces it on upload.

## Response `200`

Successful response

- object
  - `data` CreateAssetUploadBatchResponse
    - `batch_id` string, required — Identifier of the created batch. Pass to POST /v3/assets/complete/batches once all files are uploaded.
    - `items` AssetUploadBatchItem[], required — One presigned upload slot per requested file, in the submitted order.
      - `asset_id` string, required — Reusable asset identifier. Becomes usable after POST /v3/assets/complete/batches finalizes the batch.
      - `upload_url` string, required — Presigned S3 URL. PUT the raw file bytes here.
      - `upload_headers` object, required — Headers that must be sent verbatim on the PUT request.
      - `expires_in_seconds` integer, required — Seconds until the upload URL expires.
      - `max_bytes` integer, required — Maximum allowed upload size in bytes.
      - `status` 'pending_upload', required — Upload lifecycle status. Always 'pending_upload' here.

## Other responses

- `400` — Invalid request parameters
- `401` — Authentication failed
- `409` — A prior request with this Idempotency-Key is still in progress. Wait for the original request to complete, then retry.
- `429` — Rate limit exceeded

---

[API](https://skmtc.net/heygen/apis/heygen-external-api.md) · [All operations](https://skmtc.net/heygen/apis/heygen-external-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/heygen/heygen-external-api/revisions/e2e54726e210/schema)
