Errors
Errors are returned in the JSON-RPC error object. The HTTP status is 200 even for an error — inspect the body, not the status.
{ "jsonrpc": "2.0", "id": 1, "error": { "code": 2001, "message": "not_found", "data": "…" } }
error.data, when present, carries client-safe detail (a validation reason, a limit). Internal detail is never leaked into it.
Application codes
| Code | Message | Meaning & remedy |
|---|---|---|
1001 |
unauthorized |
Missing or invalid token, bad login, or a throttled login. Re-authenticate. |
1002 |
token_expired |
The access token expired. Call auth.refresh once and retry. |
1003 |
forbidden |
Not the owner, or the method is outside a personal access token's scope. |
2001 |
not_found |
No such resource owned by the caller. |
2002 |
validation_failed |
The request was malformed; error.data says why. |
2003 |
cursor_stale |
The cursor photo is no longer visible in this album. Restart pagination without the cursor and deduplicate by photo id. |
2004 |
taken_down |
Moderation prevents this operation on the image or album. |
2005 |
operation_locked |
Retention prevents deletion or moving this resource; error.data is retained. |
2006 |
download_not_ready |
The authorized download is unavailable (HTTP 409 equivalent). error.data.state is preparing, empty, too_large or unavailable. Check download status before requesting a fresh link; internal storage details are never exposed. |
3001 |
storage_error |
A transient backend failure while verifying your request (e.g. a database blip). Your token is fine — retry with backoff. |
4001 |
custom_crop_limit_exceeded |
The image already has the maximum of five custom crops. |
4002 |
rate_limited |
Too many requests. When present, error.data.retry_after_seconds says how long to wait before retrying. |
JSON-RPC codes
Transport-level errors use the standard JSON-RPC range:
| Code | Meaning |
|---|---|
-32700 |
Parse error — the body is not valid JSON. |
-32600 |
Invalid request — not a conforming JSON-RPC object (e.g. a batch on an alias route, or a method that disagrees with the path). |
-32601 |
Method not found. |
-32602 |
Invalid params — the params did not match the method's schema. |
-32603 |
Internal error. |
-32605 |
The request exceeded the per-method time limit. |
A batch_too_large invalid-request (-32600) is returned when a batch exceeds 20 requests (see rate limits).
Anonymous report HTTP errors
Reporting uses plain HTTP outside JSON-RPC. An hourly limit returns
HTTP 429 with error: rate_limited, retry_after_seconds and a
Retry-After header in seconds. Proof rejection is always HTTP 400
verification_failed; no internal reason or target information is disclosed.