# Retries and idempotency

How to retry any request safely, so a timeout never sends a customer two replies or runs a refund twice.


Networks fail. Texa is built so you can always send a request again without anything happening twice.

## Idempotency-Key

Any `POST` to the Texa API can carry an `Idempotency-Key` header: a string you choose, unique for
the thing you're doing.

```bash
curl https://api.texadesk.com/v1/conversations \
  -H "Authorization: Bearer $TEXA_API_KEY" \
  -H "Idempotency-Key: open-user-1842-2026-10-19" \
  -H "Content-Type: application/json" \
  -d '{"channel": "web", "customer_ref": "user-1842"}'
```

- The first request runs.
- A retry with the **same key and the same body** gets the same answer back, with the header
  `Idempotent-Replayed: true`. Nothing runs again.
- The same key with a **different body** is a `409`: you've reused a key by mistake.
- Keys are kept for **24 hours**.

Good keys say what they're for: `open-wa-2348031234567`, `refund-order-88-attempt-1`.

## message_id

Messages also take your own `message_id`, which works for as long as the conversation lasts. Send
the same `message_id` again and you get the first answer, marked `"replayed": true`. If your
channel gives each message an id (WhatsApp does), use it.

## When to retry

| Answer | Retry? |
|---|---|
| A timeout or a dropped connection | Yes, with the same key or `message_id` |
| `429` | Yes, after `Retry-After` seconds |
| `5xx` | Yes, after a pause that doubles each time (1 s, 2 s, 4 s…), a few times |
| `4xx` other than 429 | No: the request itself needs fixing |

No SDK retries behind your back: you decide when, and they make it safe by sending the same key.

## What Texa sends you

The other direction works the same way. Action requests carry an `idempotency_key` for your payment
or ledger API, and webhooks carry `X-Texa-Event-Id`. Store what you've handled, and ignore a repeat.
