Errors
Every error from the Video API endpoints uses the same JSON shape:
{
"error": {
"code": "...",
"message": "..."
}
}The HTTP status tells you the class of the problem; error.code is a stable string you can branch on in code. Always match on error.code rather than parsing error.message.
Error codes
references_conflict and too_many_references are request-body validation errors — see Create video for the exact limits. cancel_not_supported and cancel_failed are described on Cancel video. not_found is returned for both an unknown job and a job owned by a different API key; the two cases are intentionally indistinguishable.
real_person preprocessing errors
When real_person: true image preprocessing fails because of the supplied image, the API returns HTTP 400 with error.code: "invalid_request". The end of error.message includes one of these stable reason tokens and identifies the failing reference, for example input_references[0]:
{
"error": {
"code": "invalid_request",
"message": "real_person image processing failed — input_references[0]: ... (not_image)"
}
}Branch on error.code in application logic. Use the reason token and reference location to correct the input or for diagnostics.
402 Insufficient credits
insufficient_credits is returned only when you create a job (POST /v1/videos). When pre-authorization is enabled, ofox estimates the cost from the requested resolution and duration before accepting the job. If the estimate exceeds your balance, the request is rejected immediately — no job record is created and nothing is charged.
{ "error": { "code": "insufficient_credits", "message": "..." } }insufficient_credits is the only 402 code the Video API returns. Handle this single code, top up your balance, and retry.
429 Rate limiting
rate_limited covers both the per-key polling limit on GET /v1/videos/{id} and upstream rate limits. When you hit the polling limit, the response carries a Retry-After header:
HTTP/1.1 429 Too Many Requests
Retry-After: 1
Content-Type: application/json
{ "error": { "code": "rate_limited", "message": "..." } }Respect the Retry-After header and back off before retrying. If you are polling frequently, switch to webhook notifications so ofox pushes the terminal state to you instead — this avoids the polling limit entirely. Job creation (POST) and cancellation (DELETE) are not affected by the polling limit.