YouTube transcript API errors and safe retries

Classify Capslane transcript failures, preserve request IDs and retry only errors that can recover.

Read the machine code

The HTTP status provides the category. The error field provides the stable programmatic code. Keep requestId in your logs.

Error response
{
  "error": "transcript_unavailable",
  "message": "No usable transcript is available",
  "requestId": "req_..."
}

Stop on permanent failures

Do not retry invalid_request, invalid_video_id, invalid_api_key, monthly_limit_exceeded or generation_minutes_limit_exceeded. A native-only transcript_unavailable also requires a product decision, not an identical retry.

Retry transient failures with a budget

Network, capacity and upstream errors may recover. Use exponential backoff with jitter, a maximum attempt count and an end-to-end deadline.

JavaScript
const retryable = new Set([
  'upstream_unavailable',
  'capacity_exceeded',
])

const shortRateLimit = response.status === 429 &&
  result.error === 'request_failed' && response.headers.has('retry-after')

if (!response.ok && (retryable.has(result.error) || shortRateLimit)) {
  // Schedule a bounded retry and honor Retry-After when present.
}

Respect a server retry delay when one is returned. Never run unbounded retries inside a request handler.

Keep job failure separate from request failure

An accepted job can later become failed or cancelled. Store its job ID and final error. Creating a replacement job should remain an explicit decision.

A failed status request is also different from a failed job. If polling returns a transient HTTP error, retry the same job ID within your deadline. Do not send a new transcript request for every polling failure. A 202 response means accepted work, not final success.

Diagnose common HTTP responses

HTTPCodeMeaning and action
400invalid_requestA header, query or job ID fails validation. A missing or too-short x-api-key header also returns this code.
400invalid_video_idThe video URL or identifier is invalid. Correct the input.
401invalid_api_keyThe supplied key is invalid, expired or revoked.
404transcript_unavailableNo usable native track exists. Consider auto only if generation is permitted.
404job_not_foundThe job is absent or belongs to another workspace.
429request_failedShort rate limit. Respect Retry-After before trying again.
429monthly_limit_exceededThe monthly transcript request allowance is exhausted.
429generation_minutes_limit_exceededThe Free generated-minute allowance cannot cover this generation.
429generation_concurrency_exceededThe Free workspace already has an active generation.
502upstream_unavailableThe upstream service could not complete the request. Use bounded backoff.
503capacity_exceededThe generation queue is full. Try again later within a retry budget.

For a short rate limit, HTTP 429 uses request_failed with a Retry-After header. Monthly request and generated-minute limits require an allowance change or monthly reset. A concurrency limit can clear when the active generation finishes. Retry temporary upstream or capacity failures with bounded backoff; when polling, retry the same job ID.

Use one deadline for the whole operation

Stopping a client request or reaching a client timeout does not cancel an accepted server job. Resume with its job ID. JavaScript SDK 0.1.3 bounds both waits and in-flight reads within the polling deadline. Python checks its polling deadline between iterations. Each HTTP request also has its own timeout.

A local SDK processing_timeout does not establish server failure. Keep the job ID and resume polling when appropriate.

The classification snippet above is not a complete retry client. Put a limit on attempts and elapsed time, check the HTTP status before treating JSON as transcript content, and allow for non-JSON proxy responses. Random jitter prevents a batch of workers from retrying simultaneously. Honor Retry-After when the server provides it.

Submission retries can reserve additional request units. An ambiguous network timeout may occur after the server accepted work. Retain any known job ID and consult Logs before recreating a job. Avoid recording keys or transcript text in diagnostic messages.

The downloadable Python and Node.js HTTP clients stop on errors and enforce a shared deadline, leaving retry policy to your application. They are tested against immediate results, multiple polling states, terminal failures and timeouts. Check service status and include the request ID when reporting a persistent failure.