## TL;DR
An idempotency key locks to the first payload it saw. Sending different invoice data under the same key returns a 400. Generate a new key for the new payload, or resend the original payload to get the original result. Never recycle keys across different invoices.

```text
idempotency key reused different payload 400
```

## Use this when
- Invoice creation returns 400 citing the idempotency key and a payload mismatch.
- A retry loop accidentally reused a key with modified invoice data.
- You are designing key generation for invoice creation.

## Not for this skill when
- The retry used the same payload and returned the cached result. That is idempotency working.
- The error is a 409 or a different key error. Check the exact code.

## Steps
1. ('Read the error: it names the idempotency key conflict. Verify: the key was used before with different parameters.', 'Decide intent: if this is a true retry, resend the original payload with the same key and take the cached result. Verify: you get the original invoice back.', 'If this is a genuinely new invoice, generate a fresh unique key and resend. Verify: the new invoice creates.', 'Fix the key generator: keys must be unique per logical operation, typically a UUID per invoice creation attempt. Verify: keys are never reused across operations.', 'Add a test that sends two different payloads under one key and asserts the 400. Verify: your code handles the conflict.')

## Variant phrasings
### stripe idempotency key already used different request
Reordered search.

### idempotency key conflict stripe invoice
Short search.

### stripe 400 idempotency key reuse
Status-code search.


Compatibility: Stripe API idempotency, all endpoints and client versions.

## Why it happens
Idempotency keys exist to make retries safe: same key plus same payload returns the original result instead of double-creating. To keep that guarantee, Stripe binds the key to the payload hash. A different payload under the same key is ambiguous (retry or new operation?), so Stripe rejects it with a 400 instead of guessing. The error is the system refusing to decide for you.

## Edge cases / pitfalls
- UUID per operation is the safe default. Timestamps and customer ids are not unique enough.
- A key that collided for one customer will poison every later use of that key. Scope keys narrowly.
- Server clocks that generate keys from invoice numbers break when numbers repeat. Use random keys.
- Log the key with every invoice creation call. Debugging without it is guesswork.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_L8IAbUFq08WYUot5ITBgWQ
