A retry is not a second write.
A payment capture times out, and the honest next move is to try again. The dishonest result is a second charge. "Our API is idempotent" isn't a policy until someone says what counts as the same attempt and who owns the duplicate.

Before you accept a vendor’s idempotency claim, fill a TWIMCO Idempotency Key Policy Card for one mutating write: key scope, who mints the key, retry window, collision rule, replay response, and the role who owns a duplicate. Score scope, replay, conflict, and owner. Pass only when none is zero and replay is shown.
The header is not the policy
A payment capture times out. An order create returns nothing. A status write lands halfway. The honest next move is often to try again. The dishonest outcome is a second charge, a second fulfillment, or a second record that looks new because nobody named what “the same attempt” means.
Vendors will say the API is idempotent. That sentence is not a policy. A policy says which write the key covers, who mints the key, how long a replay still counts as the same attempt, what happens when the same key arrives with a different payload, what the caller receives on a safe replay, and which role owns a duplicate that already escaped.
This note is the TWIMCO Idempotency Key Policy Card: one page for a single write edge, filled before you treat a retry story as something you can buy. It is a buying instrument, not a benchmark. You record what the vendor can show. You do not invent a duplicate rate to make the sheet look measured. There is no published generator for this card. Copy the fields and fill them in the room.
On Sutton|Place, the ongoing partnership treats verification and who may act as inspectable facts. A retry policy belongs in that family. If the buy is really about writes that must not double-apply across a handoff, the scoping home is business process automation.
Buying teams often accept “we support idempotency keys” the way they accept “we have audit logs”: a checkbox that ends the question. The checkbox does not say whether the key is per request, per order, or per line. It does not say whether a timeout after the commit still returns the original result. It does not say who may decide that two effects were one intention. Those questions show up on the first angry duplicate, which is a poor time to discover that the policy was a header name.
Bring one real write from your operation. Not a tour of the platform. One mutating call that, if it runs twice, costs money, inventory, or trust. If the vendor cannot walk that call, the card stays blank on purpose. Blank is a finding. A demo on a pristine tenant still has to leave the happy path: send the same key twice, then send it again with a changed amount. If they will not, score the missing lines as not shown.
What the card forces you to name
Fill one card per write edge. A platform with forty writes does not get one vague card. Start with the write that hurts when it doubles.
Write edge. Name the operation in the caller’s language and in the vendor’s: capture payment, create fulfillment, mark a lot sold. If you cannot name it, you are not ready to score the key.
System of record. Which store is allowed to say the write happened? A green banner is not the record. The card names the record an operator would open to see whether the effect exists.
Key scope. What does one key mean? Choose, do not stack: one customer intent, one order action, one line, one amount. “The whole request body,” with no rule for which fields may change, is not a scope. Write the fields inside the key and the fields outside it.
Who mints the key. Caller, vendor, or both with a precedence rule. If both can mint and neither wins, retries fork.
Where seen keys live. Name the store and how long the key itself is retained. A key that expires before people actually retry is a second write waiting to happen. Do not invent a duration. Write the duration the vendor implements, or “not shown.”
Retry window. The period during which a replay with the same key is the same attempt. Outside the window, say what the API does: reject, accept as new, or leave it undefined. Undefined fails this line.
Collision rule. Same key and equivalent payload: return the original result and do not re-apply the effect. Same key and different payload: reject. Do not accept a silent merge unless the vendor shows the merge and you write the acceptance on the card. Silent merge is how amounts drift.
Replay response. What the caller receives on a safe replay: the original identifier, a replay flag, both, or an error that looks like a first-time failure. If replay looks like failure, operators will retry again and widen the mess.
Duplicate owner. The role, not a nickname, who may decide that two effects were one intent, and the role who may reverse the extra effect. “Support, somehow” leaves the line incomplete.
Out-of-scope side effects. Emails, picks, ledger lines, or webhooks that fire again even when the key hits. A key that protects the row and not the side effect is a partial policy. List those side effects or write “not demonstrated.”
That field set is the TWIMCO Idempotency Key Policy Card. Another studio can tell you to use idempotency keys. They do not have this field set, the evidence rule below, or your filled lines tied to your write.
How the work moves
Fill one card for one write
- Name the write
One mutating edge, in caller language and vendor language.
- Fix the scope
Fields inside the key, fields outside it, and who mints it.
- Set the window
How long a replay is the same attempt, and what happens after.
- Write the collision
Same payload returns the original. Different payload is rejected.
- Name the owner
The role who may find a duplicate and compensate one effect.
A retry without a key scope is a second write with a cleaner name.
Score what they can show
Score four lines 0, 1, or 2. This is a planning default for a buying conversation, not a certification and not a measured quality score.
Scope shown. 0 means they named a header and could not say what it covers. 1 means scope was described and not walked. 2 means one named write, the fields inside the key, and the fields outside it, shown against a request you recognize.
Replay shown. 0 means no replay. 1 means replay was described. 2 means the same key and the same payload returned the original result without a second effect, and you saw the record.
Conflict shown. 0 means a different payload on the same key was shrugged off. 1 means conflict was mentioned. 2 means a different payload was rejected or otherwise blocked, and the first effect remained.
Duplicate owner shown. 0 means no role. 1 means a queue exists and accountability is fuzzy. 2 means a role can find both effects and is named as the one who may compensate.
Pass rule. Pass only when no line is 0 and at least two lines are 2, and Replay is one of the lines that was shown rather than described. Conditional means no zeros but fewer than two 2s: a dated follow-up owned by a named buyer. Fail means any zero. Do not average a polished header demo over a missing conflict rule. If procurement wants a total, sum the four lines and still refuse a zero. The point of the rule is to stop the average from hiding a hole.
Prefer two scorers: one who calls the API, one who lives with the duplicate. Where they disagree, keep the lower score until the evidence is replayed. “They said they support it” is not a 2. A slide that says “exactly-once” is not a 2. A header echoed in a response, with no second look at the record, is not a 2.
Run the sitting while the recording is fresh. Ask for five minutes of the happy path, then the rest on this one write. If they cannot leave the script, Scope and Replay stay at 0. Attach the card to the buying memo beside the security questionnaire. A product can be careful about access and still double-apply a write.
Window, collision, and the owner of the extra effect
Most retry bugs are unfinished sentences, not exotic puzzles.
The window is shorter than the human retry. The job fails. Someone notices after lunch. They resubmit. The key has expired. The second write is new by policy. The window line exists so you can compare it with how your operators actually retry, not with how a load test retries in a fraction of a second. If you do not know the human delay, write “operators retry the same day” or whatever is true, and ask whether the key still means the same attempt then.
The collision rule is missing. A client retries a corrected amount under the same key. The vendor may keep the first amount and return success, keep the second and leave the first charge, or write both. “Idempotent” is being used for three behaviors. The card makes you pick the one you saw.
The side effect sits outside the key. The order row is deduped. The pick is not. The warehouse does the work twice. The out-of-scope line is where that gap becomes a buying issue instead of a surprise in the first week of production.
The owner is a channel. Someone posts in chat. Two people reverse the extra effect, or nobody does. The duplicate-owner line is done only when a role can see both effects and may compensate one of them without inventing a procedure in the moment.
When you fill these from a demo, mark evidence: a timestamp, a response body, or “not shown.” Do not upgrade “not shown” because the roadmap slide was confident. These patterns are delivery-shaped composites from integration work, not client telemetry and not a claim about any vendor’s defect rate. Use them to recognize a story. Do not publish them as measurements.
If the vendor’s answer is “the queue is idempotent,” ask which write, which consumer, and what happens when the consumer dies after the effect and before the ack. A queue that redelivers is a retry. It still needs a key policy on the effect, or the redelivery is the second write.
Decision guide
A header versus a key policy
| Consideration | Sounds idempotent | Card is fillable |
|---|---|---|
| What the key covers | A header name and a shrug. | One write, with fields inside and outside the key. |
| Same key, same payload | Promised verbally. | Original result shown, and the record did not double. |
| Same key, new amount | Undefined or silently merged. | Rejected, and the first effect is still the effect. |
| When it doubles anyway | Someone posts in chat. | A named role may see both effects and compensate one. |
Put this into practice
- Pick one write that must not double-apply. Put that name at the top of the TWIMCO Idempotency Key Policy Card.
- Fill scope, minter, store, window, collision, replay response, duplicate owner, and side effects. Unknown stays unknown.
- Ask the vendor to show replay and conflict on that write. Score the four lines. Apply the pass rule the same day.
- Keep the card with the buying memo. Re-open it when a release claims the retry behavior changed.
- If the gap is the handoff between caller, record, and the person who may compensate, bring the card into a scoping conversation for business process automation. The operating standard is the one a partnership like Sutton|Place already uses for verification: the fact is inspectable, and the person who may act is named.
A retry is a courtesy to a failed call. It is a second write when the key has no scope, no window, and no owner.
We build alongside the people doing the work.
Bring us the problem you’re thinking about.