Skip to main content
A POST that times out leaves you guessing: the alert, webhook connection, or transcription request may already exist. Send an Idempotency-Key header with the write, resend the same key on every retry, and the request runs at most once. A retry gets the first response back, so you can retry a write the same way you retry a read.

Send a key

Generate one key per logical write, such as a UUID, before the first attempt, and reuse it for every retry of that write:
Run the same command again with the same $KEY and you get the first response back, with Idempotent-Replayed: true, and no second alert. Mint a new key for a new write: a key belongs to one request. A key is 8 to 128 printable ASCII characters. The header is optional; a write sent without it behaves as it always has.

Endpoints that take a key

Each of these carries x-idempotent: true and the Idempotency-Key header parameter in the OpenAPI document, so a generated client can find them. Other endpoints ignore the header. Reads are already safe to retry, and an alert update or a delete can simply be sent again.

What a retry gets back

A request is the same when its method, path, query string, and body bytes all match. Resend the body exactly as you first sent it rather than rebuilding it. A success is replayed for 24 hours. After that the key is forgotten, and a request under it runs as new.

Scope

A key belongs to the API key that sent it. Two API keys can use the same key string without colliding, and one project’s key can never replay another project’s response. A revoked key gets 401 on its retries like on any other request. The header is ignored on a keyless x402 request, which has no credential to hold a key, and on a signed-in session at platform.particle.pro, whose access to a project can be withdrawn while a key is still being replayed.

Limits

  • An organization can start 50,000 keyed writes in 24 hours. Past that, a request with a new key gets 429 rate_limit_exceeded with Retry-After and does not run. Retries of keys already in use still get their answers, and requests without a key are unaffected.
  • If we cannot check the key, the request does not run. A 503 with Retry-After means the key could not be looked up, so the write was refused rather than run unrecorded. Retry with the same key.
  • A failure on our side can still run a write twice. If our server stops, or loses the store that records keys, after the write commits but before its response is recorded, a retry gets 409 idempotency_key_in_use until shortly after the request’s own time limit, and a retry after that runs the write again. This takes a failure on our side at one exact moment; a timeout or a dropped connection on your side does not cause it.
  • MCP tool calls do not take a key. The particle_alert_* tools on the MCP server run without one; check with particle_alert_list before creating an alert again.
Webhook deliveries are the other direction: we retry them to you, and your receiver de-duplicates them on the match id. See Delivery, retries, and idempotency.