Idempotency Keys

Idempotency keys are unique identifiers that API clients can provide in HTTP request headers to ensure that a specific API request is not processed multiple times even if it is accidentally sent more than once. This mechanism helps maintain data consistency and prevent undesired side effects like duplicated transactions or repeating customer notifications.

Idempotency keys can be passed to most of the non-idempotent endpoints through a custom header x-idempotency-key. The value of this header should be a unique operation identifier. If the request with the same idempotency key and body has already been processed in the past the response body will be stored in a temporary storage for 48 hours and returned to all subsequent requests with 409 Conflict status code. The 409 responses can be handled by the API client as if it would be a successful response. The use of a separate response code can help API consumers identify the root cause for duplicated requests and fix the issue.

In some cases when two duplicated requests are sent within a short interval of time it is possible that a 423 Locked response code will be returned. The 423 response indicates that the API started processing the previous request, but the response was not generated yet. The API client should retry the request after a reasonable amount of time.

Find below an example of code that illustrates implementing the idempotency keys mechanism using Python's requests library.

import json
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

from logging import getLogger

logger = getLogger("xcover")

url = "https://api.xcover.com/x/partners/YOUR_PARTNER_ID/instant_booking/"

payload = json.dumps({
    # ... generated payload
})

headers = {
    # ... other required headers
    'x-idempotency-key': 'db55f986-c30c-4883-ac4f-0d2cfada6d3f'
}
retry_strategy = Retry(total=3, status_forcelist=[423, 429, 502, 503, 504], backoff_factor=5)

with requests.Session() as session:
    session.mount(url, HTTPAdapter(max_retries=retry_strategy))
    response = session.post(url, headers=headers, data=payload)
    if response.status_code in (200, 409):
        if response.status_code == 409:
            # this request is a duplicate, let's log it as a warning
            logger.warning("duplicated xcover request")

        # successfull response
        print(response.json())
    else:
        # error response
        print(response.status_code)

Last updated