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

# Idempotency

> How to safely retry API requests without creating duplicate resources.

Idempotency lets you safely retry requests without side effects. If a network error occurs and you're unsure whether your request succeeded, you can retry with the same idempotency key.

## How It Works

Include an `Idempotency-Key` header with POST requests that create or trigger work. The key lets the server return the original result if your client retries the same request after a timeout or network failure.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://www.agentref.co/api/v1/programs \
    -H "Authorization: Bearer ak_live_YOUR_KEY" \
    -H "Idempotency-Key: create-acme-referrals-v1" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Acme Referrals",
      "commissionType": "recurring",
      "commissionPercent": 25,
      "currency": "USD"
    }'
  ```

  ```javascript Node.js theme={null}
  const program = await client.programs.create({
    name: 'Acme Referrals',
    commissionType: 'recurring',
    commissionPercent: 25,
    currency: 'USD',
  }, {
    idempotencyKey: 'create-acme-referrals-v1',
  })
  ```

  ```python Python theme={null}
  program = client.programs.create(
      name="Acme Referrals",
      commission_type="recurring",
      commission_percent=25,
      currency="USD",
      idempotency_key="create-acme-referrals-v1",
  )
  ```
</CodeGroup>

## Behavior

| Scenario                             | Result                               |
| ------------------------------------ | ------------------------------------ |
| First request with a key             | Processed normally, result cached    |
| Retry with same key + same body      | Returns cached result (no duplicate) |
| Retry with same key + different body | `409 IDEMPOTENCY_KEY_REUSED` error   |
| Key expires (after 24 hours)         | Treated as a new request             |

## Generating Keys

Use a UUID v4 or combine business-meaningful values:

<CodeGroup>
  ```javascript Node.js theme={null}
  import { randomUUID } from 'crypto'

  // Option 1: Random UUID
  const key = randomUUID()

  // Option 2: Business-meaningful (prevents duplicates across retries AND code paths)
  const key = `payout_${affiliateId}_${period}`
  ```

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

  # Option 1: Random UUID
  key = str(uuid.uuid4())

  # Option 2: Business-meaningful
  key = f"payout_{affiliate_id}_{period}"
  ```
</CodeGroup>

## Best Practices

<Info>
  Idempotency keys are only meaningful for mutation requests that accept them. The Node.js and Python SDKs attach idempotency keys to POST requests when you pass the method-specific idempotency option. `GET`, `PATCH`, and `DELETE` requests are not retried through the idempotency cache.
</Info>

* **Always use idempotency keys** for create/action requests such as creating programs, invites, payouts, or marketing resources
* **Use business-meaningful keys** when possible (e.g., `payout_{affiliate_id}_{period}`) to prevent duplicates even across separate code paths
* **Retry with the same key** – don't generate a new key for retries
* **Keys expire after 24 hours** – after that, the same key can be reused
