Skip to main content

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​

HTTPcodeMeaningWhat to do
400bad_requestMalformed request overallCheck body and headers
401unauthorizedKey missing, invalid, or revokedReissue the key: /apikey in the bot
402insufficient_fundsNot enough doubloons for the orderTop up in the bot; check GET /balance
403forbiddenAccess deniedMake sure your key touches your own resources
404not_foundNo such order, webhook, channel, or fileCheck the id; other users' resources also 404; order files live 30 days
409fair_use_exceededPlan fair-use limit exhausted (heavy videos)Wait for next month or pay in doubloons
409not_awaiting_reviewThe order is not waiting for script reviewReview only works in awaiting_review
409idempotency_conflictIdempotency-Key already used by another accountGenerate your own unique key
410gonePromo code expired or fully redeemedAsk for a new code
422invalid_paramsBody failed validationmessage names the field and the reason
429rate_limitedOver 30 POST/minute on the key (or hourly suggest/master-prompt limit)Slow down, respect Retry-After
429active_tasks_exceededAlready 10 active tasks (queued+running; videos and clips combined)Wait for done/error, respect Retry-After
500internal_errorSomething broke on our sideRetry with backoff; if it persists — support
502generator_unavailableGenerator temporarily unavailableRetry with backoff
503service_unavailableService under maintenance (incl. suggest daily global limit)Retry with backoff

Frequent 422s:

  • cta: true is incompatible with cta_target_type/cta_target/cta_word/cta_limit — two different modes: simple CTA (cta + required placement) and targeted CTA (without cta; cta_target = bot @handle or site URL, optional cta_word/cta_limit).
  • bg_preset only accepts ids from the live catalog GET /public/v1/bg-presets — never guess names.
  • Content and background sources are mutually exclusive: theme_url vs theme; exactly one of bg_ai/bg_preset/bg_url/bg_asset_id.
  • Clips: exactly one source — source_url OR source_asset_id; smart_crop requires split_layout: 33; split_layout must be 0/33/50/60.
  • Channel: schedule_enabled: true requires schedule_hour and a non-empty schedule_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-Key on 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 (200 instead of 201).
  • Retry GETs with exponential backoff and jitter; on 429/5xx follow Retry-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.