Delivery verification
Every Stormedo delivery attempt carries a project-scoped Ed25519 delivery token. The token lets a receiver authenticate Stormedo and bind the delivery to the expected project, URL, HTTP method, stable request ID, time window, and body digest.
Delivery headers
Section titled “Delivery headers”Stormedo controls two headers on every attempt:
Stormedo-Request-Id: req_33uZSQsVaf8aZjDuzkuAqStormedo-Signature: compact-EdDSA-JWTReject missing or duplicated values before calling the SDK verifier.
Configure a JavaScript verifier
Section titled “Configure a JavaScript verifier”Create one verifier with the project ID and reuse it.
import { DeliveryVerifier } from "@stormedo/sdk";
const projectId = process.env.STORMEDO_PROJECT_ID!;
const verifier = new DeliveryVerifier(projectId);Authenticate without checking the body in JavaScript
Section titled “Authenticate without checking the body in JavaScript”Use authenticateDelivery only when the runtime cannot provide the raw body. This authenticates Stormedo and the request context, but it does not prove payload integrity.
const delivery = await verifier.authenticateDelivery({ signature, requestId, expectedUrl: "https://your-app.example/webhooks/stormedo", method: "POST",});
delivery.payloadIntegrity; // "unchecked"Verify the exact body in JavaScript
Section titled “Verify the exact body in JavaScript”Capture the raw bytes before a JSON or form parser changes them.
const delivery = await verifier.verifyDelivery({ signature, requestId, expectedUrl: "https://your-app.example/webhooks/stormedo", method: "POST", rawBody,});
delivery.payloadIntegrity; // "verified"Configure a Python verifier
Section titled “Configure a Python verifier”Create one verifier with the project ID and reuse it.
import os
from stormedo import DeliveryVerifier
project_id = os.environ["STORMEDO_PROJECT_ID"]
verifier = DeliveryVerifier(project_id)For asynchronous applications:
from stormedo import AsyncDeliveryVerifier
async_verifier = AsyncDeliveryVerifier(project_id)Authenticate without checking the body in Python
Section titled “Authenticate without checking the body in Python”delivery = verifier.authenticate_delivery( signature=signature, request_id=request_id, expected_url="https://your-app.example/webhooks/stormedo", method="POST",)
assert delivery.payload_integrity == "unchecked"Verify the exact body in Python
Section titled “Verify the exact body in Python”delivery = verifier.verify_delivery( signature=signature, request_id=request_id, expected_url="https://your-app.example/webhooks/stormedo", method="POST", raw_body=raw_body,)
assert delivery.payload_integrity == "verified"Handle verification errors
Section titled “Handle verification errors”Use DeliveryVerificationError.code to handle verification failures.
import { DeliveryVerificationError } from "@stormedo/sdk";
try { await verifier.verifyDelivery({ signature, requestId, expectedUrl: "https://your-app.example/webhooks/stormedo", method: "POST", rawBody, });} catch (error) { if (error instanceof DeliveryVerificationError) { console.error(error.code); }}from stormedo import DeliveryVerificationError
try: verifier.verify_delivery( signature=signature, request_id=request_id, expected_url="https://your-app.example/webhooks/stormedo", method="POST", raw_body=raw_body, )except DeliveryVerificationError as error: print(error.code)Receiver responsibilities
Section titled “Receiver responsibilities”- Build the complete public destination URL from trusted configuration.
- Do not trust forwarded host or protocol headers without an explicit proxy trust boundary.
- Authenticate or verify while the delivery token is current.
- Store the validated request ID before, or atomically with, the business side effect.
- Parse the application body only after verification when payload integrity is required.
Verification proves who sent the request and what it was bound to. Duplicate-safe business processing is covered separately in the advanced Idempotency guide.