Skip to main content

Errors & rate limits

The error envelope

Every error response is JSON with a machine-readable code:

{ "code": "INVALID_CREDENTIALS", "error": "Invalid identifier or password" }

Always branch on code, never on errorerror is an English debug string that can change without notice and should never be shown to an end user as-is.

Some codes carry extra fields alongside code/error:

Extra fieldAppears on
retryAfterRATE_LIMITED — seconds until the limit resets
attemptsLeftINVALID_OTP — remaining attempts before lockout
channelVERIFICATION_REQUIRED — which channel (EMAIL/CELLPHONE) needs proving
fieldDUPLICATE_CUSTOMER — which field collided (email/cellphone)
errorsVALIDATION_ERROR — a field → { code, message } map

Edge's own codes

These originate in the gateway itself, regardless of which backend eventually handles the call:

HTTPcodeWhen
401TOUCHPOINT_UNAUTHORIZEDMissing/invalid/disabled touchpoint credential
401UNAUTHENTICATEDMissing/invalid Customer JWT on a customer-scoped call
404ROUTE_NOT_FOUNDNo such endpoint
429RATE_LIMITEDApp-level rate limit exceeded (retryAfter included)
501NOT_IMPLEMENTEDA reserved seam — the backend operation doesn't exist yet
400MALFORMED_REQUESTBody isn't valid JSON
400INVALID_REQUESTA path/query value is malformed (e.g. a non-UUID id)
400VALIDATION_ERRORA field failed validation — see errors
415UNSUPPORTED_MEDIA_TYPEWrong/missing Content-Type
405METHOD_NOT_ALLOWEDWrong HTTP method for the path
500INTERNAL_ERRORUnhandled failure

Backend codes (pass through unchanged)

The Edge API forwards most operations to backend services, and their business-rule errors pass through verbatim — same status, same code, same extra fields. You key off one stable set of codes regardless of which service actually produced it:

HTTPcodeExtra fieldsMeaning
401INVALID_CREDENTIALSWrong identifier/password, or wrong current password on change
400INVALID_OTPattemptsLeftWrong one-time code
400INVALID_REGISTRATION_TOKENBogus, expired, or already-consumed registration session token
409VERIFICATION_REQUIREDchannelTouchpoint requires proof of this channel before an account exists
404CUSTOMER_NOT_FOUNDNo such customer (e.g. a stale JWT)
403CUSTOMER_INACTIVEAccount exists but isn't LIVE + ACTIVE
409VERSION_CONFLICTOptimistic-lock: PATCH /me sent a stale version
409DUPLICATE_CUSTOMERfieldNew email/cellphone collides with another customer
404COUNTRY_NOT_FOUNDUnknown country code on the subdivisions lookup

Rate limiting

The Edge API enforces a per-identifier and per-touchpoint rate limit on sensitive operations (login, registration, password reset). Exceeding it returns:

{ "code": "RATE_LIMITED", "error": "Too many requests", "retryAfter": 30 }

retryAfter is in seconds. Back off and retry after that window — retrying immediately will repeatedly hit the same limit.

Reserved seams return 501, never fake data

A handful of documented endpoints don't have a backend behind them yet (see the Roadmap). Calling them always returns:

{ "code": "NOT_IMPLEMENTED", "error": "Not implemented yet" }

with HTTP 501. Thalamus Lite never fabricates a plausible-looking success response for an unbuilt feature — if you see 501, the operation genuinely isn't live yet.