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

# Idempotency keys for safe API retries

> Use the Idempotency-Key header to safely retry Straddle API requests without duplicating operations like charges or payouts. Includes best practices.

Straddle supports idempotent API requests, which means you can safely retry requests without fear of performing the same operation multiple times. This is especially important for operations that change state, like creating a payment, where duplicate requests could lead to financial discrepancies.

## Overview

Idempotency is achieved by including a unique `Idempotency-Key` header in your HTTP requests. Straddle then uses this key to detect and prevent duplicate operations. If a request with a given key has already been processed, Straddle will return the original response without re-executing the operation.

<Info>
  Idempotency is currently supported for **POST** and **PATCH** requests only and requires API key authentication.
</Info>

## How it Works

When you send a request with an `Idempotency-Key` header:

1. Straddle checks if a request with that key has been seen before.
2. If it's a new key, the request is processed normally. The key and the request's details (path, method, body hash) are stored.
3. If the key has been seen before:
   * If the previous request with that key is still in progress, a `409 Conflict` error is returned, indicating a concurrent request.
   * If the previous request completed and the requests are identical, the original response is replayed with an `Idempotent-Replayed: true` header.
   * If the idempotency key is reused for a non-identical request, a `409 Conflict` error is returned, indicating that the key has been reused for a different request.
4. Idempotency keys are only stored for a limited period of time (\~24 hours).

## Using Your Idempotency Key

To make an idempotent API request, include a unique string in the `Idempotency-Key` header. We require a key length of 10-40 characters.

Here's an example of how to include the `Idempotency-Key` header in your API requests:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://sandbox.straddle.com/v1/charges \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: unique-client-key-7890" \
    -d '{
      "amount": 100.00,
      "currency": "USD",
    }'
  ```

  ```javascript Node.js theme={null}
  const apiKey = 'YOUR_API_KEY'
  const idempotencyKey = 'unique-client-key-7890'

  async function createCharge() {
    const res = await fetch('https://sandbox.straddle.com/v1/charges', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': idempotencyKey
      },
      body: JSON.stringify({
        amount: 100.00,
        currency: 'USD'
      })
    })
    const json = await res.json()
    console.log(json)
  }
  createCharge().catch(err => console.error('Error:', err))
  ```

  ```python Python theme={null}
  import requests

  api_key = 'YOUR_API_KEY'
  idempotency_key = 'unique-client-key-7890'

  headers = {
      'Authorization': f'Bearer {api_key}',
      'Content-Type': 'application/json',
      'Idempotency-Key': idempotency_key
  }

  payload = {
      "amount": 100.00,
      "currency": "USD"
  }

  response = requests.post('https://sandbox.straddle.com/v1/charges', headers=headers, json=payload)

  print(response.json())
  ```
</CodeGroup>

### Response Headers (Replayed)

When an identical request is successfully replayed, the response will include the original HTTP status code, original response headers, and the original response body, with an additional header:

```
HTTP/1.1 201 Created
Idempotent-Replayed: true
Content-Type: application/json
```

## Handling Idempotency Errors

Straddle will return specific `409 Conflict` errors in idempotency-related scenarios:

### Idempotency Key Reused for a Different Request

If you send a request with an `Idempotency-Key` that was previously used for a different request (e.g., different path, method, or request body), you will receive a `409 Conflict` error.

```json theme={null}
{
  "status": 409,
  "type": "/conflict",
  "title": "Conflict",
  "detail": "Idempotency key already used for a different request."
}
```

**Recommended Action**: Generate a new, unique `Idempotency-Key` for each distinct logical operation.

### Concurrent Request in Progress

If you send a request with an `Idempotency-Key` that is currently being processed by another request, you will receive a `409 Conflict` error.

```json theme={null}
{
  "status": 409,
  "type": "/conflict",
  "title": "Conflict",
  "detail": "Previous identical request currently in progress."
}
```

**Recommended Action**: Backoff and retry the transaction with the same idempotency key. If the retry returns an unsuccessful status, you can safely retry the transaction with a new idempotency key.

### Invalid Idempotency Key

If the `Idempotency-Key` header is supplied and does not meet the length requirements (10-40 characters), a `400 Bad Request` error will be returned.

```json theme={null}
{
  "status": 400,
  "type": "/bad_request",
  "title": "Bad Request",
  "detail": "Validation failed",
  "items": [
    {
      "detail": "The Idempotency-Key header value is not valid."
    }
  ]
}
```

**Recommended Action**: Ensure your `Idempotency-Key` is present and meets the specified length requirements.

## Best Practices

1. **Generate Unique Keys per Business Operation**: For each distinct business operation you initiate, generate a new and unique `Idempotency-Key`. Do not reuse keys across different logical actions.
2. **Use UUIDs**: Universally Unique Identifiers (UUIDs) are an excellent choice for generating idempotency keys due to their high probability of uniqueness.
3. **Handle 409 Conflicts**: Implement logic in your client to properly handle `409 Conflict` responses. For "key already used for a different request," generate a new key. For "previous identical request currently in progress," consider retrying.
4. **Key Length**: Ensure your `Idempotency-Key` is between 10 and 40 characters long.
5. **Avoid Sending Same Key with Different Data**: Never send the same `Idempotency-Key` with a different request body, path, or HTTP method. This will result in a `409 Conflict` error.

## Next Steps

Now that you are familiar with idempotent requests, it's time to start using them. Check out our [API Reference](/api-reference) for detailed information on available endpoints and how to use them.
