Errors
API HTTP errors use 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 body, such as a malformed input UUID or an 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). | Use a key with the required scope. |
404 | Resource does not exist — or belongs to another key. | Check the id; ownership failures read as 404, not 403. |
409 | The action conflicts with the resource state, such as cancelling a completed order. | Read the current state. Repeating the same cancellation will not change a settled result. |
429 | Rate limit exceeded. | Wait Retry-After seconds — see Rate limits. |
5xx | Something failed on our side. | Retry reads with backoff. Before resubmitting an order after an uncertain response, check whether it was created to avoid duplicate work. Report the affected order or asset ID and the request time if the problem persists. |
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. cancelled and expired are also terminal outcomes without a completed result. In batches, these outcomes count in the failed group and do not block siblings.
Typed SDK errors
SDK 1.1.0 exposes the following error types. HTTP errors carry the status. Order failures, ingest failures and timeouts are separate from HTTP errors.
| Failure | JavaScript | Python | Kotlin |
|---|---|---|---|
| 400: invalid request | ValidationError | BkbnLabValidationError | BkbnLabValidationException |
| 401: authentication | AuthError | BkbnLabAuthError | BkbnLabAuthException |
| 403: insufficient scope | ForbiddenError | BkbnLabAuthError | BkbnLabAuthException |
| 404: unknown resource | NotFoundError | BkbnLabNotFoundError | BkbnLabNotFoundException |
| 409: state conflict | ConflictError | BkbnLabConflictError | BkbnLabConflictException |
| 429: retries exhausted or delay too long | RateLimitError | BkbnLabRateLimitError | BkbnLabRateLimitException |
| Ingest refused the file | IngestError | BkbnLabIngestError | BkbnLabIngestException |
| Order failed or expired | OrderFailedError | BkbnLabOrderError | BkbnLabOrderException |
| Order cancelled | OrderCancelledError | BkbnLabOrderError | BkbnLabOrderException |
| Client deadline exceeded | TimeoutError | BkbnLabTimeoutError | BkbnLabTimeoutException |
Camera RAW is supported. Ingest can still reject an unreadable file, an unsupported format or a file exceeding the upload or resolution limits. Read data.code and data.reason from GET /v1/assets/:id/status to diagnose an ingest failure.
JavaScript's OrderCancelledError extends OrderFailedError. In Python, inspect BkbnLabOrderError.state for "cancelled"; in Kotlin, inspect BkbnLabOrderException.state for OrderState.CANCELLED. A client timeout does not cancel the order.