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

# Idempotency

> Make outbound sends safe to retry without double-texting customers.

Outbound message creates accept an **idempotency key**. Replaying the same key returns the original result instead of placing a second message on the line.

## Why it matters

Your infrastructure will retry:

* HTTP timeouts after Comms already accepted the send
* Queue redelivery
* Deploy mid-request
* Manual “run again” on a failed job

Without idempotency, customers get duplicate texts. With it, retries are free.

## How to send the key

Either header or body (header preferred):

```http theme={null}
Idempotency-Key: order-4242-shipped
```

```json theme={null}
{
  "to": "+12125550147",
  "body": "Your order shipped.",
  "idempotency_key": "order-4242-shipped"
}
```

## Choosing a key

| Good                                          | Why                                |
| --------------------------------------------- | ---------------------------------- |
| `order-{id}-shipped`                          | Stable per business event          |
| `booking-{id}-reminder-t24`                   | Distinct from other reminders      |
| UUID generated once and stored on the job row | Safe if you persist it before POST |

| Avoid                                 | Why                           |
| ------------------------------------- | ----------------------------- |
| `Date.now()` only                     | Every retry is a new key      |
| Random UUID recreated on each attempt | Same problem                  |
| User-visible content of the body      | Collisions and encoding noise |

## Responses

| Status                        | Meaning                                             |
| ----------------------------- | --------------------------------------------------- |
| **202**                       | First acceptance — delivery will proceed            |
| **200** + `"duplicate": true` | Same key already processed — use returned `message` |

Both should count as success in your application.

## Scope

Idempotency applies to **outbound sends** (`POST /api/v1/comms/messages`). List endpoints are read-only and do not need a key.
