Errors come back as JSON with an error object.
| HTTP | Code | Meaning | How to fix |
|---|---|---|---|
401 |
invalid_api_key |
Missing or invalid subtitle API key | Add Authorization: Bearer <key> or X-API-Key: <key>. Check the key wasn't lost or revoked |
402 |
insufficient_credits |
Account balance is 0 | Top up from your dashboard's Billing tab or check GET /api/keys/balance |
422 |
validation_error |
Bad request | Verify from/to are supported, the file is ≤ 5 MB with a valid extension, and numeric params are in range (e.g. shift_ms ±30000) |
503 |
billing_unconfigured |
Billing isn't set up on the account | Contact support to enable credit top-ups |
Common gotchas
- File over 5 MB → rejected with
422. Compress or split before sending. - Wrong
fromfor the file content → garbled timestamps. Matchfromto the actual source format. positionvalues:top/middle/bottomrewrite{\anN}markers;removestrips them entirely.
Rate limits
The API allows 60 requests per minute per subtitle API key. Requests over the limit are rejected with a rate-limit error — back off and retry. If you're running large batches, spread them across the window or add retry logic with a small delay.
Best practices
- Store the key server-side. The subtitle API key is a credential. Keep it in env vars or a secrets manager; never ship it to the client.
- Dedupe before you ship captions. Turn on
remove_duplicateswithdup_similarityanddup_proximity_mstuned to your content to kill repeated or overlapping cues. - Resync by type. Constant offset →
shift_ms. Drifting sync → two-point linear resync (two_point_t1/t1p/t2/t2p). Frame mismatch →frame_rate_from/frame_rate_to. - Build a cleanup pipeline, not one-off calls. Combine
clean_sdh,fix_all_caps,casing,max_line_length, andmerge_short_linesinto a single conversion for reproducible, broadcast-ready captions. - Watch
X-Avg-Cps. Values above ~20 chars/sec indicate captions are on screen too briefly — bumpmax_linesor adjust timing before publishing.