# Idempotency

> Use Idempotency-Key to retry Mailmanny API requests without sending an email twice.

Source: https://www.mailmanny.com/docs/idempotency
All docs for AI agents: https://www.mailmanny.com/llms.txt

Networks fail. A request can time out after Mailmanny already queued your email. With an Idempotency-Key you can retry as often as you like and the email still goes out once.

## Send a key

**Node.js SDK**

```tsx
await mm.emails.send(
  { from: "Manny <orders@mannysbakery.com>", to: order.email, subject: "Your receipt", react: <Receipt order={order} /> },
  { idempotencyKey: `receipt-${order.id}` },
);
```

**curl**

```bash
curl -X POST https://www.mailmanny.com/api/v1/emails \
  -H "Authorization: Bearer $MAILMANNY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: receipt-1042" \
  -d '{ "from": "Manny <orders@mannysbakery.com>", "to": "sam@example.com", "subject": "Your receipt", "html": "<p>Thanks!</p>" }'
```

Use a value that identifies the thing you're emailing about, like `receipt-1042`, or a UUID you store with the job. Keys are 1–256 printable characters without spaces, and unique per workspace.

## What happens on a retry

- `Same key, same email` (200): The original response, with the original ids. Nothing is sent again.
- `Same key, different email` (409): invalid_idempotent_request: a different recipient or subject reused the key.
- `First request still running` (409): concurrent_idempotent_requests: retry after a moment.
- `First request failed` (—): Nothing was queued, so the retry runs normally.

**409 Conflict**

```json
{
  "statusCode": 409,
  "name": "invalid_idempotent_request",
  "message": "This Idempotency-Key was already used for a different email. Use a new key for a new email."
}
```

## Where it works

- `POST /emails`: the key covers the email to all its recipients.
- `POST /emails/batch`: each email in the batch gets its own derived key. If a batch fails halfway, retrying it with the same key queues only the emails that didn't make it.
- `POST /events`: an event with a key Mailmanny saw in the last 24 hours doesn't start automations again.

Contact upserts, tag edits and template pushes are naturally idempotent: repeating them leaves the same result, so they don't need a key.

> **Good to know:** Retries in the SDK are safe by default
> The SDK only retries POSTs that carry an idempotency key, so a flaky network never turns into a duplicate email.
