Skip to content

Errors

Every error — 4xx or 5xx, on every product — uses one envelope:

{
"error": {
"code": "order.invalid_transition",
"message": "Order ord_9d31f2 is cancelled; it cannot move to preparing."
}
}

Branch on error.code, never on error.message. Codes are stable and dot-namespaced (<domain>.<problem>); messages are for humans and may change wording at any time.

StatusMeaningRetry?
400The request is malformed: validation failure, unknown field, bad enum valueNo — fix the request. Retrying the same payload returns the same error
401Missing, expired or invalid credentialRefresh the token, retry once. If it fails again, stop — see Authentication
403Authenticated but not allowed: revoked consent, wrong environment, disallowed operationNo — this does not resolve on its own
404The resource does not exist, or no active integration covers itNo — check the id and the integration state
409Conflict with current state, e.g. a duplicate createNo — read the current state and reconcile
429Rate limitedYes — after the Retry-After delay. See Rate limits
500 / 502 / 503Server-side failureYes — exponential backoff with jitter, cap the attempts
504Gateway timeout — the request may have been appliedYes, but read the resource state first before repeating a write
CodeStatusCause
request.validation400A body or query field failed validation; message names the field
request.unknown_field400The body contains a field the endpoint does not accept (including app_id — the token carries it)
auth.invalid_client401Unknown client_id, wrong secret, or revoked credential
auth.token_expired401Access token past its lifetime
auth.invalid_token401Malformed, revoked or wrong-environment token
auth.invalid_grant400Authorization code expired, reused, or bound to a different redirect_uri
auth.consent_revoked403Merchant uninstalled or revoked your app
store.not_found404Unknown store id, or the store is outside your token’s reach
store.not_integrated404The store exists but has no active integration for your app
menu.push_not_allowed403The integration’s menu_sync_direction does not permit POS-to-Quiqqy pushes
menu.job_not_found404Unknown async menu job id
order.not_found404Unknown order id for your integration
order.invalid_transition409The requested status is not reachable from the order’s current status
rate.limited429Too many requests — the response carries Retry-After
internal.error500Unexpected server failure; safe to retry with backoff

The list grows over time; treat any unrecognised code as non-retryable unless the status row above says otherwise.

Denying (cancelling) an order is not an error — it is a structured outcome. When your POS cannot fulfil an order, send POST /pos/orders/:orderId/cancel with a free-text reason (shown to the customer) and a structured reason_code from this enum, so Quiqqy can inform the customer accurately and remediate automatically:

reason_codeUse whenWhat Quiqqy does
ITEM_OUT_OF_STOCKOne or more lines cannot be madeRefunds; prompts an availability resync so the items stop selling
STORE_CLOSEDThe store is closed despite showing openRefunds; flags the store’s hours for review
POS_OFFLINEThe POS cannot receive or process orders right nowRefunds; can pause the store until you recover
CAPACITYThe kitchen is too busy to take the orderRefunds; capacity signals feed prep-time estimates
PRICE_MISMATCHThe order’s prices disagree with the POS catalogueRefunds; flags the menu for re-sync
OTHERAnything else — include a message explaining itRefunds; the message is surfaced to support
POST /pos/orders/ord_9d31f2/cancel
{
"reason": "Burrata is finished for the day",
"reason_code": "ITEM_OUT_OF_STOCK"
}

reason is free text — it is what the customer sees. The enum lives in reason_code; an optional message can carry additional detail for support.