Read the machine code
The HTTP status provides the category. The error field provides the stable programmatic code. Keep requestId in your logs.
{
"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.
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
| HTTP | Code | Meaning and action |
|---|---|---|
| 400 | invalid_request | A header, query or job ID fails validation. A missing or too-short x-api-key header also returns this code. |
| 400 | invalid_video_id | The video URL or identifier is invalid. Correct the input. |
| 401 | invalid_api_key | The supplied key is invalid, expired or revoked. |
| 404 | transcript_unavailable | No usable native track exists. Consider auto only if generation is permitted. |
| 404 | job_not_found | The job is absent or belongs to another workspace. |
| 429 | request_failed | Short rate limit. Respect Retry-After before trying again. |
| 429 | monthly_limit_exceeded | The monthly transcript request allowance is exhausted. |
| 429 | generation_minutes_limit_exceeded | The Free generated-minute allowance cannot cover this generation. |
| 429 | generation_concurrency_exceeded | The Free workspace already has an active generation. |
| 502 | upstream_unavailable | The upstream service could not complete the request. Use bounded backoff. |
| 503 | capacity_exceeded | The 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.