docs

Idempotency

Every mutating heliumOS endpoint (POST, PUT, DELETE) accepts an Idempotency-Key request header. Set it, and heliumOS will return the same response for the same key — no duplicate side effects — for 24 hours.

Idempotency-Key: 9d4b5b16-5b4f-4f0b-b4d1-7b6a9a3e2c3d

Generate the key on the client side before the request goes out — typically a UUIDv4 per logical operation. Reusing a key for a genuinely new operation is an error.

Scoping

Idempotency keys are scoped by (operator_id, environment_id). You can reuse the same string in sandbox and live without collision, and no other operator can ever collide with yours.

When a replay happens

A replay requires the same request, not just the same key. The key is bound to the method, the path, the query string and the body of the call that first used it — so POST /v1/subscriptions/sub_a/cancel and POST /v1/subscriptions/sub_b/cancel are two operations even though both send an empty body, and they need two keys.

If heliumOS sees a key whose request matches, it replays the original response byte-for-byte, with an extra header:

Idempotent-Replayed: true

If it sees a key that was first used for a different request, it returns 409 Conflict and performs no work. That is the safety net for the mistake that costs the most: reusing one key across two calls would otherwise answer the second from the first's cached response, and your second mutation would never happen while the response told you it had. Mint a new key and send it again.

What to key on

  • Cron jobs that fire every N minutes: key on (job_name, run_at).
  • User-initiated actions: key on a per-action UUID captured once in your UI.
  • Webhook handlers that re-process deliveries on retry: key on the event's id.

What not to key on

  • The wall clock alone. Two requests can arrive in the same second.
  • An incrementing integer with no scope. You will collide across environments or restarts.