---
title: "Create Transcription"
method: POST
path: "/v3/audio/transcriptions"
tags: ["Audio"]
---

# Create Transcription

`POST /v3/audio/transcriptions`

## Request

- Base URL: `https://api.heygen.com`
- URL: `https://api.heygen.com/v3/audio/transcriptions`
- Auth: one of:
  - API key in header `x-api-key`
  - HTTP bearer

Transcribe an audio or video file with `scribe-v2`. The request waits for the transcript and answers 200 with it. Audio is limited to 10 minutes with `diarize` on and 30 minutes with it off. Send an `Idempotency-Key` header with every request: it is required. Repeating a request with the same key and body returns the original result instead of transcribing again, and a duplicate sent while the original is still running gets 409 `request_in_progress`. The transcription is priced at the vendor's cost for the decoded audio length. A request the workspace's API credits cannot cover is refused with 402 `insufficient_credit` before the model runs. The credits are charged once the transcript is made, and a failed transcription is not charged. If the balance no longer covers the charge when the transcript is ready, the request answers 402 `insufficient_credit` without it. Read `status` rather than assuming the POST finished the transcription.

## Headers

- `Idempotency-Key` string, required

## Request body

- TranscriptionCreateRequest: A transcription by `scribe-v2`.
  - `audio` union, required: The audio or video file to transcribe, as a url, an asset_id or inline base64.
    - AssetUrl: Asset input via publicly accessible HTTPS URL.
      - `type` 'url', required: Input type discriminator
      - `url` string, required: Publicly accessible HTTPS URL for the asset
    - AssetId: Asset input via HeyGen asset ID from the asset upload endpoint.
      - `type` 'asset_id', required: Input type discriminator
      - `asset_id` string, required: HeyGen asset ID from the asset upload endpoint
    - AssetBase64: Asset input via base64-encoded content.
      - `type` 'base64', required: Input type discriminator
      - `media_type` string, required: MIME type of the encoded content (e.g. "image/png")
      - `data` string, required: Base64-encoded file content
  - `model` 'scribe-v2', required: Transcription model.
  - `language` string, nullable: Spoken language as a lowercase ISO 639 code, such as `en`. Detected from the audio when omitted.
  - `word_timestamps` boolean: Return per-word timings in each segment.
  - `diarize` boolean: Label speakers. Audio is limited to 10 minutes with this on and 30 minutes with it off.
  - `num_speakers` integer, nullable: Expected number of speakers; only valid with `diarize` true.

## Response `200`

The finished transcription with its transcript.

- object
  - `data` TranscriptionResponse
    - `id` string, required: Transcription identifier, for reading the transcription again.
    - `status` 'pending' | 'completed' | 'failed', required
    - `model` 'scribe-v2', required: The transcription model that produced the transcript.
    - `created_at` integer, required: Request creation time as Unix seconds.
    - `language` string, nullable: Detected or requested language; present once completed.
    - `duration_seconds` number, nullable: Length of the transcribed audio; present once completed.
    - `text` string, nullable: Full transcript; present once completed.
    - `segments` TranscriptionSegment[], nullable: Transcript segments; present once completed.
      - `speaker` string, nullable: Absent when `diarize` was false.
      - `start` number, required: Start time in seconds.
      - `end` number, required: End time in seconds.
      - `text` string, required: The segment's text.
      - `words` TranscriptionWord[], nullable: Present when `word_timestamps` was true.
        - `word` string, required: The word as spoken, with any attached punctuation.
        - `start` number, required: Start time in seconds.
        - `end` number, required: End time in seconds.
        - `speaker` string, nullable: Absent when `diarize` was false.
    - `failure_code` 'invalid_input' | 'vendor_unavailable' | 'vendor_timeout' | 'ai_vendor_access_restricted' | 'internal_error' | 'insufficient_credit' | 'api_key_required' | 'rate_limited'
    - `failure_message` string, nullable: Human-readable failure description. Only present when status is failed.

## Other responses

- `400`: Invalid request parameters
- `401`: Authentication failed
- `402`: Insufficient credit
- `403`: Forbidden
- `409`: Conflict — `error.code` is one of: `request_in_progress`, `conflict`.
- `429`: Rate limit exceeded
- `502`: Upstream dependency failed — the request did not complete and is safe to retry.
- `504`: Upstream dependency timed out — the request did not complete and is safe to retry.

## Changes

- **2026-11-03** `7dfa5e59b4f5`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/heygen/apis/heygen-external-api/changes/v3/audio/transcriptions/post.md)

---

[API](https://skmtc.dev/heygen/apis/heygen-external-api.md) - [All operations](https://skmtc.dev/heygen/apis/heygen-external-api/llms.txt) - [OpenAPI document](https://skmtc.dev/heygen/apis/heygen-external-api/revisions/7dfa5e59b4f5?raw)
