Browse documentation

Idempotency and retry budgets

Make repeated requests safe with action identity, atomic result storage and retries that respect capacity and deadlines.

On this page
Before you start
  • Business action identity
  • A durable outcome store
  • Destination retry semantics

A repeated activation request

The action key and request fingerprint resolve an uncertain outcome without scheduling another activation.

A repeated activation requestStep 1: Caller to API boundary. POST + action key. Step 2: API boundary to Action ledger. Reserve key + fingerprint. Step 3: API boundary to Destination. Execute permitted action. Step 4: Destination to Action ledger. Record final outcome. Step 5: Caller to API boundary. Retry same request. Step 6: API boundary to Caller. Return stored outcome.CallerAPI boundaryAction ledgerDestinationPOST + action key1Reserve key + fingerprint2Execute permitted action3Record final outcome4Retry same request5Return stored outcome6

Scroll across the diagram to see all four systems.

Inspect each exchange

POST + action key

Submit the activation with one identity for the intended business action.

Identify the intended business action

A network request identifier identifies an attempt. An idempotency key identifies the business operation that repeated attempts should share. Scope the key to the authenticated tenant and operation so one tenant cannot collide with another’s work.

Store a canonical request fingerprint with the key. If the same key arrives with different meaningful input, return a conflict rather than treating the new body as the original request. Document which headers and fields contribute to the fingerprint.

Activation with a stable action keyhttp
POST /api/v1/campaign-activations HTTP/1.1
Host: api.example.test
Authorization: Bearer <access_token>
Idempotency-Key: tenant_a:campaign_19:revision_4
Content-Type: application/json

{
  "campaign_id": "campaign_19",
  "revision": 4,
  "audience_id": "audience_28"
}

Reserve and complete the outcome atomically

A read followed by an unconstrained insert can allow two concurrent requests to execute. Use a uniqueness constraint or equivalent atomic reservation around the tenant, operation and key. Represent in progress and completed outcomes separately.

The action ledger alone cannot make an external side effect exactly once. If a worker crashes after a destination accepted the write but before the ledger was updated, recovery must use the destination’s idempotency support or reconcile its current state.

Ledger stateRepeated request behaviorRecovery requirement
Key absentReserve the operation atomically.One owner begins execution.
In progressReturn a defined pending state.Do not launch a second worker for the same action.
Completed, same fingerprintReturn the recorded outcome.Preserve the original business result.
Same key, different fingerprintReject the conflict.Use a new action identity only for an intended new action.
Outcome uncertainReconcile the destination.Do not assume a timeout means no write.

Retry only when repetition is safe

HTTP method idempotence concerns the intended effect, not identical response bytes. RFC 9110 warns against automatically retrying a non idempotent request unless the client knows that repetition is safe or that the original request was not applied.

Separate a failed transport attempt from a business rejection. Validation errors, denied permissions and payload conflicts need correction. Temporary capacity errors may justify a delayed retry when the operation remains within its deadline.

Give retries a finite budget

Use exponential backoff with jitter, a maximum delay and an overall deadline. Retry-After can be a delay in seconds or an HTTP date; parse both supported forms and respect the destination’s documented behavior. A 429 response may include this header but is not required to.

Coordinate rate limits by the provider’s actual boundary, such as account, app or connection. Thousands of workers each implementing their own local limit can still overload the same shared credential. Queue work fairly and surface delayed items to their owner.

Retain identity for the actual replay horizon

Choose retention from retry windows, manual replay expectations and the consequence of duplicate action. After an idempotency record expires, the same key may no longer protect an old operation. Document the behavior rather than implying protection lasts forever.

Test concurrent identical requests, changed payloads under one key, worker crash after destination acceptance, lost responses, expired records and repeated rate limiting. Recovery should preserve the business action identity while creating a new attempt record.

Resolve a repeated operation

Change the key state and fingerprint to see when work is replayed, held or rejected.

POST/api/v1/campaign-activations

Contract inputs

Includes request values and the server validation context defined below.

Expected outcome

HTTP 201

Activation created

A new action identity is reserved before execution.

{
  "activation_id": "activation_42",
  "state": "completed"
}

Decision path

  1. Scope the key to tenant and operation
  2. Reserve the key atomically
  3. Execute the permitted action
  4. Persist its result
Input schema 4 fields
FieldTypeMeaning
ledger_stateRequiredstringDurable state for this action key.Allowed: absent, in_progress, completed
request_fingerprintRequiredstringFingerprint of the submitted meaningful input.
stored_fingerprintRequiredstringFingerprint reserved with the action key.
destination_limitedRequiredbooleanWhether the provider is currently rate limiting this operation.
Download JSON Schema

Standards and documentation

Explore the protocol specifications and platform guidance for this topic.

Bring the contract into your operating environment.

Discuss an implementation

Image preview