# 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.

```python
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)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.covergenius.com/xcover/idempotency-keys.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
