[ADP-130] Idempotent-Key
Overview
POST/PATCH requests are not inherently idempotent, but we can make POST/PATCH requests idempotent by using the Idempotency-Key header, ensuring that multiple identical requests have the same result as a single request. This allows clients to safely retry requests without causing unintended side effects. For more information on idempotency, please refer to ADP-366.
Guidance
APIs SHOULD allow clients to use the Idempotency-Key for POST/PATCH operations to ensure that multiple identical requests are processed only once.
- That is, API designs MAY decide whether the Idempotency-Key is an optional or required parameter.
The server MUST verify that the client-provided Idempotency-Key is unique for each request to prevent duplicate processing.
As suggested by the RFC draft, using UUIDs can ensure that the Idempotency-Key has high uniqueness and randomness.
Clients MAY decide whether to include the Idempotency-Key in the request header. For requests that fail due to network issues, clients can retry with the same Idempotency-Key.
If an API requires an Idempotency-Key, it SHOULD respond with a 400 Bad Request when the key is missing.
If the Idempotency-Key is not mandatory, the API SHOULD still process requests for non-idempotent operations.
Implementation Example
Scenario
A client creates a new resource using a POST request, including an Idempotency-Key to prevent multiple resource creations on retries.
Request
POST /resources HTTP/1.1
Host: api.example.com
Idempotency-Key: 123e4567-e89b-12d3-a456-426614174000
Content-Type: application/json
{
"name": "Example Resource",
"type": "example"
}
Server Processing
- Check the Idempotency-Key upon receiving the request.
- If the Idempotency-Key has not been used before, process the request and create the resource.
- If the Idempotency-Key has been used, return the result of the previous request.
Response
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": "abc123",
"name": "Example Resource",
"type": "example"
}
Example with OpenAPI
openapi: 3.1.0
info:
title: Example API
version: 1.0.0
paths:
/resources:
post:
summary: Create a new resource
operationId: createResource
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
type:
type: string
required:
- name
- type
responses:
'201':
description: Resource created successfully
content:
application/json:
schema:
type: object
properties:
id:
type: string
name:
type: string
type:
type: string
'400':
description: Idempotency-Key is missing
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Error'
parameters:
- name: Idempotency-Key
in: header
required: false
schema:
type: string
description: A unique identifier to ensure idempotency
components:
schemas:
Error:
type: object
properties:
type:
type: string
title:
type: string
detail:
type: string