DocsErrors
Errors
The error envelope, every error code, and which ones to retry.
A request error means the API refused the call. A job failure means the API accepted the transcription, but it later ended with status set to failed.
The error envelope
Every /v1 request error has the same shape:
{
"error": {
"code": "insufficient_minutes",
"message": "Not enough minutes",
"retryable": false,
"action_url": "https://transcript1.com/dashboard/billing",
"minutes_needed": 20,
"minutes_remaining": 3
}
}Handle errors by code. Display message to the user; its wording may change. When retryable is true, the same request may succeed later.
Some errors add fields next to retryable:
| Field | On which errors | Meaning |
|---|---|---|
action_url | insufficient_minutes | Where to buy a plan or a top-up. |
minutes_needed, minutes_remaining | insufficient_minutes | Minutes the request needs (null when it is not known yet) and minutes you have. |
supported_platforms | unsupported_platform | The platforms you can send, for example ["youtube"]. |
missing_chunks | upload_incomplete | Indexes of the chunks that did not arrive. |
max_bytes | media_too_large | The largest file size allowed for you, in bytes. |
params | invalid_request | For body and query validation errors, an object mapping each field to what is wrong with it. |
Request errors
| HTTP status | code | Retryable | When |
|---|---|---|---|
| 400, 422 | invalid_request | No | A parameter or body field is missing or invalid, for example diarize together with source: "captions", or reuse_recent with webhook_url. |
| 422 | invalid_url | No | url is not a supported YouTube video URL. |
| 422 | unsupported_platform | No | platform is not supported. |
| 422 | unsupported_media | No | The uploaded file does not have a supported extension. |
| 401 | unauthorized | No | The credential is missing, invalid, expired or revoked, or the upload token is invalid or expired. |
| 403 | insufficient_scope | No | An OAuth token lacks transcriptions:read or transcriptions:write. |
| 403 | email_not_verified | No | Verify your email address before creating transcriptions. |
| 402 | insufficient_minutes | No | Your usable minutes are 0 or fewer than the transcription needs. |
| 402 | no_active_plan | No | You tried to buy a top-up without an active paid plan. The dashboard's billing endpoint returns this, not the transcription endpoints. |
| 404 | not_found | No | The transcription does not exist or belongs to another team. |
| 409 | upload_incomplete | No | Some chunks are missing. Send them and complete again. |
| 409 | invalid_state | No | The transcription is not awaiting an upload, so chunks can no longer be sent or completed. |
| 409 | idempotency_conflict | No | The Idempotency-Key was already used with different parameters. |
| 413 | media_too_large | No | The file is larger than your limit. See Uploads. |
| 429 | rate_limited | Yes | Too many requests per minute. Wait for Retry-After seconds. |
| 429 | too_many_active_jobs | Yes | Too many transcriptions running, or too many open uploads. Wait for Retry-After seconds. |
| 500 | internal_error | Yes | Something went wrong on our side. Retry shortly. |
| 503 | service_unavailable | Yes | transcript1 is temporarily unavailable. Retry shortly. |
Requests from a browser that use a login cookie instead of a bearer credential are also checked for their origin. A request from another site returns 403 forbidden_origin. API calls with an Authorization header are not affected.
Every 429 response includes a Retry-After header with the number of seconds to wait. See Billing and limits for the limits themselves.
Retry a request
- Retry only when
retryableistrue:rate_limited,too_many_active_jobs,internal_errorandservice_unavailable. HonorRetry-Afterwhen it is present and back off between attempts otherwise. - When retrying
POST /v1/transcriptions, send the sameIdempotency-Keyheader to avoid a second charge if the original request succeeded. - Fix the request before sending it again for every other code.
Job failures
When a transcription ends with status set to failed, the object has error: { "code", "message" }. Failures can happen after the request returned, so read error when you poll or in the transcription.failed webhook.
error.code | Meaning | Try again? |
|---|---|---|
media_unavailable | The video does not exist or is no longer available. | No. Check the URL. |
media_private | The video is private. | No. Only public and unlisted videos can be fetched. |
age_restricted | The video is age-restricted. | No. Upload the file instead. |
live_stream | The video is a live stream, or a stream that has not started yet. | After the stream has ended. |
no_captions | source was captions and the video has no usable caption track. | Use source: "auto" or "stt". |
media_too_long | Speech-to-text accepts up to 5 hours of media. | No. Split the media. |
unsupported_media | The file could not be read or has no audio track. | No. Send a supported file. |
no_speech | No speech was detected. | No. |
unsupported_language | The language of this media is not supported. | No. Set language to a supported code or "auto". |
insufficient_minutes | Your minutes ran out before the transcription could be charged. | After you top up. |
fetch_failed | Fetching the media failed after several attempts. | Yes, later. |
transcription_failed | Speech-to-text failed after several attempts. | Yes, later. |
Failed and canceled transcriptions are never charged. Minutes that were taken for a transcription are returned when it fails or is canceled.
Updated October 14, 2026