Idempotency
Stormedo has two separate idempotency boundaries:
- Publisher idempotency prevents the same submission from creating multiple request resources.
- Receiver idempotency prevents duplicate delivery attempts from repeating a business side effect.
You usually need both.
Publisher idempotency
Section titled “Publisher idempotency”Send an Idempotency-Key header when creating a request:
Idempotency-Key: order-123-createdThe reservation is scoped to the project and retained for 24 hours.
During that window:
- The same key with the same input returns the original request.
- The same key with different input returns
409 Conflict. - A new accepted submission without a key creates new work.
- After 24 hours, the key no longer protects a repeated submission. Preserve business idempotency at the receiver as well.
Use a stable business identifier when your application already knows what one logical operation means.
curl --request POST \ 'https://api.stormedo.com/send?url=https://your-app.example/webhook' \ --header "Authorization: Bearer $STORMEDO_TOKEN" \ --header 'Idempotency-Key: order-123-created' \ --header 'Content-Type: application/json' \ --data '{"order_id":"ord_123"}'Recover an unknown submission
Section titled “Recover an unknown submission”A timeout, lost connection, or API 500, 502, or 503 can occur after durable acceptance. Treat the result as unknown, not proof that Stormedo rejected the work.
- Keep the original project, endpoint, idempotency key, and input.
- Retry with that same key and unchanged input within 24 hours. Do not generate a new key for recovery.
- Store the returned request ID and inspect its delivery status. A brief initial
404can mean the read projection has not caught up. - If the original submission had no key, inspect request history and your receiver before resubmitting. A new submission can duplicate accepted work.
A key conflict (409) requires investigation of the original input. Increasing retry frequency or changing the key does not resolve that conflict safely. Use bounded backoff for publisher retries. Destination retry settings apply only after acceptance.
SDK submission behavior
Section titled “SDK submission behavior”The JavaScript and Python SDKs generate one key per logical send. If the API call is interrupted before receiving a response, the SDK safely retries once with the same key.
Pass idempotencyKey in JavaScript or idempotency_key in Python when you want the key to represent a business operation across separate application calls.
Receiver idempotency
Section titled “Receiver idempotency”Stormedo provides at-least-once delivery. A destination can process an attempt successfully before Stormedo records the response, so the same request can arrive again.
Every attempt includes:
Stormedo-Request-Id: req_33uZSQsVaf8aZjDuzkuAqAfter verifying the delivery signature and exact body, commit the stable request ID and the business side effect in the same database transaction. Committing the ID first can lose work if the process crashes before applying the effect.
A common database pattern is:
BEGIN insert request_id into processed_deliveries with a unique constraint if the insert succeeded, apply the business side effectCOMMITWhen the unique insert reports that the ID already exists, return a successful response without applying the side effect again.
Do not use attempt identity
Section titled “Do not use attempt identity”Attempts are operational records. They can change between deliveries of the same logical request.
Deduplicate with the stable Stormedo-Request-Id, not a timestamp, response status, or attempt number. Replay creates a new request ID. Use an additional stable business-operation ID in the payload when the same event must be processed only once across replays and separate submissions.
These transactions protect effects in the same database. For an external API call, use that API’s idempotency mechanism or a transactional outbox; a local deduplication row cannot make a remote side effect atomic. See Receive deliveries for runnable receiver examples.
Batch and schedule keys
Section titled “Batch and schedule keys”Batch creation requires a key for the complete batch and can also include an idempotency key for each item.
Schedule creation requires an Idempotency-Key. Repeating the same definition with the same key returns the original schedule, while changing the definition returns 409 Conflict.