Errors, retries & limits
Idempotency: retry safely
Every POST needs an Idempotency-Key header, unique per action (a UUID is ideal). If the network fails and you don’t know whether Fidelia received the call, send it again with the same key and the same body:
- if the first call went through, you get its answer again (with
Idempotent-Replayed: true), and nothing happens twice; - if it didn’t, it runs now.
The same key with a different body answers 409 idempotency_mismatch. Keys are kept 24 hours.
If Fidelia can’t be reached, don’t block the customer: finish the sale and retry later with the same key.
Errors
Errors have an HTTP status and a stable code to branch on:
{ "error": "insufficient_balance", "message": "The card balance is too low.", "request_id": "6f1c…" }
message is English, for your logs. field names the invalid parameter on 400; detail sometimes adds the rule that failed.
| Status | Codes |
|---|---|
| 400 | invalid_input (with field), invalid_location |
| 401 | invalid_key |
| 402 | plan_required (the shop isn’t on Pro), subscription_inactive |
| 403 | scope_denied |
| 404 | card_not_found, receipt_not_found, pairing_not_found, milestone_not_found, not_found |
| 409 | insufficient_balance, insufficient_points, insufficient_items, not_ready, already_claimed, reward_ready, wrong_card_type, pack_inactive, membership_expired, membership_inactive, program_inactive, already_reversed, reverse_conflict, reverse_window_expired, idempotency_mismatch |
| 410 | card_voided (the shop erased this customer), pairing_expired, pairing_collected |
| 429 | rate_limited: wait Retry-After seconds |
| 500 | internal_error: retry later with the same idempotency key |
Rate limits
Per key: 10 requests per second and 20,000 per day. Over the limit you get 429 with Retry-After. Need more? Ask us.
Timeouts
Use a 10-second timeout. Most calls answer in well under a second.
Versioning
The version is in the URL (/v1). Within v1 we only add: new fields, new endpoints, new reason or error codes. Ignore fields you don’t know, and treat an unknown error code by its HTTP status. Breaking changes would come as /v2, announced in advance. See the changelog.
Support
Send us the X-Request-Id of the call: it lets us find it in our logs. support@fidelia.se