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

# Use Idempotency Keys to Prevent Duplicate Messages

> Protect against network retries creating duplicate WhatsApp messages by sending an Idempotency-Key header with every POST /v1/messages request.

When you send a message over a network, transient errors can leave you unsure whether your request reached the server. If you retry and the original request did succeed, your recipient receives the same message twice. Idempotency keys solve this: you attach a unique key to each request, and RelayOS guarantees that regardless of how many times you send that exact key, only one message is ever dispatched. If RelayOS sees a key it has already processed, it returns the original response without creating a duplicate.

## How to use the `Idempotency-Key` header

Include an `Idempotency-Key` header in every `POST /v1/messages` request. The value is a string of your choosing — typically something that uniquely identifies the specific message you intend to send.

```bash theme={null}
curl -X POST https://api.relayos.com.br/v1/messages \
  -H "Authorization: Bearer rly_live_xxx..." \
  -H "Idempotency-Key: pedido-42-lembrete" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+5511999998888",
    "template": "lembrete_consulta",
    "language": "pt_BR",
    "variables": {
      "1": "João Silva",
      "2": "14h",
      "3": "Dra. Helena"
    }
  }'
```

If you retry this exact request with the same `Idempotency-Key`, RelayOS returns the original response — the same `id`, `status`, and `queuedAt` — without queuing a second message.

## What happens on a duplicate request

When RelayOS receives a `POST /v1/messages` request with a key it has seen before, it:

1. Looks up the stored response for that key.
2. Returns that response immediately with the same HTTP status code.
3. Does **not** create, queue, or send another message.

Your client code can treat a retry response identically to the original — the `id` is the same and you can track the message status normally.

## Best practices for key values

A good idempotency key is **unique per intended message**, not per API call. Combine identifiers that naturally describe what you are sending:

| Scenario             | Example key                  |
| -------------------- | ---------------------------- |
| Order confirmation   | `order-8821-confirmation`    |
| Appointment reminder | `appointment-5503-reminder`  |
| Shipping update      | `shipment-TRK001-dispatched` |
| Password reset       | `user-19-pwd-reset-20260514` |

Keys built from your own entity IDs and event types are safe to reconstruct in a retry without any shared state between processes.

<Warning>
  Never reuse an idempotency key for a different message. If you use the same key for two different recipients or templates, RelayOS will return the original response and the second message will never be sent. Treat each unique key as a permanent token for one specific delivery intent.
</Warning>

## When to use idempotency keys

Use an `Idempotency-Key` on:

* **All retries** — any time your HTTP client re-sends a request after a timeout or connection error.
* **Automated triggers** — background jobs, queued workers, or event-driven functions that may execute more than once due to at-least-once delivery semantics.
* **Critical transactional messages** — confirmations, receipts, or alerts where a duplicate would cause confusion or a compliance issue.

<Info>
  Even when you are confident a request succeeded, always include an idempotency key. The overhead is negligible and the protection it provides is significant in production environments with unreliable networks.
</Info>
