Skip to main content
The Assets API lets you upload files to HeyGen and receive an asset_id you can reference in other endpoints — including Video Agent, Avatar creation, Video Translation, and Lipsync. There are two ways to upload:
  • POST /v3/assets — a single multipart/form-data request. Simplest option, capped at 32 MB.
  • Direct upload — a presigned-URL flow for files larger than 32 MB. The file bytes go straight to storage and never pass through the API.

Upload via POST /v3/assets

Full schema: POST /v3/assets. Upload a file using multipart/form-data — the MIME type is auto-detected from file bytes.

Constraints

Example request

Response

Upload large files (direct upload)

For files larger than 32 MB, use the direct upload flow. It is a three-step process — all three steps are required; the asset_id is not usable until you call the complete endpoint:
1

Initialize the upload

Call POST /v3/assets/direct-uploads with the file’s name, MIME type, and exact byte size. The response contains an asset_id, a presigned upload_url, and upload_headers.
2

PUT the file bytes

Send the raw file bytes to upload_url with an HTTP PUT, including every header from upload_headers verbatim. The URL expires after expires_in_seconds, and the byte size is signed into it — the upload fails if the file doesn’t match the declared size_bytes.
3

Complete the upload

Call POST /v3/assets/{asset_id}/complete to finalize the asset. This step is idempotent — repeated calls return the same finalized asset. The asset_id is now usable anywhere the API accepts assets.

Example

Initialize response fields

Calling complete before the PUT has finished returns a 409 conflict (“Uploaded object not found yet”). Retry after the PUT returns 200. You can optionally pass checksum_sha256 (hex) at both the initialize and complete steps to have the stored bytes verified end to end.

Use assets in Video Agent

Once uploaded, reference the asset_id in the files array when creating a video:

Three ways to provide files

Video Agent and other endpoints accept files in three formats. Use whichever is most convenient for your workflow:

Asset ID

Upload once, reference by ID. Best for files you reuse across multiple videos.

HTTPS URL

Point to a publicly accessible URL. No upload step needed — HeyGen fetches the file directly. Same 32 MB per-file limit as uploads.

Base64

Inline the file content as a base64-encoded string. Useful for small files or when you want a self-contained request.

Format comparison

The 32 MB per-file limit also applies to URL inputs — pointing at a larger self-hosted file fails with Maximum size for URL inputs of type 'video/mp4' is 32 MB. For larger files, use direct upload and pass the resulting asset_id. Base64 encoding additionally inflates payload size by ~33%, so prefer the other two formats for anything beyond a few MB.

Where assets can be used

The asset_id format is accepted anywhere the API takes file inputs:

Example: Upload then generate

A complete workflow — upload a PDF, then use it to generate a video: