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.