Idempotency
Idempotency lets you safely retry a POST request — after a network blip or
a timeout — without risking a duplicate side effect. Send an Idempotency-Key
and Evinor guarantees the operation runs at most once for that key.
Idempotency applies to POST requests only. Other methods are already
naturally idempotent (GET) or address a specific resource (DELETE,
PATCH), so they ignore the header.
Sending an idempotency key
Add an Idempotency-Key header with a unique value you generate — a UUID is a
good choice:
curl -X POST https://api.evinor.ai/v1/sensors \
-H "Authorization: Bearer evnr_live_your_key_here" \
-H "Idempotency-Key: 3f1c9a2e-6b4d-4e2a-9f77-0c53412fd0e1" \
-H "Content-Type: application/json" \
-d '{ "name": "…", "filter": { … }, "actions": [ … ] }'
The key must be 1–255 characters from A-Za-z0-9_-. A key outside that
charset or length returns a 400
validation-failed.
How it behaves
Keys are scoped to your API key. For a given key, Evinor tracks the request and its outcome:
| Situation | Result |
|---|---|
| First use of the key | The request executes normally and its response is stored. |
| Replay — same key, same request, after it completed | The stored response is returned verbatim, with an Idempotency-Replayed: true header. |
| Conflict — same key, a different request | 422 idempotency-key-conflict. |
| In progress — same key, original request still running | 409 idempotency-in-flight. |
"Same request" means the same HTTP method, path, and request body. Reusing a key with any of those changed is treated as a conflict, so give each distinct operation its own key.
Important details
- Validation failures are never cached. If a first attempt fails request
validation (
400), the key is not consumed — fix the payload and retry with the same key. - Replays don't re-run the operation. A replay returns the original stored outcome; it never creates a second resource or fires a second side effect.
- Signing secrets are not replayed. When you create a sensor or rotate a
secret with an
Idempotency-Key, the one-timesigning_secretis present only in the original response. It is omitted from the stored copy, so a replay of the same key returns the sensor withoutsigning_secret. Capture the secret from the first response — see Getting Started. - A stuck request self-heals. If an original request never finished (for example, the caller crashed mid-flight), the key becomes reclaimable after a short window so a later retry with the same key can proceed.
Recommended pattern
- Generate one idempotency key per logical operation (e.g. per "create this sensor" intent), and reuse it across retries of that operation.
- Retry on network errors, timeouts,
409,429, and503using the same key. - On success or on a replay, record the result and stop retrying.