Limits and errors
Rate limits, test-mode limits, and every error code a v1 endpoint can return.
Rate limits
Each API key has its own limit, checked per second: a live key may make up to 10 requests per second; a test key, 5 requests per second. Going over either returns 429 RATE_LIMITED with a Retry-After header (seconds to wait). Every authenticated response, whether it succeeds or not, carries X-RateLimit-Limit and X-RateLimit-Remaining so you can back off before you hit the limit rather than after.
http
HTTP/1.1 429 Too Many Requests
Retry-After: 1
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0json
{
"statusCode": 429,
"error": "RATE_LIMITED",
"message": "Limit is 10 requests per second for this key."
}Common errors
| Status | Body / cause |
|---|---|
401 | Missing or invalid X-Api-Key. |
403 | Missing scope(s): <scope> — the key isn't authorized for this call. |
403 | CARD_NOT_IN_ORG — the cardId doesn't belong to your org. |
404 | CARD_NOT_FOUND / CUSTOMER_NOT_FOUND — check the cardId/{ref}. |
409 | AMBIGUOUS_CUSTOMER_MATCH — a call that resolves a customer by email or phone (enroll, GET /v1/customers/lookup, or an email:/phone: {ref}) matched more than one existing customer; nothing written. See CRM and customer data. |
409 | EXTERNAL_ID_ON_OTHER_CARD — enroll was given an externalCustomerId already used on a different card of yours; the body names that cardId and passUserId. Nothing written. Use a different id per card — see CRM and customer data. |
409 | EXTERNAL_ID_TAKEN — PATCH /v1/customers/{ref} tried to set an externalCustomerId already used by a different customer; nothing written. |
409 | TEST_CUSTOMER_LIMIT — a test key tried to enroll a new customer past the 100-customer test-mode cap. Create a live key, or wait — test customers are removed 30 days after creation. |
400 | NOT_AVAILABLE_IN_TEST_MODE — PATCH /v1/cards/{cardId} called with a test key; card settings always need a live key. |
400 | UNSUPPORTED_FOR_CARD_TYPE — e.g. redeeming a level card's fixed reward, or setting points on a stamp card. |
400 | EMAIL_MUST_BE_A_SINGLE_VALUE / PHONE_MUST_BE_A_SINGLE_VALUE — GET /v1/customers/lookup called with email or phone repeated in the query string. |
400 | EMAIL_OR_PHONE_REQUIRED — GET /v1/customers/lookup called with neither email nor phone. |
400 | RESERVED_CUSTOM_FIELDS / UNKNOWN_CUSTOM_FIELDS / INVALID_CUSTOM_FIELD_VALUES — a customFields key is reserved (name/email/phone/status/custom), unknown to the card, or a non-scalar value; the error names the offending key. |
400 | Field validation errors (missing/malformed body fields) — standard Nest validation-error shape. |
Every write endpoint (POST/PATCH under /v1/customers) also accepts an Idempotency-Key header to make retries safe — see Keys and test mode.