Skip to main content
Every failure uses a { "error": "..." } body. Extra diagnostic fields only appear on some codes.

400 — request rejected

The request body could not be read or did not pass validation. No job is created and no credits are deducted.
For a Parameter tidak valid error, do not try other values by guessing. Refetch GET /api/v1/models and use the arrays it lists.
Never repeat a 401 request blindly. Fix the credentials first.
The solution is to top up, not to retry. Compare requiredCredits with the estimated price from the catalog before sending a batch.
This happens when GET /api/v1/jobs/{id} uses an id belonging to another account — usually a hardcoded id, or the key in use changed. Your own jobs never hit this code.
The model is known but currently switched off. Refresh the catalog and move the request to another model; do not retry the same one.
Compress or trim the file first. This limit applies before the contents are inspected, so it cannot be negotiated with a parameter.

429 — capacity

Three different causes, each with its own body shape:All concurrent slots used (Unlimited account)
Daily video quota exhausted
Server queue full / uploads too frequent
On POST /api/v1/upload, the response carries a Retry-After header in seconds. Honor its value.
429 means wait, not switch keys. Creating a new API key raises no limit at all, because every limit attaches to the account.
Rare, and it does not consume credits. Report it together with the time and the endpoint.
Use exponential backoff and keep the same idempotencyKey.

Failures that arrive as failed, not as an HTTP status

These cases show up later, in the errorMessage of GET /api/v1/jobs/{id}. Credits were deducted and then refunded, so check the creditsCharged value that is left at 0.
errorMessage values are deliberately in English in the API response. Translate them into your UI language, but do not change their meaning when showing them to an end user.