Errors, limits and billing
Error codes, plan limits, rate limits and how API jobs are billed.
Errors
Every error is JSON with a message for people and a stable code for programs, sometimes with extra fields:
{ "error": "Invalid request: settings.maxCharsPerLine must be an integer from 10 to 250", "code": "invalid_request" }Switch on code. The error text may change. Authentication errors are plain 401 responses, never a redirect to a sign-in page.
Creating a job
| Status | code | Meaning |
|---|---|---|
400 | invalid_json | The body is not valid JSON. |
400 | invalid_request | One or more fields are invalid. A fields list names every problem: [{ "field": "settings.maxCharsPerLine", "message": "must be an integer from 10 to 250" }]. |
401 | missing_api_key, malformed_api_key, invalid_api_key | See API keys. |
402 | insufficient_credits | Your organization does not have enough credits. The response includes requiredCents and availableCents. Nothing was created. |
403 | platform_quota_reached | The platform's monthly upload quota is used up. |
404 | folder_not_found, preset_not_found | The folder or preset is not in your organization. |
409 | no_active_owner | The organization has no active owner to own the job. |
413 | plan_limit_exceeded | The file is larger or longer than your plan allows. details says by how much. |
429 | rate_limited | Wait for Retry-After seconds. |
501 | source_url_not_supported | sourceUrl was sent. It is reserved for later. |
503 | billing_unavailable | Credits could not be checked right now. Retry later. |
A refused request creates nothing: no project and no charge.
Reading a job
| Status | code | Meaning |
|---|---|---|
400 | invalid_job_id | The id is not a valid job id. |
400 | invalid_transcript_id, invalid_format, invalid_max_chars, unsupported_format, invalid_offset | A parameter is invalid. The message says which. |
404 | job_not_found | There is no such job in your organization. |
404 | transcript_not_found | No transcript matches. The response lists the ones the job has, in transcripts. |
409 | job_not_ready, transcript_not_ready | Still running. Keep polling. |
409 | job_failed, transcript_failed | It failed. Do not retry. |
Server errors (500) mean something went wrong on our side. Retrying after a short wait is safe for reads. For a failed POST /jobs, check your project list before retrying so you do not create a duplicate.
Limits
| Requests | 120 per minute for each API key |
| File size | Up to 5 GiB in one upload, and never more than your plan allows |
| Length | Up to what your plan allows |
| Upload URL | Valid for one hour |
| Custom vocabulary | Up to 1,000 terms of up to 100 characters |
Plan limits on file size and length are the same as in the app.
Billing
API jobs use the same credits as jobs uploaded in the app.
- Checked when you create the job. The
durationSecondsyou send is priced, and your organization needs enough credits, or the request fails with402. - Charged when the upload arrives, as for an upload in the app.
- Settled on the real length. After transcription, the charge is compared with the media's measured duration. If the audio is longer than you declared, the difference is charged. If it is shorter, the difference is refunded. Declaring a shorter duration does not make a job cheaper.
- Refunded if the job fails.
Send an accurate durationSeconds. ffprobe gives it to you in one line, as in the quickstart.
Keeping jobs findable
Jobs are normal projects, so they appear in your project list under the person who created the key. To keep API work together, send a folderId to file each job into a folder, and a name so people can recognize it.