Idempotency lets you safely retry requests without accidentally performing the same operation twice. This is especially important for mutations like issuing passes, booking sessions, and purchasing credits — where a network timeout could leave you uncertain whether the request succeeded.How to use#
Include a unique Idempotency-Key header on any state-changing request. A UUID is recommended:Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Generate a new key per logical operation. Store the key on your side before sending the request so you can reuse it on retry.Behaviour#
| Scenario | What happens |
|---|
| First request with a new key | Processed normally; response cached for 90 seconds |
| Retry with same key + same body | Cached response returned immediately; X-Idempotent-Replayed: true set on response |
| Same key + different body | 409 idempotency_error with code idempotency_key_reused |
| Concurrent requests with same key | Second request waits for first to complete; both receive the same response |
| No key provided | Request is processed normally; no error |
Detecting a replayed response#
When a cached response is returned, the API sets:X-Idempotent-Replayed: true
You can use this to detect replays in your integration layer.Cache details#
Cache scope: per reseller — keys from different reseller accounts never collide
Cache key: {reseller_id}:{idempotency_key}
Endpoints that accept Idempotency-Key#
| Method | Endpoint | Operation |
|---|
| POST | /issued_passes | Issue a pass |
| POST | /issued_passes/update | Update an issued pass |
| POST | /issued_passes/{id}/expiry | Update issued pass expiry |
| POST | /access-codes | Generate an access code |
| POST | /gym_copay_purchases | Purchase a gym co-pay package |
| POST | /spa_copay_purchases | Purchase a spa co-pay package |
| POST | /bookings/spa | Book a spa service |
| POST | /bookings/class | Book a class |
| POST | /credit_purchases | Purchase credits |
Cancellation endpoints#
POST /bookings/{bookingId}/cancel does not accept an Idempotency-Key. Cancellations are naturally idempotent — cancelling an already-cancelled booking returns a 409 already_cancelled error rather than performing any side effects.Best practices#
Always send an Idempotency-Key on mutation requests in production.
Use UUIDs — they are random enough to avoid collisions across retries.
Do not reuse the same key for different operations.
If you receive a 5xx error, retry with the same key. If you receive a 4xx, fix the request before retrying with a new key.
Modified at 2026-05-19 11:14:33