---
title: "YouTube Audio Transcript API"
method: GET
path: "/v1/youtube/audio-transcript"
tags: ["YouTube"]
---

# YouTube Audio Transcript API

`GET /v1/youtube/audio-transcript`

## Request

- Base URL: `https://api.captapi.com`
- URL: `https://api.captapi.com/v1/youtube/audio-transcript`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Speech-to-text for YouTube audio.

Transcribes YouTube audio with AI speech-to-text when the video has no published captions (or when you want speech-to-text regardless). Audio with no speech answers 422 NO_SPEECH at 0 credits, remembered for 24 hours. Separate from /transcript — that endpoint only returns YouTube's caption tracks. Pricing is duration-based and honest: creditsUsed = ceil(durationSeconds / 60) × 2 (badge: 2 credits/min of audio). Success includes estimatedCredits (same number) so maxCredits is usable without doing the arithmetic. Pass maxCredits to refuse expensive jobs before any STT runs (400 cost_exceeds_max, 0 credits). Measured end-to-end: ~20 min of audio ≈ 12s, ~82 min ≈ 49s. Audio is re-encoded to 16 kHz mono 32 kbps before upload so podcast-length jobs stay under the ~25 MB ceiling. Sync path is capped at 90 minutes so the request finishes inside the 110s request deadline; longer videos return 400 duration_too_long with estimatedCredits before any STT spend. An audio download miss is 502 audio_extract_failed with a split reason: blocked_rate (403/429, retryable, retryAfterSeconds=300), extract_timeout (retryable, 60s), extractor_unavailable (signed-URL / extractor miss, retryable, 120s), no_audio_format / restricted / live_unavailable (this video, retryable false). estimatedCreditsIfRetried is only present when retryable is true. A permanent miss with no captions sets obtainable:false and says no transcript is obtainable — it does not leave suggestedEndpoint:null as an open loop. Download budget is 20s (a doomed fetch used to sit for ~67s). blocked_rate opens a service-wide circuit (cacheScope=service, blockedRateConsecutive) so further downloads wait out the cooldown instead of deepening a YouTube block. When a published caption track exists, suggestedEndpoint=/v1/youtube/transcript — suggest, never substitute STT with captions. Response always includes source: "asr", asrProvider, languageIsDetected, numeric segments[{text,startMs,endMs}], text, durationSeconds, creditsUsed, estimatedCredits. Cache hits still bill — the cache is our margin.

Docs: https://captapi.com/apis/youtube-audio-transcript

## Query parameters

- `url` string, required
- `language` string
- `maxCredits` integer
- `cache` boolean

## Response `200`

Success. The data object for this endpoint.

- object
  - `success` unknown, required
  - `data` object, required
    - `platform` string: Always "youtube" on this endpoint.
    - `videoId` string: YouTube video id parsed from the url.
    - `url` string: Canonical URL of the item.
    - `asrProvider` string: Speech-to-text tier that produced this transcript: "asr-fast" (default) or "asr-standard" (used when the fast tier is unavailable).
    - `language` string: BCP-47 / ISO speech language code from ASR (e.g. "en"), not a full name like "english".
    - `languageIsDetected` boolean: true when language was auto-detected from the audio; false when the language query param was honored.
    - `durationSeconds` integer: Audio length in whole seconds — basis for per-minute billing.
    - `segments` object[]
      - `text` string: Full transcript — segment texts joined with a single space. Prefer this over any legacy transcript alias.
      - `startMs` integer: Cue start in integer milliseconds.
      - `endMs` integer: Cue end in integer milliseconds (always > startMs).
    - `text` string: Full transcript — segment texts joined with a single space. Prefer this over any legacy transcript alias.
    - `creditsUsed` integer: Credits billed for this call: ceil(durationSeconds / 60) × 2. Present in data (and echoed on the envelope).
    - `source` unknown

## Other responses

- `400`: Bad request: wrong platform URL, unknown endpoint, or an invalid parameter value. Not billed.
- `401`: Missing, invalid or revoked API key. Not billed.
- `402`: Not enough credits for this request. Not billed.
- `404`: The resource does not exist or is not public. Not billed.
- `422`: A required parameter is missing or has the wrong type. Not billed.
- `429`: Rate limit reached. Wait for Retry-After seconds. Not billed.
- `502`: The platform could not be reached or returned nothing usable. Retryable, not billed. 503 and 504 use the same envelope.

---

[API](https://skmtc.dev/captapi/apis/captapi-api.md) · [All operations](https://skmtc.dev/captapi/apis/captapi-api/llms.txt) · [OpenAPI document](https://skmtc.dev/captapi/apis/captapi-api/revisions/c9b9ac5ff1bd?raw)
