# Idempotency

> Making writes safe to retry.

A write is safe to retry when sending it twice has the same effect as sending it once. In the API, handler commands take an idempotency key; most other writes are safe to retry by their nature, as below.

## Which routes accept an idempotency key

`POST /api/v1/agents/{agent_id}/commands` and `POST /api/v1/approvals/decisions` accept an `Idempotency-Key` header:

- 8 to 128 characters of `A-Z a-z 0-9 . _ : -`; anything else is `400 bad_query`, naming `Idempotency-Key`;
- the same person sending the same key gets back **the same command**, with its current status, and no second command is created.

```http
POST /api/v1/agents/research:summary/commands
Idempotency-Key: pause-research-summary-2026-11-01
Content-Type: application/json

{"type": "agent.pause", "params": {"reason": "Checking a source"}}
```

These routes are for a signed-in person only, so the request above is made from that person’s session in LightHouse, never with a key. See [Handlers](/concepts/handlers/).

## How long a key is remembered

As long as the command is kept: a key is matched against every command the same person issued with it. Use a new key for each new intent.

## Writes that are safe to retry without a key

- **`PUT`** routes set a setting to the body you send, so sending the same body twice leaves the same result. Where a setting carries a `version` (access rules, command settings), a write against a stale version is refused (`409 version_conflict`) rather than overwriting someone else’s change.
- **Connecting a connector** to the same target again replaces the old connection, rather than adding a second one.
- **Commands expire.** A command no deployment took before its `ttl_s` (300 seconds by default, 30 to 900) is never run, and the engine refuses a command it has already seen (`replay`).

## Request size caps

| Body                                                      | At most |
| --------------------------------------------------------- | ------- |
| Most writes                                               | 256 KiB |
| A handler command, an approval decision                   | 16 KiB  |
| A connector token                                         | 16 KiB  |
| A connector device approval                               | 8 KiB   |
| A connector approval or device request, a profile request | 4 KiB   |

A larger body is refused with `422 invalid` and read no further.

Source: https://docs.atlanticagenticlabs.com/api/idempotency/
