Errors
Every failure uses the same envelope: the HTTP status and a human-readable reason. Branch on the status, log the reason.
{ "error": { "status": 400, "reason": "each value in inputs must be a UUID" } }Status codes
| Status | Meaning | What to do |
|---|---|---|
400 | Invalid request — bad body, malformed UUID, unknown option value. | Fix the request; the reason names the offending field. |
401 | Missing, invalid, or rotated-away API key. | Check the X-API-Key header and the key's validity. |
403 | Valid key, insufficient scope (admin endpoint) or foreign resource. | Use a key with the right scope; check the resource id. |
404 | Resource does not exist — or belongs to another key. | Check the id; ownership failures read as 404, not 403. |
429 | Rate limit exceeded. | Wait Retry-After seconds — see Rate limits. |
5xx | Something failed on our side. | Retry with backoff; report the request id if it persists. |
Request ids
Every response carries an x-request-id header. Include it when reporting a problem — it lets us find the exact request in our logs. The SDKs attach it to every typed error they raise.
Order failures are not HTTP errors
A successfully submitted order that later fails (unprocessable image, upstream model error) does not produce an HTTP error: the order reaches status: "failed" with an error field explaining why, via the same streams and polls as success. In batches, a failed scene never blocks its siblings.
Typed SDK errors
The SDKs never make you parse reason strings — each failure mode is a typed error carrying the status, the reason, and the x-request-id. The same hierarchy exists in all three languages (JavaScript names shown; Python bkbnlab.errors, Kotlin BkbnLab*Exception):
| Error | Raised on |
|---|---|
ValidationError | 400 — the request itself is wrong. |
AuthError | 401 — bad or revoked key. |
ForbiddenError | 403 — scope or ownership. |
NotFoundError | 404 — unknown resource. |
RateLimitError | 429 with a long wait; carries the retry delay. Short waits are absorbed silently. |
IngestError | An uploaded file was refused (camera RAW, degenerate resolution). |
OrderFailedError | wait() on an order that reached failed. |
TimeoutError | wait() exceeded your deadline. |