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_video_id, unsupported_source, invalid_api_key, tenant_disabled or monthly_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',
'processing_timeout',
'rate_limited',
])
if (!response.ok && retryable.has(result.error)) {
// Retry with exponential backoff and jitter.
}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.