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

# Idempotency

> Safely retry requests without double-sending

Network issues happen. If a request to `POST /messages` times out, you need to know whether the message actually sent before deciding to retry. Idempotency keys solve this.

## Using an idempotency key

Pass a unique value in the `Idempotency-Key` header on any `POST` request:

```bash theme={null}
curl -X POST https://api.pulsewave.dev/v1/messages \
  -H "Authorization: Bearer pw_live_8f2k9q3m1n7r5t6y4u2i0o8p" \
  -H "Idempotency-Key: order-1042-confirmation" \
  -H "Content-Type: application/json" \
  -d '{ "channel": "email", "to": "ada@example.com", "from": "orders@acme.com", "subject": "Order confirmed", "text": "..." }'
```

If you retry the exact same request with the same key, Pulsewave returns the original response instead of sending a second message — even if the first request is still being processed.

## Choosing a key

A good idempotency key is unique to the operation, not the HTTP request. Derive it from something in your own system, such as an order ID or a job ID, rather than generating a random value on every attempt — a random value defeats the purpose, since a retry would send a *different* key.

```javascript theme={null}
// Good: stable across retries of the same logical operation
const idempotencyKey = `order-${order.id}-confirmation`;

// Bad: a new key every attempt means retries are no longer safe
const idempotencyKey = crypto.randomUUID();
```

## Behavior

* Keys are scoped to your account and remembered for 24 hours.
* Replaying a key with a **different** request body returns a `400` — Pulsewave assumes this is a bug, not an intentional retry.
* Idempotency only applies to `POST` requests that create something (`/messages`, `/templates`, `/contacts`, `/lists`, `/domains`, `/api-keys`, `/webhook-endpoints`). `GET`, `PATCH`, and `DELETE` are already safe to retry on their own.

<Tip>
  Official SDKs generate and attach an idempotency key automatically for retried requests, so you only need to think about this when calling the HTTP API directly.
</Tip>
