Rewardly Docs
Guides

Error handling

The error envelope, status codes, and how to react to each.

Every error is JSON with a stable envelope:

{ "error": "insufficient_funds", "message": "Wallet balance is too low for this reward" }

Validation errors (400) also include an issues array with per-field details.

Status codes and what to do

StatuserrorWhat to do
400bad_requestFix the request — the message names each invalid field
401unauthorizedCheck the Authorization: Bearer header and that the key isn't revoked
402insufficient_fundsTop up, then retry
403forbiddenThe key lacks the needed scope (read vs write)
404not_foundWrong id, or the resource belongs to another merchant
422validationThe request is well-formed but can't be fulfilled (e.g. canceling a redeemed reward, amount outside an item's range)
429Rate limited (300 requests/minute). Back off and retry
5xxinternalRetry with backoff; use idempotency keys for sends

Retry rules of thumb

  • Never blind-retry 400/422 — the request will fail the same way.
  • Don't retry 402 until a top-up settles.
  • Do retry timeouts, 429, and 5xx with exponential backoff — and always send an Idempotency-Key on POST /v1/rewards so retries can't double-send.

Card issuance failures

Issuance happens asynchronously, so a 201 from POST /v1/rewards doesn't guarantee every card materializes. If the upstream provider rejects a card, you get a card.failed webhook and the value is re-credited to the reward (choice) or wallet. The reward detail endpoint shows per-card status.

On this page