Skip to content

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.

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_secret
URL=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.

  1. 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.
  2. Send POST /v1/merchant/webhooks/test. Your endpoint gets webhook.test, with data.test set to true.
  3. Run the quickstart. A robo driver delivers the order in about two minutes, and every status arrives as an event.
  4. 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.