The Webhooks dashboard lives at wassist.app/developers/webhooks. Create one there, copy the signing secret, and you’re done.
How a delivery works
Behind the scenes:- The event is committed to our outbox as a
WebhookDeliverywith a stable UUID. - A worker POSTs the JSON body to your URL.
- We record an attempt row with status code, duration, and response body.
- On
5xxor network errors we retry up to 3 times with exponential backoff (10s, 30s, 90s). - After 20 consecutive failures the webhook is auto-disabled and you get a banner in the dashboard.
Headers
| Header | Purpose |
|---|---|
Content-Type | Always application/json. |
User-Agent | Wassist-Webhook/1.0 |
X-Wassist-Event | The event name, e.g. message.received. |
X-Wassist-Delivery | Stable UUID. Use this as your idempotency key. It does not change across retries. |
X-Wassist-Timestamp | Unix seconds. The time we signed the request. |
X-Wassist-Signature | t=<ts>,v1=<hex hmac sha256> — Stripe-style. |
Verifying signatures
ComputeHMAC-SHA256 over the string <timestamp>.<raw body> using the webhook’s signing secret and compare it in constant time to the v1 component.
- Node.js
- Python
- Go
Event catalog
message.received
Fired when a customer sends a message to one of your numbers.
test.ping
Triggered by the dashboard Send test event button. Same envelope as a real event with a stub payload — use it to validate signature verification in CI.
Best practices
- Idempotency. Store the
X-Wassist-DeliveryID and reject duplicates. We use the same ID across all retries. - Respond fast. Send a
2xxwithin 10 seconds and do real work asynchronously. We treat slow responses as failures and retry. - Replay protection. Reject events where
X-Wassist-Timestampis more than 5 minutes from now. - Rotate secrets. From the dashboard, Rotate secret generates a new secret. The old one stops working immediately.
- Local development. Use the CLI:
wassist listentunnels real events tolocalhostwithout exposing a public URL.
Replaying deliveries
Every delivery is stored with its full payload. From the dashboard you can:- Filter deliveries by status (all / failed / succeeded).
- Open a delivery to see request headers, response body, and the timeline of every retry attempt.
- Click Replay to send a fresh copy of the same payload (it gets a new
X-Wassist-DeliveryID).
POST /api/v1/webhook-deliveries/{id}/replay/.