Getting started
Errors
Every error — validation, auth, billing or server — comes back in one consistent JSON shape with a stable machine code, so you can handle them uniformly.
Error shape
All errors share the same ErrorResponse body:
Error response
{
"error": "validation_error",
"message": "Invalid input data",
"details": [
{ "loc": ["body", "filename"], "msg": "Field is required", "type": "value_error" }
],
"request_id": "123e4567-e89b-12d3-a456-426614174000",
"timestamp": "2026-07-04T10:30:00Z"
}Fields
error— a stable machine code. For business errors it’s the exception name (e.g.InsufficientCreditsError,RateLimitError); for validation it’svalidation_error; for raw HTTP errors it’shttp_<status>(e.g.http_404). Branch on this, not on the message.message— a human-readable description. For debugging and display; don’t parse it.details— a list of{ loc, msg, type }field errors on422validation failures;nullotherwise.request_id— a server-generated UUID for this request, also returned in theX-Request-IDheader.timestamp— ISO-8601 UTC time the error was produced.
Branch on error, log request_id
Useerror for control flow and always log request_id — it’s the fastest way for support to trace a specific failed call.Status codes
400Bad requestBad requestA business/validation error — e.g. malformed Base64, empty upload, missing filename.
401UnauthorizedUnauthorizedMissing or invalid credentials, or an anonymous call to a login-only tool.
402Payment requiredPayment requiredOut of credits, or a per-key / per-member spend budget was exceeded. No work runs.
403ForbiddenForbiddenAPI key out of scope, or a suspended / unverified / inactive account.
413Payload too largePayload too largeThe request body is over the size ceiling.
415Unsupported media typeUnsupported media typeThe uploaded file’s type isn’t accepted by that tool (e.g. a non-PDF where PDF is required).
422Unprocessable entityUnprocessable entityRequest validation failed — a field is missing, wrong type, or an invalid enum value.
429Too many requestsToo many requestsRate limit exceeded. A
Retry-After header is included when the reset time is known.500Server errorServer errorAn unexpected error while processing. Safe to retry with backoff.
503Service unavailableService unavailableThe tool was disabled by an admin, or pricing config is temporarily unavailable.
The request ID
Each request gets a UUID that appears both in the request_id body field and the X-Request-ID response header. Note that the API ignores any inbound X-Request-ID you send — the ID is always server-generated to keep metering idempotency safe.
Handling errors
A robust client checks the status, branches on error, and respects Retry-After on 429:
JavaScript
const res = await fetch(url, options);
if (!res.ok) {
const body = await res.json();
if (res.status === 429) {
const wait = Number(res.headers.get("Retry-After") ?? 1);
// back off for 'wait' seconds, then retry
}
if (body.error === "InsufficientCreditsError") {
// prompt the user to top up
}
throw new Error(`${body.error}: ${body.message} (${body.request_id})`);
}See Credits & billing for 402 handling and Authentication for the 401/403 cases.
