Errors
Error response
Section titled “Error response”Most errors return this JSON body:
{ "request_id": "req_…", "code": "JOB_RECIPE_NOT_FOUND", "message": "The requested recipe is not available.", "retryable": false, "field_details": {}, "documentation_url": "https://docs.originalpictures.com/api/errors", "job_reference": null}| Field | Description |
|---|---|
request_id |
Unique request identifier. Include it in every support request. |
code |
Machine-readable reason code. See Reason codes. |
message |
Human-readable explanation. Do not parse it. |
retryable |
Whether repeating the same request can succeed. |
field_details |
Per-field validation messages, when relevant. |
documentation_url |
Link to this page. |
job_reference |
The related job, when the error concerns one. |
Branch on code and retryable, never on message. Responses never include stack traces or
storage identifiers.
Request-shape validation failures return 422 with a list of field errors. Some authentication
and routing failures return a minimal {"detail": "…"} body.
Status codes
Section titled “Status codes”| Status | Meaning |
|---|---|
| 401 | Missing, invalid, or revoked credential. The body never says which. |
| 402 | Billing quota or account state prevents the operation. |
| 403 | The key lacks the operation’s scope, the operation is denied by default, or the key’s IP allowlist excludes this client. |
| 404 | The resource does not exist in your tenant. |
| 409 | Conflict, for example an Idempotency-Key reused with a different payload. |
| 410 | The resource has expired, for example an upload session. |
| 422 | The request is malformed. |
| 429 | Too many requests: the key’s own rate limit, or an operation that enforces a rate. Wait for Retry-After. |
| 503 | A required dependency is temporarily unavailable. Retry with backoff. |
API key restriction codes
Section titled “API key restriction codes”A key can carry its own rate limit and IP allowlist (see Authentication). Three reason codes belong to them:
| Code | Status | Meaning |
|---|---|---|
API_KEY_RATE_LIMITED |
429 | The key’s own rate limit was exceeded. Retryable after Retry-After seconds. The refused request used no capacity. |
API_KEY_IP_NOT_ALLOWED |
403 | The key is limited to client networks and this request came from outside them, or from an address the API could not determine. |
API_KEY_IP_ALLOWLIST_UNAVAILABLE |
409 | This deployment cannot yet trust the client address, so it does not accept an IP allowlist. A rate limit can still be set. |
A 429 API_KEY_RATE_LIMITED response also carries RateLimit-Policy, for example
"per-key";q=60;w=60: q requests per w seconds.
Retries
Section titled “Retries”- Retry only when
retryableistrue, or on429and503. When the response has aRetry-Afterheader, wait at least that many seconds; otherwise use exponential backoff with jitter. - Send the same
Idempotency-Keyon a retry so the API does not create duplicate work. - A timeout on your side does not cancel a durable job. Poll the job instead of resubmitting it.
SDK errors
Section titled “SDK errors”The SDKs raise typed errors that carry the same code, request_id, and retryable values.
Examples are AuthenticationError, PermissionDeniedError, NotFoundError, ConflictError,
RateLimitError, and ServiceUnavailableError. See the Python and
TypeScript pages.
