Skip to main content
Send a unique Idempotency-Key header on any POST request and you can safely retry on failure. The server caches the first response (status code and body) and replays it on retries. Keys expire after 24 hours.
curl -X POST https://api.reap.global/cards \
  -H "Authorization: Bearer $REAP_API_KEY" \
  -H "Reap-Version: 2026-01-01" \
  -H "Idempotency-Key: 7e7f1a90-3e0e-4a7e-bd2c-9b3a3c2d8e1f" \
  -H "Content-Type: application/json" \
  -d '{ "userId": "...", "accountId": "...", "type": "VIRTUAL" }'
Generate one key per logical operation. Use a UUIDv4 or any high-entropy string up to 255 characters. Keep the same key across every retry - never generate a new key on each attempt.

Behavior

SituationResponse
First requestExecutes and caches the response.
Retry, same key, same bodyReturns the cached response. Includes Idempotent-Replayed: true response header.
Retry, same key, different body400 IDEMPOTENT_PARAMETER_MISMATCH - use a new key for a different request.
Two concurrent requests, same key409 IDEMPOTENCY_REQUEST_IN_PROGRESS - retry with backoff.
Key reused after 24 hoursTreated as a fresh request.
All outcomes are cached, including 4xx and 5xx. If the first attempt returned a business error, retries replay that error. Fix the input and use a new key to try again. 401, 422, and 429 responses are not cached and are safe to retry with the same key.

Retry pattern

const idempotencyKey = crypto.randomUUID(); // generate once, reuse on retries

async function createCardWithRetry(body) {
  for (let attempt = 0; attempt < 5; attempt++) {
    try {
      const res = await fetch('https://prod.api.reap.global/cards', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${apiKey}`,
          'Reap-Version': '2026-01-01',
          'Idempotency-Key': idempotencyKey,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(body),
      });
      if (res.status === 429 || res.status >= 500) {
        await sleep(2 ** attempt * 1000);
        continue;
      }
      return await res.json();
    } catch {
      await sleep(2 ** attempt * 1000); // network error: safe to retry same key
    }
  }
}

Recommendations

  • Retry on network errors and 429 with the same key. These are the only cases where the original request may not have reached the server.
  • Use a new key after a 4xx business error. The cached error replays on retries; only a new key triggers a fresh attempt.
  • Persist the key before sending if you need guaranteed retry safety after a client crash.