Idempotency
Networks fail. To make retries safe, send an Idempotency-Key header on every request that creates
something (payment intents, checkout sessions, invoices, payment links, wallets, webhook endpoints).
POST /v1/payment-intents HTTP/1.1Authorization: Bearer gp_live_YOUR_KEYIdempotency-Key: order-123Content-Type: application/jsonSemantics
Section titled “Semantics”- The first request with a key is processed normally and its response is stored.
- A repeat with the same key and the same parameters returns the stored response — no second object is created.
- A repeat with the same key but different parameters is rejected with an
idempotency_error. Use a new key for a different operation. - While the first request is still in flight, a concurrent duplicate waits briefly and then receives either the stored response or a conflict telling you to retry.
- Keys are scoped to your organization and environment and may be up to 255 characters.
Payment intents additionally enforce a unique key per organization and environment in the database, so even under heavy parallel retries only one intent is created.
Choosing keys
Section titled “Choosing keys”Derive the key from your own business identifier so that retries — from any process — collapse onto the same object:
await gp.paymentIntents.create(params, { idempotencyKey: `order-${order.id}` });params.IdempotencyKey = "order-" + order.IDintent, err := client.PaymentIntents.Create(ctx, params)gp.payment_intents.create(**params, idempotency_key=f"order-{order.id}")The official SDKs generate a random key for create calls when you do not pass one and reuse it across their own automatic retries.