Appearance
Idempotency & Retries
This page standardizes retry and idempotency guidance across services. When in doubt, follow the service surfaces page for the specific endpoint.
See also:
Safe-to-retry rules (default)
- GET / list / head: safe to retry with the same query and headers.
- Mutation with
expected_revision: safe to retry only if you reuse the sameexpected_revision. On409or428, re-read before retrying. - Create: assume not idempotent unless the service explicitly documents an idempotency key or caller-provided ID. If you did not receive a response, verify via a read/resolve before retrying.
When idempotency is explicit
- MRS supports
idempotency_keyon create/put:- Scope: container + record_id (if provided) or container + idempotency_key (auto-id).
- Window: 24 hours.
- Replays return the first response (errors included).
Service-by-service idempotency support (current)
| Service | Idempotency key | Scope | Retention | Notes |
|---|---|---|---|---|
| MRS | idempotency_key | container + record_id (or container + idempotency_key) | 24h | Replays return original response. |
| SCM | idempotency_key | orgcode + route + idempotency_key | 24h | Implemented on documented create/record/commit endpoints (orders, promises, shipments, tenders, tax, inbox/comments). Replays return original response; mismatch returns 409. |
| PCM | idempotency_key | orgcode + route + idempotency_key | 24h | Implemented on documented create/record/set endpoints (PO, receipt, NPI, RTV, invoice, inbox/comments). Replays return original response; mismatch returns 409. |
| PPM | idempotency_key | orgcode + route + idempotency_key | 24h | Implemented on documented create/record/set endpoints (price, lists, rules, inbox/comments). Replays return original response; mismatch returns 409. |
| ICS | idempotency_key | orgcode + route + idempotency_key | 24h | Implemented on documented create/record/commit endpoints (adjustment, allocation, reservation, transfer, count, inbox/comments). Replays return original response; mismatch returns 409. |
| UAS/USM/OFM/PVM/PMC/CRM/Influencer/Accounting/IPM/RBS/UTL | Varies by service | See service surfaces | — | If an endpoint documents idempotency_key, follow its scope/retention; otherwise assume non-idempotent and verify before retrying. |
Idempotency contract requirements (required)
For every mutation, the service must document:
- Key scope (org/facility/route/entity) and whether the key is mandatory.
- Retention window (minimum duration idempotency is guaranteed).
- Replay behavior (same response vs current snapshot vs explicit "already processed").
- Conflict handling when a key is reused with different payloads.
- Expected-revision interaction for revisioned updates.
Minimum baseline (unless a service explicitly documents stronger rules):
- Scope includes org + route + idempotency_key, and entity id when applicable.
- Retention window is >= 24 hours for hot-path creates; longer windows may be required for order and procurement flows (policy-defined).
- Replays return the original response body and status (no second mutation).
- If payload differs for the same key, return 409 with a stable error tag; no mutation.
- For revisioned updates, replays must not advance revision or alter conflict semantics.
Retry guidance by outcome
- 2xx: do not retry.
- 401/403: do not retry; fix auth/roles/org status first.
- 404: treat as not found or not associated (anti-enumeration). Use the self-check flow before retrying.
- 409/428: conflict or missing revision; re-read, update
expected_revision, then retry if still appropriate. - For 409s, clients should prefer
error.conflict_snapshotwhen present to avoid an extra read. - 429/5xx: retry with exponential backoff and jitter; stop if the error persists or you exceed your client’s retry budget.
Recommended patterns
- Prefer client-side idempotency where supported (for example,
idempotency_keyin MRS). - For network timeouts on create, verify before retrying to avoid duplicates.
- Log and surface
request_id+buildfrom responsestatsto simplify support.