Error catalogue
Every error the API can return.
The machine code to branch on, the status it arrives with, why it fired and what to do about it. Written for the moment you have one in your hand.
15 codes, and the set is closed — branch on all 15 and you have covered every error the API itself returns. What it cannot cover is a request that never reached us. Check the status before you read the body.
The envelope
One shape, every time.
Every failure returns the same four fields, in the same flat shape. There is no nested error object to unwrap. Some errors add fields alongside these four — never instead of them.
{ "success": false, "code": "not_found", "error": "Not found", "message": "Zone not found" }
{ "success": false, "code": "validation_error", "error": "Validation error", "message": "Zone data validation failed", "errors": [ { "field": "radius_meters", "rule": "min", "value": 0 } ] }
{ "success": false, "code": "quota_exceeded", "error": "Quota exceeded", "message": "Zone limit reached", "current": 100, "limit": 100, "tier": "free", "upgradeUrl": "mailto:hello@polyfence.io" }
successAlways false on an error. The one field you can test without knowing anything else.
codeThe stable discriminator. Branch on this — it is drawn from a closed enum and does not change.
errorA short title for the class of failure. For display, not for logic.
messageThe specific detail. Free to change and free to localise, so never parse it.
+ extrasSome errors carry more on the root. A validation failure adds errors, one entry per field and rule; a quota failure adds current, limit, tier and upgradeUrl. The four above are always there — treat anything else as additive.
The 15 values are a closed enum. Rather than typing them out, take the typed ErrorCode from the OpenAPI spec → — it is the same source this page is generated from, and it is in every generated SDK from 2.0.0.
The closed set
15 codes, and no sixteenth.
The whole enum, on one screen. The last two are ours or our upstream’s rather than yours — a 502 means a source you pointed us at failed, not Polyfence. Two more are easy to confuse: quota_exceeded is a monthly allowance running out, rate_limited is a per-second cap. They do not retry the same way.
Your request
Ours, or upstream of us
Outside the envelope. A 504 comes from the gateway, not from Polyfence — usually a connector sync that ran past its time budget. There is no code, and no JSON to parse. Treat a response you cannot parse as a retryable infrastructure failure, not a client error. To make one traceable, send your own x-request-id — any UUID v4 — and quote it to hello@polyfence.io.
Where they come from
One code, many situations.
A code names the class of failure, not what you did. These are the situations, grouped by what you were trying to do — 48 of them, every message quoted as the API actually returns it.
Still stuck?
If the code and the message do not explain it, that is on us to fix, not you to work around.
Or email hello@polyfence.io with the code, the endpoint, and your x-request-id.