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

# Create Asset Upload

`POST /v3/assets/direct-uploads`

Begin a direct-to-S3 upload. Returns an asset_id and a presigned upload_url; PUT the file bytes to upload_url, then call POST /v3/assets/{asset_id}/complete. Unlike POST /v3/assets (which proxies the bytes), this never sends the file through the API.

## Headers

- `Idempotency-Key` string

## Request body

- CreateAssetUploadRequest — Request to begin a presigned direct-to-S3 upload (POST /v3/assets/direct-uploads).
  - `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', 'application/zip'). Verified against the stored bytes at completion.
  - `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` CreateAssetUploadResponse — Presigned upload instructions.
    - `asset_id` string, required — Reusable asset identifier. Becomes usable after POST /v3/assets/{asset_id}/complete.
    - `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/versions/e2e54726e210/schema)
