Error codes
Every API error arrives in the same envelope:
{
"error": {
"code": "insufficient_funds",
"message": "not enough doubloons: need 150, balance is 100"
}
}
code is a machine string — branch on it in your code. message is for
humans; its format is not guaranteed, don't parse it.
Code table
| HTTP | code | Meaning | What to do |
|---|---|---|---|
| 400 | bad_request | Malformed request overall | Check body and headers |
| 401 | unauthorized | Key missing, invalid, or revoked | Reissue the key: /apikey in the bot |
| 402 | insufficient_funds | Not enough doubloons for the order | Top up in the bot; check GET /balance |
| 403 | forbidden | Access denied | Make sure your key touches your own resources |
| 404 | not_found | No such order, webhook, channel, or file | Check the id; other users' resources also 404; order files live 30 days |
| 409 | fair_use_exceeded | Plan fair-use limit exhausted (heavy videos) | Wait for next month or pay in doubloons |
| 409 | not_awaiting_review | The order is not waiting for script review | Review only works in awaiting_review |
| 409 | idempotency_conflict | Idempotency-Key already used by another account | Generate your own unique key |
| 410 | gone | Promo code expired or fully redeemed | Ask for a new code |
| 422 | invalid_params | Body failed validation | message names the field and the reason |
| 429 | rate_limited | Over 30 POST/minute on the key (or hourly suggest/master-prompt limit) | Slow down, respect Retry-After |
| 429 | active_tasks_exceeded | Already 10 active tasks (queued+running; videos and clips combined) | Wait for done/error, respect Retry-After |
| 500 | internal_error | Something broke on our side | Retry with backoff; if it persists — support |
| 502 | generator_unavailable | Generator temporarily unavailable | Retry with backoff |
| 503 | service_unavailable | Service under maintenance (incl. suggest daily global limit) | Retry with backoff |
Frequent 422s:
cta: trueis incompatible withcta_target_type/cta_target/cta_word/cta_limit— two different modes: simple CTA (cta+ requiredplacement) and targeted CTA (withoutcta;cta_target= bot @handle or site URL, optionalcta_word/cta_limit).bg_presetonly accepts ids from the live catalogGET /public/v1/bg-presets— never guess names.- Content and background sources are mutually exclusive:
theme_urlvstheme; exactly one ofbg_ai/bg_preset/bg_url/bg_asset_id. - Clips: exactly one source —
source_urlORsource_asset_id;smart_croprequiressplit_layout: 33;split_layoutmust be 0/33/50/60. - Channel:
schedule_enabled: truerequiresschedule_hourand a non-emptyschedule_days(integers 0–6, Mon–Sun).
Limits and Retry-After
Each key has two limits: 10 active tasks (queued + running; since
0.87.0 clips count toward the same quota — videos and clips combined) and
30 POST per minute. Exceeding either returns 429 with a
Retry-After header (seconds until the next attempt). Respect it — it's
cheaper than guessing.
Good manners
Idempotency-Keyon every POST to/videos,/videos:quick— and mandatory on/clips— client retries must not double-charge. A repeat with the same key within 24 hours returns the original task (200instead of201).- Retry GETs with exponential backoff and jitter; on
429/5xxfollowRetry-After. - A generation failure is not an HTTP error: check the order
status.refunded— the doubloons were refunded to the balance automatically (same as in the bot);error— failed with no charge (trial, or an externally paid order).
Support: @piratepress_support.