Errors

Every error answers the same JSON shape with a fitting HTTP status:

{
  "error": {
    "code": "not_enough_balance",
    "message": "The card doesn't have enough for this reward.",
    "request_id": "5f0c2a1e-8b3d-4c7a-9e21-6d4b8a0c3f19"
  }
}
  • Branch on code, never on message. Messages are English and may be reworded.
  • details lists field problems for invalid_request: [{ "path": "body.stamps", "message": "…" }]. Paths start with body., query., path. or header.
  • Quote request_id (also in the X-Request-Id header of every answer) when you contact support.
  • New codes may be added within v1 (see Versioning): treat an unknown code by its HTTP status.
  • A 422 loyalty answer such as below_min_bill or not_enough_balance is a normal outcome to show the cashier, not a bug.

All codes

CodeStatusMessageWhat to do
unauthorized401The API key is missing, invalid or revoked.Check the key; it may have been revoked.
forbidden403This API key is limited to another branch.This key is limited to one branch. Use its own branch, or a key for all branches (creating, changing or deleting menu categories and items, and managing webhook endpoints, always needs one). If you sent an Idempotency-Key, this answer is stored with it for 24 hours: once something has changed, send the request with a new key. (Creating a webhook endpoint, rotating its secret and sending a test event ignore the key: nothing is stored for them.)
insufficient_scope403This API key doesn't have the permission for this request.Ask the owner for a key with the permission named in details.required.
api_disabled403API access is turned off for this business.API access is turned off for this business. Ask the business owner; don't retry.
business_suspended403This business is suspended; only reads are allowed.Only reads work while the business is suspended. Don't retry writes.
invalid_request400The request is not valid.Fix the fields listed in details, then send the request again.
not_found404Not found.Check the id. It may have been deleted, or belong to another business or (for a branch key) another branch. If you sent an Idempotency-Key, this answer is stored with it for 24 hours: once something has changed, send the request with a new key.
conflict409A conflicting change happened at the same time. Try again.Something changed at the same moment. Retry; the same Idempotency-Key is fine. For a PATCH, read the item first. With details.reason "limit_reached" (creating an 11th webhook endpoint), retrying won't help: delete an endpoint first.
idempotency_key_required400This request needs an Idempotency-Key header.Send an Idempotency-Key header (your receipt number or a UUID).
idempotency_conflict409This Idempotency-Key was already used for a different request.Use a new Idempotency-Key for a different request.
idempotency_in_progress409A request with this Idempotency-Key is still running.Retry in a second with the same key.
rate_limited429Too many requests.Wait Retry-After seconds.
server_error500Something went wrong on our side.Retry with the same Idempotency-Key; contact support with the request_id if it persists.
no_program422This business has no active loyalty program.The business has no active loyalty program. Ask the owner to set one up. If you sent an Idempotency-Key, this answer is stored with it for 24 hours: once something has changed, send the request with a new key.
below_min_bill422The bill is below the program's minimum.Normal: the bill is under the program's minimum (card.program.min_bill). Tell the cashier; no points this time. If you sent an Idempotency-Key, this answer is stored with it for 24 hours: once something has changed, send the request with a new key.
card_cap_reached422More stamps than the program allows per visit.Send fewer stamps: at most card.program.max_stamps_per_visit per visit. If you sent an Idempotency-Key, this answer is stored with it for 24 hours: once something has changed, send the request with a new key.
reward_unavailable422That reward is not available.Pick a reward_id from the card's rewards. If you sent an Idempotency-Key, this answer is stored with it for 24 hours: once something has changed, send the request with a new key.
not_enough_balance422The card doesn't have enough for this reward.Normal: the card can't afford this reward yet. Show the balance to the cashier. If you sent an Idempotency-Key, this answer is stored with it for 24 hours: once something has changed, send the request with a new key.
already_voided409This event was already voided.Already undone. If you were retrying a void, treat this as success.
program_closed409This event belongs to a closed program.The event belongs to an older program and can't be undone through the API. The owner can adjust the card in the dashboard.
would_go_negative409Voiding this would take the card below zero.The customer already used these stamps or points. The owner can adjust the card in the dashboard.
not_voidable409This event can't be voided.This event came from a program change and can't be undone.
order_not_actionable409The order can't take this action in its current status.Read the order: its status doesn't allow this action (for example serving a rejected order). If you sent an Idempotency-Key, this answer is stored with it for 24 hours: once something has changed, send the request with a new key.
payment_required409This business wants counter orders paid first: mark the order paid, then repeat the action.The business wants counter orders paid first — before serving, or before preparing (then start is refused too). Send mark_paid with a method, then repeat the action. If you sent an Idempotency-Key, this answer is stored with it for 24 hours: once something has changed, send the request with a new key.
already_paid409The order is already paid.Nothing to do: the order is already paid.
category_not_empty409Move or delete the category's items first.Move or delete the category's items first.
external_id_taken409Another item already uses this external_id.Another category (for a category) or another item (for an item) already has this external_id; a category and an item may share one. Update that one, or use PUT …/by-external-id/{code}.
bad_category422The category doesn't belong to this business.Use a category_id from GET /menu.
endpoint_inactive409The webhook endpoint is turned off; turn it on first.The webhook endpoint is turned off. Turn it on (PATCH with status "active"), then send the test event again.

Next: Pagination, filtering & sync →