Testing webhooks
You can test your handler before Delivr can reach it: sign a sample event yourself, exactly as Delivr does, and post it to your local server.
Send a signed event to localhost
Section titled “Send a signed event to localhost”This needs openssl, jq and curl. Use any secret while you test locally, and the real whsec_… once Delivr gives you one.
SECRET=whsec_local_test_secretURL=http://localhost:3000/hooks/delivr
ID=$(uuidgen 2>/dev/null || cat /proc/sys/kernel/random/uuid)T=$(date +%s)BODY=$(jq -cn --arg id "$ID" --arg at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" '{ id: $id, type: "order.picked_up", apiVersion: "2026-11-01", createdAt: $at, data: { orderId: "3f0e9a52-8a7e-4f8e-9a51-2c0f3c9d1b7a", reference: "DD-482913", externalRef: "order-1001", type: "on_demand", status: "picked_up", version: 9 }}')SIG=$(printf '%s.%s' "$T" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $NF}')
curl -i "$URL" \ -H "Content-Type: application/json" \ -H "User-Agent: Delivr-Webhooks/1" \ -H "X-Delivr-Event: order.picked_up" \ -H "X-Delivr-Event-Id: $ID" \ -H "X-Delivr-Signature: t=$T,v1=$SIG" \ -H "Delivr-Api-Version: 2026-11-01" \ --data-binary "$BODY"Then check what your handler does when you:
| Send | Your handler should |
|---|---|
The same request again (same ID) |
Answer 2xx and change nothing. |
A new ID with a lower version |
Answer 2xx and keep the newer state. |
A type it does not know, such as order.something_new |
Answer 2xx and ignore it. |
A changed body with the old SIG |
Reject it. |
A T more than 5 minutes old |
Reject it. |
Check your signature code against the test vector too.
Receive real sandbox events
Section titled “Receive real sandbox events”- Expose your local server with a URL that does not change, such as an ngrok static domain or a Cloudflare named tunnel, and give it to Delivr (see Get sandbox access). To only look at events, a request inspector such as webhook.site works too.
- Send
POST /v1/merchant/webhooks/test. Your endpoint getswebhook.test, withdata.testset totrue. - Run the quickstart. A robo driver delivers the order in about two minutes, and every status arrives as an event.
- Read the delivery log to see what your endpoint answered, and replay any event to run it through your handler again.
curl -s "$DELIVR_API/v1/merchant/webhooks/deliveries?limit=10" \ -H "Authorization: Bearer $DELIVR_API_KEY" | jq '.items[] | {event, attempt, statusCode, succeeded, error}'
curl -s -X POST "$DELIVR_API/v1/merchant/webhooks/events/$EVENT_ID/replay" \ -H "Authorization: Bearer $DELIVR_API_KEY" \ -H "Idempotency-Key: $(uuidgen 2>/dev/null || cat /proc/sys/kernel/random/uuid)"To see retries, answer 500 for a while: the log shows each attempt on the retry schedule.