Idempotency

Created by Kalin Ivanov, Modified on Thu, 18 Jun at 7:21 PM by Kalin Ivanov

The Idempotency-Key header lets you safely retry a request without risk of double-processing.

When is it required, when is it recommended

Endpoint Header
POST /api/v1/payments Required
POST /api/v1/customers Recommended (especially for unattended writes)
Everything else (GET) Not used

If you call POST /payments without an Idempotency-Key, you'll get:

HTTP/1.1 400 Bad Request
{
  "error": {
    "code": "missing_idempotency_key",
    "message": "Idempotency-Key header is required on POST /api/v1/payments"
  }
}

How it works

Idempotency-Key: 9c6a5a52-1aa3-4f6f-9b1d-7d8a5d4e3a2b
  • Pick a stable, unique key per logical attempt — a fresh UUID, or a structured key like order_1234:attempt_1.
  • Send the same key + same body to retry safely. We return the original response — your retry never creates a duplicate payment.
  • Reuse the same key with a different body and we return:
HTTP/1.1 409 Conflict
{
  "error": {
    "code": "key_reused",
    "message": "Idempotency-Key already used with a different request body"
  }
}

The fix is to pick a new key — the new request is genuinely a different operation.

When to pick what

Situation Suggested key
One-shot charge from a fresh checkout A fresh UUID: uuidgen or crypto.randomUUID().
Charge tied to an order in your system order_<id>:attempt_<n> where you bump n only when the request body actually differs.
Scheduled charge subscription_<id>:cycle_<yyyymmdd> — stable across retries within the same cycle, different across cycles.
Customer creation tied to a user signup signup_<user_id> — guarantees that double-clicks don't create two customers.

Key lifetime

  • We retain the idempotency record for 24 hours.
  • Within that window, replays return the original response (with the exact same fields, timestamps, and IDs).
  • After 24 hours, the same key submitted again is treated as a new request.

What it doesn't help with

  • Idempotency-Key isn't a duplicate-charge prevention mechanism beyond the 24-hour window — your own application should still avoid charging the same shopper twice for the same logical order.
  • It doesn't change the outcome of a declined card — a failed response is still the original response, and replaying the key returns the same failure.

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article