<?xml version="1.0" encoding="utf-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc2629 version 1.3.15 -->

<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
]>

<?rfc toc="yes"?>
<?rfc tocindent="yes"?>
<?rfc sortrefs="yes"?>
<?rfc symrefs="yes"?>
<?rfc strict="yes"?>
<?rfc compact="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>

<rfc ipr="trust200902" docName="draft-idempotency-header-00" category="std">

  <front>
    <title>The Idempotency HTTP Header Field</title>

    <author initials="J." surname="Jena" fullname="Jayadeba Jena">
      <organization></organization>
      <address>
        <email>jjena@paypal.com</email>
        <uri>https://github.com/jayadeba</uri>
      </address>
    </author>
    <author initials="S." surname="Dalal" fullname="Sanjay Dalal">
      <organization></organization>
      <address>
        <email>sanjay.dalal@cal.berkeley.edu</email>
        <uri>https://github.com/sdatspun2</uri>
      </address>
    </author>

    <date year="2020" month="November" day="17"/>

    
    
    

    <abstract>


<t>The <spanx style="verb">HTTP</spanx> Idempotency request header field can be used to carry idempotency key in order to make non-idempotent <spanx style="verb">HTTP</spanx> methods such as <spanx style="verb">POST</spanx> or <spanx style="verb">PATCH</spanx> fault-tolerant.</t>



    </abstract>


  </front>

  <middle>


<section anchor="introduction" title="Introduction">

<t>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 <spanx style="verb">SHOULD</spanx> be the same.</t>

<t>Idempotency is important in building a fault-tolerant <spanx style="verb">HTTP API</spanx>. An <spanx style="verb">HTTP</spanx> request method is considered <spanx style="verb">idempotent</spanx> 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. <xref target="RFC7231"/> defines methods <spanx style="verb">OPTIONS</spanx>, <spanx style="verb">HEAD</spanx>, <spanx style="verb">GET</spanx>, <spanx style="verb">PUT</spanx> and <spanx style="verb">DELETE</spanx> as idempotent. However, <spanx style="verb">POST</spanx> and <spanx style="verb">PATCH</spanx> methods are <spanx style="verb">NOT</spanx> idempotent.</t>

<t>Suppose a client on <spanx style="verb">HTTP API</spanx> wants to create or update a resource using <spanx style="verb">POST</spanx> method. Since <spanx style="verb">POST</spanx> is <spanx style="verb">NOT</spanx> an idempotent method, calling it multiple times can result in duplication or wrong updates. What would happen if you sent out the POST request to the server, but you get a timeout? Is the resource actually created or updated? Does the timeout happened during sending of the request to the server, or while receiving the response on the client? Can we safely retry again, or do we need to figure out first what has happened with the resource? If <spanx style="verb">POST</spanx> was an idempotent method, we would not have to answer such questions. We could safely resend a request until we actually get a response back from the server.</t>

<t>For many use cases in <spanx style="verb">HTTP API</spanx>, creation of duplicate records is a severe problem from business perspective. For example, in Fintech industry, duplicate records for requests involving any kind of payment transaction on a financial account <spanx style="verb">MUST NOT</spanx> be allowed. In other cases, processing of duplicate webhooks due to retries is not warranted.</t>

<section anchor="notational-conventions" title="Notational Conventions">

<t>The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they appear in all capitals, as shown here.</t>

<t>This specification uses the Augmented Backus-Naur Form (ABNF) notation of <xref target="RFC5234"/> and includes, by reference, the IMF-fixdate rule as defined in Section 7.1.1.1 of <xref target="RFC7231"/>.</t>

<t>The term “resource” is to be interpreted as defined in Section 2 of <xref target="RFC7231"/>, that is identified by an URI.</t>

</section>
</section>
<section anchor="the-idempotency-http-request-header-field" title="The Idempotency HTTP Request Header Field">

<t>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 <spanx style="verb">Idempotency-Key</spanx> HTTP request header field carries this key.</t>

<section anchor="syntax" title="Syntax">

<t>The <spanx style="verb">Idempotency-Key</spanx> request header field describes</t>

<figure><artwork><![CDATA[
Idempotency-Key       = idempotency-key-value

idempotency-key-value = opaque-value
opaque-value          = DQUOTE *idempotencyvalue DQUOTE
idempotencyvalue      = %x21 / %x23-7E / obs-text
       ; VCHAR except double quotes, plus obs-text
]]></artwork></figure>

<t>Clients MUST NOT include more than one <spanx style="verb">Idempotency-Key</spanx> header field in the same request.</t>

<t>The following example shows an idempotency key using UUID version 4 scheme:</t>

<figure><artwork><![CDATA[
Idempotency-Key: "8e03978e-40d5-43e8-bc93-6894a57f9324"
]]></artwork></figure>

</section>
<section anchor="uniqueness-of-idempotency-key" title="Uniqueness of Idempotency Key">

<t>The idempotency key that is supplied as part of every <spanx style="verb">POST</spanx> request MUST be unique and can not be reused with another request with a different request payload.</t>

<t>How to make the key unique is up to the client and it’s agreed protocol with the resource owner. It is <spanx style="verb">RECOMMENDED</spanx> that <spanx style="verb">UUID</spanx> or a similar random identifier be used as the idempotency key.</t>

</section>
<section anchor="idempotency-key-validity-and-expiry" title="Idempotency Key Validity and Expiry">

<t>The resource MAY enforce a time based idempotency keys, thus, be able to purge or delete a key upon its expiry. The resource server SHOULD publish expiration policy related documentation.</t>

</section>
<section anchor="idempotency-fingerprint" title="Idempotency Fingerprint">

<t>An idempotency fingerprint MAY be used in conjunction with with an idempotency key to determine the uniqueness of a request and is generated from request payload data. An idempotency fingerprint is generated by the resource implementation. Idempotency Fingerprint generation algorithm MAY use one of the following or similar approaches to generate a fingerprint.</t>

<t><list style="symbols">
  <t>Checksum of the entire request payload.</t>
  <t>Checksum of selected elements in the request payload.</t>
  <t>Field value match for each field in the request payload.</t>
  <t>Field value match for selected elements in the request payload.</t>
  <t>Request digest/signature.</t>
</list></t>

</section>
<section anchor="idempotency-enforcement-scenarios" title="Idempotency Enforcement Scenarios">

<t><list style="symbols">
  <t>First time request (Idempotency Key and Idempotency Fingerprint scenarios has not been seen)  <vspace blankLines='1'/>
The resource server SHOULD process the request normally and respond with an appropriate response and status code.</t>
  <t>Duplicate request (Idempotency Key and Idempotency Fingerprint scenarios has been seen)  <vspace blankLines='1'/>
Replay  <vspace blankLines='1'/>
The request was replayed after the original request completed. The resource server MUST respond with the result of the previously completed operation, success or an error.  <vspace blankLines='1'/>
Concurrent Request  <vspace blankLines='1'/>
The request was replayed before the original request completed. The resource server MUST respond with a resource conflict error. See ## Error Scenarios for details.</t>
</list></t>

</section>
<section anchor="responsibilities" title="Responsibilities">

<t>Client</t>

<t>For the idempotent resource operations, the client MUST present a unique idempotency key in Idempotency-Key request header field.</t>

<t>Resource Server</t>

<t><list style="symbols">
  <t>Generate Idempotency Fingerprint when required.</t>
  <t>Check for idempotency under various scenarios including the ones described earlier.</t>
  <t>Manage the lifecycle of the Idempotency Key.</t>
  <t>Publish idempotency related specification in relevant documentation.</t>
</list></t>

</section>
<section anchor="error-scenarios" title="Error Scenarios">

<t>If the <spanx style="verb">Idempotency-Key</spanx> request header is missing for a documented idempotent operation requiring this header, the resource server MUST reply with an <spanx style="verb">HTTP</spanx> <spanx style="verb">400</spanx> status code with body containing a link pointing to the relevant documentation. Alternately, using the <spanx style="verb">HTTP</spanx> header <spanx style="verb">Link</spanx>, client could be informed about the error too as shown below.</t>

<figure><artwork><![CDATA[
HTTP/1.1 400 Bad Request
Link: <https://developer.example.com/idempotency>;
  rel="describedby"; type="text/html"
]]></artwork></figure>

<t>If there is an attempt to reuse an idempotency key with a different request payload, the resource server MUST reply with an <spanx style="verb">HTTP</spanx> <spanx style="verb">422</spanx> status code with body containing a link pointing to the relevant documentation. Using the <spanx style="verb">HTTP</spanx> header <spanx style="verb">Link</spanx>, client could be informed about the error as following.</t>

<figure><artwork><![CDATA[
HTTP/1.1 422 Unprocessable Entity
Link: <https://developer.example.com/idempotency>;
rel="describedby"; type="text/html"
]]></artwork></figure>

<t>If there is an attempt to reuse an idempotency key that is expired, the resource server MUST reply with an <spanx style="verb">HTTP</spanx> <spanx style="verb">422</spanx> status code with body containing a link pointing to the relevant documentation. Using the <spanx style="verb">HTTP</spanx> header <spanx style="verb">Link</spanx>, client could be informed about the error as following.</t>

<figure><artwork><![CDATA[
HTTP/1.1 422 Unprocessable Entity
Link: <https://developer.example.com/idempotency>;
rel="describedby"; type="text/html"
]]></artwork></figure>

<t>If the request is replayed, while the original request is still processing, the resource server MUST reply with an <spanx style="verb">HTTP</spanx> <spanx style="verb">409</spanx> status code with body containing a link pointing to the relevant documentation. Using the <spanx style="verb">HTTP</spanx> header <spanx style="verb">Link</spanx>, client could be informed about the error as following.</t>

<figure><artwork><![CDATA[
HTTP/1.1 409 Conflict
Link: <https://developer.example.com/idempotency>;
rel="describedby"; type="text/html"
]]></artwork></figure>

<t>For other errors, the resource MUST return the appropriate status code and error message.</t>

</section>
</section>
<section anchor="iana-considerations" title="IANA Considerations">

<section anchor="the-idempotency-key-http-request-header-field" title="The Idempotency-Key HTTP Request Header Field">

<t>The <spanx style="verb">Idempotency-Key</spanx> request header should be added to the permanent registry of message header fields (see <xref target="RFC3864"/>), taking into account the guidelines given by HTTP/1.1 <xref target="RFC7231"/>.</t>

<figure><artwork><![CDATA[
Header Field Name: Idempotency-Key

Applicable Protocol: Hypertext Transfer Protocol (HTTP)

Status: Standard

Author: Jayadeba Jena, <jjena@paypal.com>
        Sanjay Dalal <sanjay.dalal@cal.berkeley.edu>

Change controller: IETF

Specification document: this specification,
            Section 2 "The Idempotency HTTP Request Header Field"
]]></artwork></figure>

</section>
</section>
<section anchor="implementation-status" title="Implementation Status">

<t>Note to RFC Editor: Please remove this section before publication.</t>

<t>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 <xref target="RFC7942"/>.  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.</t>

<t>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”.</t>

<t>Organization: Stripe</t>

<t><list style="symbols">
  <t>Description: Stripe uses custom HTTP header named <spanx style="verb">Idempotency-Key</spanx></t>
  <t>Reference:  https://stripe.com/docs/idempotency</t>
</list></t>

<t>Organization: Adyen</t>

<t><list style="symbols">
  <t>Description: Adyen uses custom HTTP header named <spanx style="verb">Idempotency-Key</spanx></t>
  <t>Reference: https://docs.adyen.com/development-resources/api-idempotency/</t>
</list></t>

<t>Organization: Dwolla</t>

<t><list style="symbols">
  <t>Description: Dwolla uses custom HTTP header named <spanx style="verb">Idempotency-Key</spanx></t>
  <t>Reference: https://docs.dwolla.com/</t>
</list></t>

<t>Organization: Interledger</t>

<t><list style="symbols">
  <t>Description: Interledger uses custom HTTP header named <spanx style="verb">Idempotency-Key</spanx></t>
  <t>Reference: https://github.com/interledger/</t>
</list></t>

<t>Organization: WorldPay</t>

<t><list style="symbols">
  <t>Description: WorldPay uses custom HTTP header named <spanx style="verb">Idempotency-Key</spanx></t>
  <t>Reference: https://developer.worldpay.com/docs/wpg/idempotency</t>
</list></t>

<t>Organization: Yandex</t>

<t><list style="symbols">
  <t>Description: Yandex uses custom HTTP header named <spanx style="verb">Idempotency-Key</spanx></t>
  <t>Reference: https://cloud.yandex.com/docs/api-design-guide/concepts/idempotency</t>
</list></t>

<section anchor="implementing-the-concept" title="Implementing the Concept">

<t>This is a list of implementations that implement the general concept, but do so using different mechanisms:</t>

<t>Organization: Django</t>

<t><list style="symbols">
  <t>Description: Django uses custom HTTP header named <spanx style="verb">HTTP_IDEMPOTENCY_KEY</spanx></t>
  <t>Reference:  https://pypi.org/project/django-idempotency-key</t>
</list></t>

<t>Organization: Twilio</t>

<t><list style="symbols">
  <t>Description: Twilio uses custom HTTP header named <spanx style="verb">I-Twilio-Idempotency-Token</spanx> in webhooks</t>
  <t>Reference: https://www.twilio.com/docs/usage/webhooks/webhooks-connection-overrides</t>
</list></t>

<t>Organization: PayPal</t>

<t><list style="symbols">
  <t>Description: PayPal uses custom HTTP header named <spanx style="verb">PayPal-Request-Id</spanx></t>
  <t>Reference:  https://developer.paypal.com/docs/business/develop/idempotency</t>
</list></t>

<t>Organization: RazorPay</t>

<t><list style="symbols">
  <t>Description: RazorPay uses custom HTTP header named <spanx style="verb">X-Payout-Idempotency</spanx></t>
  <t>Reference: https://razorpay.com/docs/razorpayx/api/idempotency/</t>
</list></t>

<t>Organization: OpenBanking</t>

<t><list style="symbols">
  <t>Description: OpenBanking uses custom HTTP header called <spanx style="verb">x-idempotency-key</spanx></t>
  <t>Reference: https://openbankinguk.github.io/read-write-api-site3/v3.1.6/profiles/read-write-data-api-profile.html#request-headers</t>
</list></t>

<t>Organization: Square</t>

<t><list style="symbols">
  <t>Description: To make an idempotent API call, Square recommends adding a property named <spanx style="verb">idempotency_key</spanx> with a unique value in the request body.</t>
  <t>Reference: https://developer.squareup.com/docs/build-basics/using-rest-api</t>
</list></t>

<t>Organization: Google Standard Payments</t>

<t><list style="symbols">
  <t>Description: Google Standard Payments API uses a property named <spanx style="verb">requestId</spanx> in request body in order to provider idempotency in various use cases.</t>
  <t>Reference: https://developers.google.com/standard-payments/payment-processor-service-api/rest/v1/TopLevel/capture</t>
</list></t>

<t>Organization: BBVA</t>

<t><list style="symbols">
  <t>Description: BBVA Open Platform uses custom HTTP header called <spanx style="verb">X-Unique-Transaction-ID</spanx></t>
  <t>Reference: https://bbvaopenplatform.com/apiReference/APIbasics/content/x-unique-transaction-id</t>
</list></t>

<t>Organization: WebEngage</t>

<t><list style="symbols">
  <t>Description: WebEngage uses custom HTTP header called <spanx style="verb">x-request-id</spanx> to identify webhook POST requests uniquely to achieve events idempotency.</t>
  <t>Reference: https://docs.webengage.com/docs/webhooks</t>
</list></t>

</section>
</section>
<section anchor="security-considerations" title="Security Considerations">

<t>This section is meant to inform developers, information providers,
and users of known security concerns specific to the idempotency keys.</t>

<t>For idempotent request handling, the resources MAY make use of the value in the idempotency key to look up the idempotent request cache such as a persistent store, for duplicate requests, matching the key. If the resource does not validate the value of the idempotency key, prior to performing the lookup, it MAY lead to various forms of security attacks, compromising itself. To avoid such situations, the resource SHOULD publish the expected format of the idempotency key  and always validate the value as per the published specification for the key, before processing the request.</t>

</section>
<section anchor="examples" title="Examples">

<t>The first example shows an idempotency-key header field with key value using UUID version 4 scheme:</t>

<figure><artwork><![CDATA[
Idempotency-Key: "8e03978e-40d5-43e8-bc93-6894a57f9324"
]]></artwork></figure>

<t>Second example shows an idempotency-key header field with key value using some random string generator:</t>

<figure><artwork><![CDATA[
Idempotency-Key: "clkyoesmbgybucifusbbtdsbohtyuuwz"
]]></artwork></figure>

</section>


  </middle>

  <back>

    <references title='Normative References'>





<reference  anchor="RFC7231" target='https://www.rfc-editor.org/info/rfc7231'>
<front>
<title>Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content</title>
<author initials='R.' surname='Fielding' fullname='R. Fielding' role='editor'><organization /></author>
<author initials='J.' surname='Reschke' fullname='J. Reschke' role='editor'><organization /></author>
<date year='2014' month='June' />
<abstract><t>The 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.</t></abstract>
</front>
<seriesInfo name='RFC' value='7231'/>
<seriesInfo name='DOI' value='10.17487/RFC7231'/>
</reference>



<reference  anchor="RFC2119" target='https://www.rfc-editor.org/info/rfc2119'>
<front>
<title>Key words for use in RFCs to Indicate Requirement Levels</title>
<author initials='S.' surname='Bradner' fullname='S. Bradner'><organization /></author>
<date year='1997' month='March' />
<abstract><t>In many standards track documents several words are used to signify the requirements in the specification.  These words are often capitalized. This document defines these words as they should be interpreted in IETF documents.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t></abstract>
</front>
<seriesInfo name='BCP' value='14'/>
<seriesInfo name='RFC' value='2119'/>
<seriesInfo name='DOI' value='10.17487/RFC2119'/>
</reference>



<reference  anchor="RFC8174" target='https://www.rfc-editor.org/info/rfc8174'>
<front>
<title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
<author initials='B.' surname='Leiba' fullname='B. Leiba'><organization /></author>
<date year='2017' month='May' />
<abstract><t>RFC 2119 specifies common key words that may be used in protocol  specifications.  This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the  defined special meanings.</t></abstract>
</front>
<seriesInfo name='BCP' value='14'/>
<seriesInfo name='RFC' value='8174'/>
<seriesInfo name='DOI' value='10.17487/RFC8174'/>
</reference>



<reference  anchor="RFC5234" target='https://www.rfc-editor.org/info/rfc5234'>
<front>
<title>Augmented BNF for Syntax Specifications: ABNF</title>
<author initials='D.' surname='Crocker' fullname='D. Crocker' role='editor'><organization /></author>
<author initials='P.' surname='Overell' fullname='P. Overell'><organization /></author>
<date year='2008' month='January' />
<abstract><t>Internet 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]</t></abstract>
</front>
<seriesInfo name='STD' value='68'/>
<seriesInfo name='RFC' value='5234'/>
<seriesInfo name='DOI' value='10.17487/RFC5234'/>
</reference>



<reference  anchor="RFC3864" target='https://www.rfc-editor.org/info/rfc3864'>
<front>
<title>Registration Procedures for Message Header Fields</title>
<author initials='G.' surname='Klyne' fullname='G. Klyne'><organization /></author>
<author initials='M.' surname='Nottingham' fullname='M. Nottingham'><organization /></author>
<author initials='J.' surname='Mogul' fullname='J. Mogul'><organization /></author>
<date year='2004' month='September' />
<abstract><t>This specification defines registration procedures for the message header fields used by Internet mail, HTTP, Netnews and other applications.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t></abstract>
</front>
<seriesInfo name='BCP' value='90'/>
<seriesInfo name='RFC' value='3864'/>
<seriesInfo name='DOI' value='10.17487/RFC3864'/>
</reference>



<reference  anchor="RFC7230" target='https://www.rfc-editor.org/info/rfc7230'>
<front>
<title>Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing</title>
<author initials='R.' surname='Fielding' fullname='R. Fielding' role='editor'><organization /></author>
<author initials='J.' surname='Reschke' fullname='J. Reschke' role='editor'><organization /></author>
<date year='2014' month='June' />
<abstract><t>The 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 &quot;http&quot; and &quot;https&quot; Uniform Resource Identifier (URI) schemes, defines the HTTP/1.1 message syntax and parsing requirements, and describes related security concerns for implementations.</t></abstract>
</front>
<seriesInfo name='RFC' value='7230'/>
<seriesInfo name='DOI' value='10.17487/RFC7230'/>
</reference>




    </references>

    <references title='Informative References'>





<reference  anchor="RFC7942" target='https://www.rfc-editor.org/info/rfc7942'>
<front>
<title>Improving Awareness of Running Code: The Implementation Status Section</title>
<author initials='Y.' surname='Sheffer' fullname='Y. Sheffer'><organization /></author>
<author initials='A.' surname='Farrel' fullname='A. Farrel'><organization /></author>
<date year='2016' month='July' />
<abstract><t>This 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.</t><t>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.</t></abstract>
</front>
<seriesInfo name='BCP' value='205'/>
<seriesInfo name='RFC' value='7942'/>
<seriesInfo name='DOI' value='10.17487/RFC7942'/>
</reference>




    </references>


<section anchor="acknowledgments" title="Acknowledgments">

<t>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 <eref target="https://github.com/paypal/api-standards/blob/master/patterns.md#idempotency">PayPal</eref> and <eref target="https://stripe.com/docs/idempotency">Stripe</eref> as well as Internet Draft on <eref target="https://tools.ietf.org/html/draft-nottingham-http-poe-00">POST Once Exactly</eref> authored by Mark Nottingham.</t>

<t>The authors take all responsibility for errors and omissions.</t>

</section>
<section anchor="appendix" title="Appendix">

<section anchor="appendix-a-imported-abnf" title="Appendix A.  Imported ABNF">

<t>The following core rules are included by reference, as defined in Appendix B.1 of <xref target="RFC5234"></xref>: 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).</t>

<t>The rules below are defined in <xref target="RFC7230"/>:</t>

<figure><artwork><![CDATA[
 obs-text      = <obs-text, see [RFC7230], Section 3.2.6>
]]></artwork></figure>

</section>
</section>


  </back>

<!-- ##markdown-source:
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

-->

</rfc>

