Idempotency and concurrency
Mutations must remain safe when a client times out, a worker restarts, or two actors modify the same record. The owning operation—not the client library—defines the guarantee.
Idempotency
An idempotency key identifies one intended mutation. Where an operation supports idempotency:
- Generate a cryptographically random key for the business action, not for each network attempt.
- Keep the same key and byte-equivalent semantic payload when retrying an unknown outcome.
- Use a new key for a genuinely new action.
- Persist the key with your local operation record until the server's replay window has elapsed.
- Never derive keys from customer data, sequential IDs, or secrets.
- Treat key reuse with a different payload as a conflict, not a retryable failure.
CRM intake and controlled command implementation evidence records a hash of the idempotency key and request payload so exact replays can return the prior result while mismatched reuse fails. Accounting command and draft flows also expose idempotency or command references in their schemas. Consult the operation page: no estate-wide header name or retention window is yet promised for every mutation.
Replay outcomes
| Situation | Safe client behavior |
|---|---|
| First request succeeds and response arrives | Persist the receipt/result; do not replay |
| First request times out before any response | Reconcile by receipt or replay with the same idempotency key if the operation permits it |
| Same key and same payload | Accept the prior result or replay response as the authoritative outcome |
| Same key and different payload | Stop; surface an idempotency conflict and investigate the caller |
| No idempotency mechanism declared | Treat the outcome as unknown; do not automatically retry a consequential mutation |
| Server says retryable and supplies delay | Retry within a bounded attempt and time budget, preserving the same action identity |
A transport failure does not prove the server performed no work. That small distinction has funded many duplicate invoices throughout history.
Optimistic concurrency
Where a resource exposes recordVersion, expectedVersion, ETag, or another version token:
- Read the current resource.
- Build the mutation against that exact state.
- Send the expected version using the operation's declared field or header.
- On a stale-version conflict, read again and present or apply a deliberate merge.
- Never overwrite by silently replacing the expected version with the newest one.
CRM controlled commands and Accounting draft/settings flows use optimistic version concepts in implementation and contract evidence. Calendar command conflicts protect event, hold, recurrence, and attendance state. The exact field, status, and conflict body are operation-specific.
Command receipts
A command receipt should be treated as durable evidence of acceptance and identity. Depending on the operation, it may contain:
- command or receipt reference;
- resulting resource reference;
- disposition or state;
- resulting record version;
- whether the response is an exact replay;
- correlation identifier;
- timestamps safe for audit and reconciliation.
Do not equate receipt creation with completion of external provider work unless the response explicitly states final completion. For asynchronous work, poll or consume the documented completion event rather than repeating the command.
Retry decision
Did a response arrive?
├─ yes
│ ├─ 2xx: accept the documented result or receipt
│ ├─ conflict: reconcile state or idempotency history; do not blind-retry
│ ├─ 429: wait for Retry-After, add jitter, remain inside retry budget
│ └─ 5xx: retry only when the error model marks it retryable
└─ no
├─ idempotent read: retry with bounded exponential backoff
├─ mutation with accepted idempotency: same key and same payload
└─ mutation without accepted idempotency: outcome unknown; reconcile manually
Recommended client state for a consequential mutation:
{
"localOperationId": "op_01J6EXAMPLE00000000000000",
"idempotencyKey": "b92c835a-8bea-4b94-a82d-4a16f0cb93de",
"contractVersion": "recorded-with-request",
"attempts": 1,
"state": "outcome_unknown",
"remoteReceipt": null
}
Do not log the full private payload alongside this state. Store only what your recovery and audit policy permits.