> ## Documentation Index
> Fetch the complete documentation index at: https://zenskar.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Idempotent requests

## Overview

To ensure that API requests are handled safely without accidental duplication, Zenskar supports **idempotency**. This is especially useful in scenarios where a network interruption occurs, and you are unsure if your request reached our servers. By retrying the request with the same idempotency key, you guarantee that the operation is performed only once.

<Note>
  Currently, idempotency is supported exclusively for **Usage Event APIs**. Support for other Zenskar APIs will be rolled out in a phased manner.
</Note>

***

## How idempotency works

To make an idempotent request, include a unique key in the `Idempotency-Key` header of your HTTP request.

1. **First Request:** Zenskar processes the request normally and saves the resulting status code and response body.
2. **Subsequent Requests:** If you send another request with the same `Idempotency-Key`, Zenskar skips processing and returns the cached response from the first successful execution.

### Key lifecycle and TTL

* **TTL (time to live):** Idempotency keys are stored for **24 hours**. After 24 hours, a request with the same key will be treated as a new request.
* **Scope:** Keys are scoped to your Organization. You cannot reuse a key across different organizations, but you should ensure uniqueness within your own environment.
* **Payload consistency:** If you retry a request with the same key but change the request body, Zenskar will return an error to prevent accidental data mismatches.

***

## Workflow diagram

The following diagram illustrates how Zenskar handles requests containing an idempotency key:

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant Zenskar API
    participant Cache

    Client->>Zenskar API: POST /usage/api_calls (Idempotency-Key: "unique-key-123")
    Zenskar API->>Cache: Check if "unique-key-123" exists
    
    alt Key not found
        Zenskar API->>Zenskar API: Process request & Save data
        Zenskar API->>Cache: Store Response (TTL 24h)
        Zenskar API-->>Client: 200 OK (Original Response)
    else Key found
        Cache-->>Zenskar API: Return Cached Response
        Zenskar API-->>Client: 200 OK (Cached Response)
    end
```

***

## Example request

To report usage idempotently, add the `Idempotency-Key` header to your request. We recommend using a V4 UUID or another high-entropy string.

```bash theme={null}
curl --location --request POST 'https://api.zenskar.com/usage/api_calls' \
--header 'organisation: 888ae523-9999-4ed7-85cc-6c0a54320568' \
--header 'x-api-key: <your-api-key>' \
--header 'Idempotency-Key: 7b8b8092-2374-42f0-928d-f5370d07412e' \
--header 'Content-Type: application/json' \
--data-raw '{
    "data": {
        "call_count": 5
    },
    "timestamp": "2025-12-17 02:52:04",
    "customer_id": "c02"
}'
```

***

## Error handling and retries

Idempotency is a critical tool for building resilient integrations. Here is how to handle common scenarios:

### Network timeouts

If a request times out or the connection is dropped before you receive a response, you can safely retry the exact same request with the same `Idempotency-Key`. If Zenskar received the first request, you will get the cached result. If we didn't, we will process it for the first time.

### 4xx and 5xx Errors

* **4xx Errors:** If a request fails with a validation error (e.g., `400 Bad Request`), the idempotency key is generally not cached. You should fix the request payload and you can choose to use a new key or the same one depending on the fix.
* **5xx Errors:** If you receive a `500 Internal Server Error` or `503 Service Unavailable`, Zenskar does not cache the result. You should retry these requests with the same idempotency key.
