Skip to content

Errors

Branch on statusMessage and HTTP statusCode, not on translated error.message.

Envelope

json
{
  "success": false,
  "statusCode": 400,
  "statusMessage": "VALIDATION_ERROR",
  "results": null,
  "error": {
    "message": "Validation error",
    "data": []
  }
}

Status messages

statusMessageHTTPWhen
SUCCESS200Generic OK
CREATED200Resource created
UPDATED200Mutation applied (fulfillment actions)
DELETED200Deleted
DATA_LOADED200List / read
VALIDATION_ERROR400Schema or business rule (including maintenance mode)
SLUG_TAKEN400Unique slug clash
OUT_OF_STOCK400Cart / place
CART_EMPTY400Place or cart action
INVALID_CREDENTIALS401Bad staff password or OTP
INVALID_TOKEN401Bad token
TOKEN_EXPIRED401Expired OTP / token
AUTHENTICATION_REQUIRED401Missing customer or staff JWT
UNAUTHENTICATED401JWT rejected
FORBIDDEN403Authenticated but not allowed
ACCESS_DENIED403Missing permission (e.g. orders:update)
RESOURCE_NOT_FOUND404Unknown id
RESOURCE_EXISTS409Duplicate
RATE_LIMITED429Redis rate limit
TOO_MANY_ATTEMPTS429OTP / login throttle
INTERNAL_ERROR500Unexpected
SERVICE_UNAVAILABLE503Dependency down

Auth failures

SituationTypical code
Customer route without BearerAUTHENTICATION_REQUIRED / UNAUTHENTICATED
Staff route without BearerSame
Picker/driver POST without orders:updateACCESS_DENIED
Wrong role UIStill 200 on /auth/me — hide screens using roleKey

Store closed

Mutations to /v1/cart, /v1/orders (POST), and /v1/account/wishlist while maintenance mode is on return VALIDATION_ERROR with a localized store-closed message.

Client checklist

  1. If success === false, show error.message to the user.
  2. If statusCode === 401 on a customer app, call POST /v1/auth/refresh once and retry. If refresh fails, send the user to OTP.
  3. If statusCode === 401 on picker/driver, refresh the staff JWT once; if that fails, send the user to staff login.
  4. Retry 429 with backoff.
  5. After every fulfillment POST, reload the order; do not assume local state.
  6. Assistant POST /v1/assistant/messages and GET /v1/notifications/sse are SSE — parse event: / data: lines, not the JSON envelope.