# Safe retries

> Send a request again after a timeout without calling anybody twice.

Networks fail in the middle of requests. When you did not get an answer you cannot tell whether the
call was placed — so send your own id for it, and send it again with the same id.

## The Idempotency-Key header

| Request | The header |
|---|---|
| Place a call | Required. Without it: `400 idempotency_key_required`. |
| Start a chat | Optional. The same request again returns the same chat. |
| Send a chat message | Optional. The same message again returns the same reply, without asking the agent twice. |

Up to 120 characters. **Build it from your own data** — `lead-8812-attempt-2`, not a random string
made fresh for each try — so a retry after a crash still carries the same id.

The SDKs make a key for each call and send the same one on each of their own retries. Give your own
through their idempotency key option, or as the `Idempotency-Key` header itself: either way, yours
is the one sent.

## What happens

| Situation | Result |
|---|---|
| Same key, same request | The same conversation as it is now, with the header `Idempotent-Replayed: true`. |
| Same key, a different request | `422 idempotency_key_reused`: the agent, the numbers, the values and the metadata are compared. |
| Same key, two requests at the same moment | One of them places the call; the other gets that call. |
| The call failed after it was saved | A retry returns that failed conversation and never calls again. To call again, use a new key. |

A key belongs to its conversation for as long as the conversation exists — reusing last week's key
returns last week's call. A test key's ids and a live key's never meet.

## Ending

Ending a conversation is always safe to send again: ending one that has already ended returns it.
