|
| 1 | +--- |
| 2 | +title: Idempotency-Key header |
| 3 | +short-title: Idempotency-Key |
| 4 | +slug: Web/HTTP/Reference/Headers/Idempotency-Key |
| 5 | +page-type: http-header |
| 6 | +browser-compat: http.headers.Idempotency-Key |
| 7 | +spec-urls: https://datatracker.ietf.org/doc/draft-ietf-httpapi-idempotency-key-header/ |
| 8 | +sidebar: http |
| 9 | +--- |
| 10 | + |
| 11 | +The HTTP **Idempotency-Key** {{glossary("request header")}} can be used to make {{HTTPMethod("POST")}} and {{HTTPMethod("PATCH")}} requests {{glossary("idempotent")}}. |
| 12 | + |
| 13 | +It allows clients to resend unacknowledged requests without having to be concerned that the first operation was already received and acted on. |
| 14 | + |
| 15 | +<table class="properties"> |
| 16 | + <tbody> |
| 17 | + <tr> |
| 18 | + <th scope="row">Header type</th> |
| 19 | + <td>{{Glossary("Request header")}}</td> |
| 20 | + </tr> |
| 21 | + <tr> |
| 22 | + <th scope="row">{{Glossary("Forbidden request header")}}</th> |
| 23 | + <td>No</td> |
| 24 | + </tr> |
| 25 | + </tbody> |
| 26 | +</table> |
| 27 | + |
| 28 | +## Syntax |
| 29 | + |
| 30 | +```http |
| 31 | +Idempotency-Key: <key> |
| 32 | +``` |
| 33 | + |
| 34 | +## Directives |
| 35 | + |
| 36 | +- `<key>` |
| 37 | + - : The unique key for a particular message. |
| 38 | + The format is defined by the server. |
| 39 | + |
| 40 | +## Description |
| 41 | + |
| 42 | +The HTTP methods {{HTTPMethod("GET")}}, {{HTTPMethod("HEAD")}}, {{HTTPMethod("PUT")}}, {{HTTPMethod("DELETE")}}, and {{HTTPMethod("OPTIONS")}} are idempotent. |
| 43 | +What this means is that you can send a message with these methods any number of times and you will get the same result. |
| 44 | +For example, if you send the same `PUT` message multiple times it will update the same resource on the server each time, with the same value. |
| 45 | + |
| 46 | +The {{HTTPMethod("POST")}} and {{HTTPMethod("PATCH")}} methods are non-idempotent, which means that the server state may change each time the message is received. |
| 47 | +For example, if you send the same `POST` message multiple times it may create a new record each time. Similarly, a `PATCH` reflects a change with respect to a particular state: calling the same message again will be relative to an already-changed state. |
| 48 | + |
| 49 | +Idempotence is important in cases where a client does not receive a response, because it means the client can safely resend the request without having to worry about possible side effects. |
| 50 | + |
| 51 | +The HTTP `Idempotency-Key` header allows a client to make `POST` and `PATCH` requests idempotent by giving them a unique identifier (key). |
| 52 | +The client can then resend the same request multiple times, and the server can know that it should only perform the action once. |
| 53 | + |
| 54 | +Note that the client should attach the key to every unique request for endpoints that require it. |
| 55 | + |
| 56 | +### Server responsibilities |
| 57 | + |
| 58 | +Servers that support the `Idempotency-Key` header are expected to document and publish their support, including the endpoints that require the header, and any requirements on the key (such as length, computation method, and expiry). |
| 59 | + |
| 60 | +#### Idempotency fingerprint |
| 61 | + |
| 62 | +A particular key is expected to be used in each unique request. |
| 63 | +In order to protect against clients accidentally reusing keys for new requests, a server may create an "Idempotency fingerprint" of the request. |
| 64 | + |
| 65 | +This is a hash of all or part of the request that may be stored along with the key. |
| 66 | + |
| 67 | +#### Request processing |
| 68 | + |
| 69 | +On receiving a `POST` or `PATCH` request with an **Idempotency-Key** on an endpoint that requires it, the server should check whether it already has received a response with that key. |
| 70 | + |
| 71 | +- If it hasn't, the server should perform the operation and respond, and then store the key. |
| 72 | +- If it has, it should not perform the operation, but should respond as though it had. |
| 73 | + |
| 74 | +Servers that are using an idempotency fingerprint would also generate and store a fingerprint for each new request. |
| 75 | +This would be used to respond with an error if a subsequent key and fingerprint did not match. |
| 76 | + |
| 77 | +If a request is received without an **Idempotency-Key** on an endpoint that requires it, the server should respond with an error. |
| 78 | + |
| 79 | +#### Server error responses |
| 80 | + |
| 81 | +A server should provide error responses in the following cases: |
| 82 | + |
| 83 | +- {{HTTPStatus("400", "400 Bad Request")}}: The header is missing for a documented idempotent operation requiring this header. |
| 84 | +- {{HTTPStatus("409", "409 Conflict")}}: A request with the same key is currently/still being processed. |
| 85 | +- {{HTTPStatus("422", "422 Unprocessable Content")}}: The key is already being used for a different request payload. |
| 86 | + |
| 87 | +In the case of a `409 Conflict` response, clients will need to wait before retrying. |
| 88 | +For all the other errors clients will need to amend the requests before resending. |
| 89 | + |
| 90 | +The specification does not mandate the format of the payload but indicates it should contain a link to site-specific documentation explaining the error. |
| 91 | + |
| 92 | +The JSON payload format outlined in {{rfc(9457, "Problem Details for HTTP APIs")}} is one option. |
| 93 | +For example, the following response might be used for a missing key: |
| 94 | + |
| 95 | +```http |
| 96 | +HTTP/1.1 400 Bad Request |
| 97 | +Content-Type: application/problem+json |
| 98 | +Content-Language: en |
| 99 | +{ |
| 100 | + "type": "https://developer.example.com/idempotency/docs", |
| 101 | + "title": "Idempotency-Key is missing", |
| 102 | + "detail": "This operation is idempotent and requires correct usage of Idempotency Key.", |
| 103 | +} |
| 104 | +``` |
| 105 | + |
| 106 | +## Browser integration |
| 107 | + |
| 108 | +TBD |
| 109 | + |
| 110 | +## Examples |
| 111 | + |
| 112 | +TBD |
| 113 | + |
| 114 | +## Specifications |
| 115 | + |
| 116 | +{{Specifications}} |
| 117 | + |
| 118 | +## Browser compatibility |
| 119 | + |
| 120 | +{{Compat}} |
0 commit comments