An idempotency key comes from the client or not at all

The server cannot tell two identical requests apart from one request sent twice, because the payload is the same either way — only the client knows which it meant.

POST /api/charges
Idempotency-Key: 9c1f4a7e-3b2d-4f81-a6e0-11d0c8b3f204

{ "amount_cents": 4900, "currency": "GBP" }

# generated ONCE per logical operation, reused for every
# retry of that operation. a fresh key per attempt is the
# original bug with extra machinery.

The instinct when writing a retry loop is to generate a key each time round, which reproduces the double charge exactly. Documenting the per-operation requirement is not optional, because it is the one part of the mechanism the server cannot enforce. A customer legitimately buying the same thing twice within a minute is a different operation with a different key, and no server-side deduplication on payload can distinguish that from a retry.