Skip to main content
All error responses are JSON with { "error": "<code>", ... }. Some include a details object with extra context.

Authentication & authorisation

CodeHTTPMeaning
missing_bearer_token401No Authorization: Bearer … header on a /me/* call.
invalid_token401JWT could not be verified (signature, exp, iss mismatch, etc.).
unknown_issuer401JWT’s iss doesn’t match any registered partner.
invalid_claims401JWT verified but is missing required claims (sub, role).
missing_partner_slug401/integrations/* request missing x-partner-slug.
missing_signature401/integrations/* request missing x-signature.
unknown_partner401x-partner-slug doesn’t match a known partner.
invalid_signature_format401x-signature parse failed (missing t= or v1=).
signature_expired401Timestamp outside the ±5 min window.
invalid_signature401HMAC did not verify against the body.
partner_disabled403Partner exists but is disabled in admin.
forbidden403Caller has the wrong role for the endpoint.

Consumer & redemption

CodeHTTPMeaning
validation_failed400Zod body validation failed. issues array has details.
voucher_not_found404No voucher with that ID.
voucher_inactive422Voucher exists but is not currently active.
voucher_not_wallet_flow422Tried to claim an instant-flow voucher.
voucher_not_yet_valid422Voucher’s validFrom is in the future.
voucher_expired422Past validUntil.
voucher_out_of_scope403Voucher’s merchant or category is outside your partner allowlist.
voucher_not_valid_at_outlet422Voucher not linked to this outlet.
merchant_not_found404
merchant_inactive422
merchant_out_of_scope403
outlet_not_found404
outlet_inactive422
outlet_pin_not_set422Outlet hasn’t configured a PIN yet — staff needs to set one.
invalid_pin401Wrong 4-digit PIN.
no_claim422Wallet voucher redeemed without first claiming.
voucher_not_yet_applicable422Wallet voucher redeemed before its applicableFrom date. details: { applicableFrom }.
voucher_no_longer_applicable422Wallet voucher redeemed after its applicableUntil date. details: { applicableUntil }.
not_a_favorite403Voucher is favoritesOnly and user hasn’t favorited the merchant.
limit_reached422Per-user cycle redemption count exceeded. details: { limit, used, cycleKey }.
global_cap_reached422Shared cycle cap exhausted across all users for this voucher. details: { cap, used, cycleKey }.
too_far422GPS distance > 150m. details: { distanceMeters, maxMeters }.
codes_exhausted422Manual code pool empty — the merchant needs to upload more.
code_generation_failed500Internal: auto code generator gave up. Treat as retryable.
rate_limited429Too many redemption attempts. details: { retryAfterSeconds }.
user_not_found404(DELETE) No user for (partner, externalUserId).
upsert_failed500(POST users) Race-recovery failed; safe to retry.