Reliable API writes

Writing Idempotent API Endpoints

Make repeated requests produce one intended effect through method semantics, operation keys, atomic storage, and replay rules.

How this page is maintained

Written for learners, checked against the sources below, and reviewed every quarter. Last reviewed July 27, 2026.

Short answer

An endpoint is idempotent when repeating the same intended operation has no additional effect after the first successful application. PUT and DELETE have idempotent semantics when implemented accordingly. For non-idempotent creates or commands, accept a client-generated operation key, bind it to the authenticated scope and normalized request, store the outcome atomically, and replay that outcome for matching retries.

Who this is for: API developers handling payments, orders, jobs, webhooks, or other writes that clients and infrastructure may retry.

  • Define idempotency around business effect, not merely identical response bytes.
  • Claim an operation key in the same consistency boundary as the protected write.
  • Reject key reuse with different inputs and document retention, in-progress, and failure behavior.

Retries are normal network behavior

A client may send a request, lose the response, and have no way to know whether the server committed. Gateways and job systems can also retry after timeouts. Telling every caller never to retry trades duplicates for lost operations. The API contract should state which operations are safe to repeat and how ambiguous outcomes are resolved.

HTTP calls safe methods those intended only for retrieval and defines several methods as idempotent. Implementation still matters. A DELETE that removes a resource once remains idempotent even if a later response differs because the resource is already absent. A PUT that increments a counter instead of replacing state violates the expected semantics.

Operation keys protect commands

For a create or consequential command, the client generates a high-entropy key for one logical operation and keeps it across retries. The server scopes that key to the authenticated tenant or principal and endpoint. It records a request fingerprint, processing state, and eventual response. A different operation must use a new key.

If the same key arrives with different normalized input, reject it rather than returning an unrelated result. Avoid fingerprints based on unstable serialization or mutable headers. Do not rely on a key alone for authentication. A caller should never be able to retrieve another tenant's result by guessing or obtaining that tenant's operation key.

Atomic claims close the race

Checking for a key and then inserting it in separate unprotected steps creates a race. Use a uniqueness constraint and transaction, or an atomic conditional create, so only one request claims the operation. Couple the business write and completed outcome where the storage model permits it. Concurrent duplicates can wait, return an in-progress result, or retry later under a documented policy.

Failure semantics need care. A validation failure may be stored and replayed because the same request will not become valid spontaneously. A transient failure might allow another attempt. If the process crashes after the business effect but before recording success, recovery must reconcile from durable state rather than simply run the effect again.

Bound and observe the guarantee

Keys cannot be stored forever without cost. Set retention longer than plausible client and infrastructure retries, publish that window, and decide what happens afterward. Some business operations need a permanent domain uniqueness key in addition to temporary request deduplication. A payment reference or external event identifier can serve that role when its ownership is trustworthy.

Measure original requests, replayed results, input conflicts, concurrent in-progress responses, and recovery cases. Keep sensitive bodies out of logs and stored fingerprints. Test timeout after commit, simultaneous duplicates, process interruption, key reuse with changed input, and expiration. Idempotency is an operated reliability feature, not one header check.

Create one invoice after a timeout

A client submits an invoice creation request and times out before receiving the server's response.

  1. Generate one operation key when the user confirms creation, then preserve it across transport retries.
  2. Authenticate the caller and atomically insert a tenant-scoped key record with a fingerprint of normalized invoice input.
  3. Within the protected workflow, create the invoice under a domain uniqueness rule and save the successful response reference.
  4. On a matching retry, return the recorded invoice result; on changed input with the same key, return a conflict.
  5. Test a lost response after commit and two simultaneous requests, then verify that exactly one invoice exists.
Result: The client can retry an ambiguous timeout without creating a second invoice, and accidental key reuse cannot mask different input.

Idempotency contract template

Publish these rules with every retryable write endpoint.

  • Logical operation: effect protected, endpoint, authenticated scope, and method semantics.
  • Key: creator, format, entropy, reuse rule, request fingerprint, and retention period.
  • Atomicity: claim store, uniqueness rule, business transaction, and completion record.
  • Responses: first success, replay, changed input, in progress, validation failure, and transient failure.
  • Recovery: crash points, reconciliation source, duplicate cleanup, metrics, and support procedure.

Common mistakes

  • Generating a new idempotency key for every retry, which makes each attempt look unrelated.
  • Checking a key before the write without an atomic uniqueness claim, allowing simultaneous duplicates.
  • Returning the old response when the same key is reused with materially different request data.

Try one

Design idempotent handling for a webhook provider that redelivers events until it receives success.

A complete answer authenticates the webhook first, uses the provider's stable event identifier in a uniqueness constraint, and records receipt before or with durable business processing. Duplicate delivery returns success only after the event is safely owned or completed. The design distinguishes retryable processing failure from invalid signatures and tests simultaneous delivery plus a crash after the business update.

Sources

Learn this with a tutor

Tell LearnLive what you already know and what you need to do with idempotent api endpoints.

Build this course