The Idempotency-Key HTTP Header Fieldjayadebaj@gmail.comsanjay.dalal@cal.berkeley.eduhttps://github.com/sdatspun2The HTTP Idempotency-Key request header field can be used to carry idempotency key in order to make non-idempotent HTTP methods such as POST or PATCH fault-tolerant.Idempotence is the property of certain operations in mathematics and computer science whereby they can be applied multiple times without changing the result beyond the initial application. It does not matter if the operation is called only once, or 10s of times over. The result SHOULD be the same.Idempotency is important in building a fault-tolerant HTTP API. An HTTP request method is considered idempotent if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. According to , HTTP methods OPTIONS, HEAD, GET, PUT and DELETE are idempotent while methods POST and PATCH are not.Let’s say a client of an HTTP API wants to create (or update) a resource using a POST method. Since POST is NOT an idempotent method, calling it multiple times can result in duplication or wrong updates. Consider a scenario where the client sent a POST request to the server, but it got a timeout. Following questions arise : Is the resource actually created (or updated)? Did the timeout occur during sending of the request, or when receiving of the response? Can the client safely retry the request, or does it need to figure out what happened in the first place? If POST had been an idempotent method, such questions may not arise. Client would safely retry a request until it actually gets a valid response from the server.For many use cases of HTTP APIs, duplicated resources are a severe problem from a business perspective. For example, duplicate records for requests involving any kind of money transfer MUST NOT be allowed. In other cases, processing of duplicate webhook delivery is not expected.{::boilerplate bcp14-tagged}This specification uses the Augmented Backus-Naur Form (ABNF) notation of and includes, by reference, the IMF-fixdate rule as defined in Section 7.1.1.1 of .The term “resource” is to be interpreted as defined in Section 2 of , that is identified by an URI. The term “resource server” is to be interpreted as “origin server” as defined in Section 3 of .An idempotency key is a unique value generated by the client which the resource server uses to recognize subsequent retries of the same request. The Idempotency-Key HTTP request header field carries this key.Idempotency-Key is an Item Structured Header . Its value MUST be a String. Refer to Section 3.3.3 of for ABNF of sf-string:Clients MUST NOT include more than one Idempotency-Key header field in the same request.The following example shows an idempotency key using UUID:The idempotency key that is supplied as part of every POST request MUST be unique and MUST NOT be reused with another request with a different request payload.Uniqueness of the key MUST be defined by the resource owner and MUST be implemented by the clients of the resource server. It is RECOMMENDED that UUID or a similar random identifier be used as an idempotency key.The resource MAY enforce time based idempotency keys, thus, be able to purge or delete a key upon its expiry. The resource server SHOULD define such expiration policy and publish it in the documentation.An idempotency fingerprint MAY be used in conjunction with an idempotency key to determine the uniqueness of a request. Such a fingerprint is generated from request payload data by the resource server. An idempotency fingerprint generation algorithm MAY use one of the following or similar approaches to create a fingerprint.Checksum of the entire request payload.Checksum of selected element(s) in the request payload.Field value match for each field in the request payload.Field value match for selected element(s) in the request payload.Request digest/signature.ClientClients of HTTP API requiring idempotency, SHOULD understand the idempotency related requirements as published by the server and use appropriate algorithm to generate idempotency keys.For each request, client SHOULDSend a unique idempotency key in the HTTP Idempotency-Key request header field.Resource ServerResource server MUST publish idempotency related specification. This specification MUST include expiration related policy if applicable. Server is responsible for managing the lifecycle of the idempotency key.For each request, server SHOULDIdentify idempotency key from the HTTP Idempotency-Key request header field.Generate idempotency fingerprint if required.Check for idempotency considering various scenarios including the ones described in section below.First time request (idempotency key and fingerprint has not been seen)
The resource server SHOULD process the request normally and respond with an appropriate response and status code.Duplicate request (idempotency key and fingerprint has been seen)
Retry
The request was retried after the original request completed. The resource server SHOULD respond with the result of the previously completed operation, success or an error. See Error Scenarios for details on errors.
Concurrent Request
The request was retried before the original request completed. The resource server MUST respond with a resource conflict error. See Error Scenarios for details.If the Idempotency-Key request header is missing for a documented idempotent operation requiring this header, the resource server SHOULD reply with an HTTP 400 status code with body containing a link pointing to relevant documentation. Alternately, using the HTTP header Link, the client can be informed about the error as shown below.If there is an attempt to reuse an idempotency key with a different request payload, the resource server SHOULD reply with a HTTP 422 status code with body containing a link pointing to relevant documentation. The status code 422 is defined in Section 11.2 of . The server can also inform the client by using the HTTP header Link as shown below.If the request is retried, while the original request is still being processed, the resource server SHOULD reply with an HTTP 409 status code with body containing a link or the HTTP header Link pointing to the relevant documentation.Error scenarios above describe the status of failed idempotent requests after the resource server prcocesses them. Clients MUST correct the requests (with the execption of 409 where no correction is required) before performing a retry operation, or the the resource server MUST fail the request and return one of the above errors.For other 4xx/5xx errors, such as 401, 403, 500, 502, 503, 504, 429, or any other HTTP error code that is not listed here, the client SHOULD act appropriately by following the resource server’s documentation.The Idempotency-Key field name should be added to the “Hypertext Transfer Protocol (HTTP) Field Name Registry”.
Idempotency-Key
permanent
This specification, Section 2Note to RFC Editor: Please remove this section before publication.This section records the status of known implementations of the protocol defined by this specification at the time of posting of this Internet-Draft, and is based on a proposal described in . The description of implementations in this section is intended to assist the IETF in its decision processes in progressing drafts to RFCs. Please note that the listing of any individual implementation here does not imply endorsement by the IETF. Furthermore, no effort has been spent to verify the information presented here that was supplied by IETF contributors. This is not intended as, and must not be construed to be, a catalog of available implementations or their features. Readers are advised to note that
other implementations may exist.According to RFC 7942, “this will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature. It is up to the individual working groups to use this information as they see fit”.Organization: StripeDescription: Stripe uses custom HTTP header named Idempotency-KeyReference: https://stripe.com/docs/idempotencyOrganization: AdyenDescription: Adyen uses custom HTTP header named Idempotency-KeyReference: https://docs.adyen.com/development-resources/api-idempotency/Organization: DwollaDescription: Dwolla uses custom HTTP header named Idempotency-KeyReference: https://docs.dwolla.com/Organization: InterledgerDescription: Interledger uses custom HTTP header named Idempotency-KeyReference: https://github.com/interledger/Organization: WorldPayDescription: WorldPay uses custom HTTP header named Idempotency-KeyReference: https://developer.worldpay.com/docs/wpg/idempotencyOrganization: YandexDescription: Yandex uses custom HTTP header named Idempotency-KeyReference: https://cloud.yandex.com/docs/api-design-guide/concepts/idempotencyOrganization: http4s.orgDescription: Http4s is a minimal, idiomatic Scala interface for HTTP services.Reference: https://github.com/http4s/http4sOrganization: FinastraDescription: Finastra uses custom HTTP header named Idempotency-KeyReference: https://developer.fusionfabric.cloud/Organization: DatatransDescription: Datatrans focuses on the technical processing of payments, including hosting smart payment forms and correctly routing payment information.Reference: https://docs.datatrans.ch/docs/api-endpointsThis is a list of implementations that implement the general concept, but do so using different mechanisms:Organization: DjangoDescription: Django uses custom HTTP header named HTTP_IDEMPOTENCY_KEYReference: https://pypi.org/project/django-idempotency-keyOrganization: TwilioDescription: Twilio uses custom HTTP header named I-Twilio-Idempotency-Token in webhooksReference: https://www.twilio.com/docs/usage/webhooks/webhooks-connection-overridesOrganization: PayPalDescription: PayPal uses custom HTTP header named PayPal-Request-IdReference: https://developer.paypal.com/docs/business/develop/idempotencyOrganization: RazorPayDescription: RazorPay uses custom HTTP header named X-Payout-IdempotencyReference: https://razorpay.com/docs/razorpayx/api/idempotency/Organization: OpenBankingDescription: OpenBanking uses custom HTTP header called x-idempotency-keyReference: https://openbankinguk.github.io/read-write-api-site3/v3.1.6/profiles/read-write-data-api-profile.html#request-headersOrganization: SquareDescription: To make an idempotent API call, Square recommends adding a property named idempotency_key with a unique value in the request body.Reference: https://developer.squareup.com/docs/build-basics/using-rest-apiOrganization: Google Standard PaymentsDescription: Google Standard Payments API uses a property named requestId in request body in order to provider idempotency in various use cases.Reference: https://developers.google.com/standard-payments/payment-processor-service-api/rest/v1/TopLevel/captureOrganization: BBVADescription: BBVA Open Platform uses custom HTTP header called X-Unique-Transaction-IDReference: https://bbvaopenplatform.com/apiReference/APIbasics/content/x-unique-transaction-idOrganization: WebEngageDescription: WebEngage uses custom HTTP header called x-request-id to identify webhook POST requests uniquely to achieve events idempotency.Reference: https://docs.webengage.com/docs/webhooksThis section is meant to inform developers, information providers,
and users of known security concerns specific to the idempotency keys.Resource servers that do not implement strong idempotency keys, such as UUIDs, or have appropriate controls to validate the idempotency keys, could be victim to various forms of security attacks from malicious clients:Injection attacks-When the resource server does not validate the idempotency key in the client request and performs a idempotent cache lookup, there can be security attacks (primarily in the form of injection), compromising the server.Data leaks-When an idempotency implementation allows low entropy keys, attackers MAY determine other keys and use them to fetch existing idempotent cache entries, belonging to other clients.To prevent such situations, the specification recommends the following best practices for idempotency key implementation in the resource server.Establish a fixed format for the idempotency key and publish the key’s specification.Always validate the key as per its published specification before processing any request.On the resource server, implement a unique composite key as the idempotent cache lookup key. For example, a composite key MAY be implemented by combining the idempotency key sent by the client with other client specific attributes known only to the resource server.The first example shows an idempotency-key header field with key value using UUID version 4 scheme:Second example shows an idempotency-key header field with key value using some random string generator:Hypertext Transfer Protocol (HTTP/1.1): Semantics and ContentThe Hypertext Transfer Protocol (HTTP) is a stateless \%application- level protocol for distributed, collaborative, hypertext information systems. This document defines the semantics of HTTP/1.1 messages, as expressed by request methods, request header fields, response status codes, and response header fields, along with the payload of messages (metadata and body content) and mechanisms for content negotiation.Augmented BNF for Syntax Specifications: ABNFInternet technical specifications often need to define a formal syntax. Over the years, a modified version of Backus-Naur Form (BNF), called Augmented BNF (ABNF), has been popular among many Internet specifications. The current specification documents ABNF. It balances compactness and simplicity with reasonable representational power. The differences between standard BNF and ABNF involve naming rules, repetition, alternatives, order-independence, and value ranges. This specification also supplies additional rule definitions and encoding for a core lexical analyzer of the type common to several Internet specifications. [STANDARDS-TRACK]Structured Field Values for HTTPThis document describes a set of data types and associated algorithms that are intended to make it easier and safer to define and handle HTTP header and trailer fields, known as "Structured Fields", "Structured Headers", or "Structured Trailers". It is intended for use by specifications of new HTTP fields that wish to use a common syntax that is more restrictive than traditional HTTP field values.A Universally Unique IDentifier (UUID) URN NamespaceThis specification defines a Uniform Resource Name namespace for UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDentifier). A UUID is 128 bits long, and can guarantee uniqueness across space and time. UUIDs were originally used in the Apollo Network Computing System and later in the Open Software Foundation\'s (OSF) Distributed Computing Environment (DCE), and then in Microsoft Windows platforms.This specification is derived from the DCE specification with the kind permission of the OSF (now known as The Open Group). Information from earlier versions of the DCE specification have been incorporated into this document. [STANDARDS-TRACK]HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)Web Distributed Authoring and Versioning (WebDAV) consists of a set of methods, headers, and content-types ancillary to HTTP/1.1 for the management of resource properties, creation and management of resource collections, URL namespace manipulation, and resource locking (collision avoidance).RFC 2518 was published in February 1999, and this specification obsoletes RFC 2518 with minor revisions mostly due to interoperability experience. [STANDARDS-TRACK]Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and RoutingThe Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document provides an overview of HTTP architecture and its associated terminology, defines the "http" and "https" Uniform Resource Identifier (URI) schemes, defines the HTTP/1.1 message syntax and parsing requirements, and describes related security concerns for implementations.Improving Awareness of Running Code: The Implementation Status SectionThis document describes a simple process that allows authors of Internet-Drafts to record the status of known implementations by including an Implementation Status section. This will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature.This process is not mandatory. Authors of Internet-Drafts are encouraged to consider using the process for their documents, and working groups are invited to think about applying the process to all of their protocol specifications. This document obsoletes RFC 6982, advancing it to a Best Current Practice.The following core rules are included by reference, as defined in Appendix B.1 of : ALPHA (letters), CR (carriage return), CRLF (CR LF), CTL (controls), DIGIT (decimal 0-9), DQUOTE (double quote), HEXDIG (hexadecimal 0-9/A-F/a-f), LF (line feed), OCTET (any 8-bit sequence of data), SP (space), and VCHAR (any visible US-ASCII character).The rules below are defined in :The authors would like to thank Mark Nottingham for his support for this Internet Draft. We would like to acknowledge that this draft is inspired by Idempotency related patterns described in API documentation of PayPal and Stripe as well as Internet Draft on POST Once Exactly authored by Mark Nottingham.The authors take all responsibility for errors and omissions.