Documentation ·Docs
API design guidelines

Idempotency

Idempotency-Key makes a POST that creates a resource safe to retry: the header, what the gateway replays, the 409 and 422 answers, and what it never stores.

Read this page in العربية

On this page

At a glance#

A client that loses the answer to a POST cannot tell whether the resource was created. Sending the same Idempotency-Key on the retry makes the second request return the first answer instead of creating a second resource.

ItemRule
HeaderIdempotency-Key, sent once, 1 to 255 printable ASCII characters. A random UUID is a good key.
Applies toA POST that creates a resource
Key not sentThe request behaves as before: no replay, no protection
Same key, same request, inside 24 hoursThe stored status, headers and body, plus Idempotent-Replayed: true. The provider's service is not called again.
Same key, a different request422
Same key while the first request is still running409
Key empty, longer than 255 characters, not printable ASCII, or sent twice400

"The same request" means the same method, route, caller, path with query string and body.

What is stored#

  • Only what the provider's service answered, with a status from 200 to 499 except 408 and 429.
  • A 5xx answer is not stored: the client retries with the same key and the request runs again.
  • A response body larger than 64 KB is not stored, and a request body larger than 64 KB is not handled at all: no replay and no 409 or 422. Split a large payload instead.
  • A refusal by the gateway itself, for example an exhausted quota, is never stored.
  • A retry in the few milliseconds between the response and its storage can still see 409; the client waits and retries.

Which POSTs#

A POST creates a resource when it answers 201, when its operationId starts with create, add, register, submit, subscribe, invite, issue or generate, or when it carries x-api360-creates-resource: true. x-api360-creates-resource: false marks an action that only looks like a creation. A GET, PUT or DELETE is already safe to repeat and needs no key.

In the specification#

Document the header on every such POST, optional and bounded, and declare both conflict answers:

parameters:
  - name: Idempotency-Key
    in: header
    required: false
    description: Send the same key to retry this request safely. Valid for 24 hours.
    schema: { type: string, minLength: 1, maxLength: 255 }
responses:
  "201": { description: Created. }
  "409": { $ref: "#/components/responses/Error" }
  "422": { $ref: "#/components/responses/Error" }

The error codes of the gateway for these cases are idempotency_key_conflict (409), idempotency_key_mismatch (422) and idempotency_key_invalid (400).

Planned

The gateway honours Idempotency-Key on every POST to a product route, with the behaviour in the table above.

The domain APIs of the platform itself (accounts, billing, catalogue and the others) are not behind that gateway feature, so the ruleset does not ask their specifications to document the header.

Checked by#

RuleSeverityChecks
api360-idempotency-key-headererrorA POST that creates a resource documents an optional Idempotency-Key header with a maxLength of at most 255
api360-idempotency-responseserrorThe same POST declares the 409 and 422 responses

Both rules are on in the provider profile and off in the platform profile.

See also#

Was this page helpful?
Updated 2026-10-17