Refusal beats wrong answers.
Every error is a typed arm with distinct copy. Data-plane arms pass through the gateway byte-unchanged; gateway arms name which side refused (the key, the plan, or the license gate), so the fix is always obvious from the error alone. These are features, tested, not apologized for.
Resolver plane (passes through byte-unchanged)
candidate_setHTTP 200actionableThe address is honestly ambiguous: several locations share this key. The envelope carries the stored candidates and the evidence type a retry needs.
Fix: Retry with disambiguating evidence (unit, parcel id, building id, precise point) from the candidate rows.
not_foundHTTP 200informationalThe key parsed cleanly but no location in the corpus answers to it. Absence is reported, never papered over with a nearest guess.
Fix: Check the address against the corpus coverage; a valid off-corpus address is expected to land here.
parse_failedHTTP 422informationalThe input never parsed into a canonical address key, so no resolution was attempted.
Fix: Send a plausible postal address; the parser wants house + road + region signals.
Detail plane (passes through byte-unchanged)
no_decisive_parcelHTTP 404actionableThe address is absent or sits on multiple parcels, so the interim address shim refuses to guess between them.
Fix: Resolve first and use the decisive parcel id from grounding evidence, or supply stronger evidence.
unroutable_parcel_idHTTP 404informationalThe id maps to no county partition: it is not a well-formed parcel id for this corpus.
Fix: Use a parcel id exactly as it rides in grounding evidence or candidate rows; never re-form ids client-side.
integrity_refusedHTTP 404alarmingThe returned row failed byte-exact key verification, so the service refused to serve a possibly wrong row. Refusal beats wrong answers: tested, not apologized for.
Fix: Nothing on your side: the refusal is logged and investigated as a data-integrity event.
Gateway arms (added by the platform)
invalid_keyHTTP 401alarmingThe presented API key is unknown, revoked, or outside its validity window. Unknown keys fail closed.
Fix: Check the key id in your keys table; rotate or mint a new key if it was revoked or expired.
scope_missingHTTP 403actionableThe KEY refused this: it was created without the scope this route needs.
Fix: Mint or rotate a key that carries the needed scope; your plan already allows it.
entitlement_missingHTTP 403actionableThe PLAN refused this: your org tier does not include this capability, so the scope on the key is inert.
Fix: Upgrade the plan, or ask your operator contact to flip the entitlement flag.
license_unacknowledgedHTTP 403actionableThe LICENSE gate refused this: the source is licensed and your org-admin has not completed its click-through acknowledgement yet.
Fix: An org-admin completes the acknowledgement under Layers; the flag flips on the audit row existing.
rate_limitedHTTP 429informationalThe per-key token bucket is empty right now. The response carries RateLimit-* headers and Retry-After.
Fix: Back off per Retry-After; the client library retries this arm automatically with bounded backoff.
quota_exhaustedHTTP 429actionableThe monthly call quota for this organization is spent, so the gateway declines rather than serving work nobody agreed to pay for.
Fix: Watch the quota bar on the usage page, move to a plan with a higher ceiling, or wait for the month to roll over.
data_plane_unreachableHTTP 503alarmingThe gateway could not open a connection to the data plane at all, so no resolution was attempted and nothing was billed.
Fix: Retry once; if it persists this is ours, and the status page carries the incident.
data_plane_timeoutHTTP 504actionableThe data plane accepted the request but did not answer inside the gateway deadline, so the gateway stopped waiting instead of holding your connection open.
Fix: Retry with backoff: a plane that has just scaled up answers the second call from warm.