Skip to content

Webhooks

Dispatch POSTs delivery-status events to destinations you configure. You can manage destinations from the dashboard or programmatically via the /webhook-configs endpoints.

Webhook Config CRUD

All endpoints below authenticate with an API key (no specific scope required). Each user may configure up to 10 webhook destinations.

Create

POST /api/v1/webhook-configs
Authorization: Bearer {api_key}
json
{
  "name": "Prod delivery webhook",
  "url": "https://yourapp.com/dispatch/webhook",
  "secret": "optional-signing-secret",
  "events": ["delivered", "bounced", "failed"],
  "description": "Production delivery status listener"
}
FieldRequiredDescription
nameNoHuman label
urlYesHTTPS endpoint Dispatch will POST to
secretNoSigning secret. If omitted, Dispatch generates one and returns it.
eventsNoArray of event types to subscribe to. Empty array or omitted = subscribe to all events.
descriptionNoFree-text description

List

GET /api/v1/webhook-configs
Authorization: Bearer {api_key}

Get

GET /api/v1/webhook-configs/{id}
Authorization: Bearer {api_key}

Update

PUT /api/v1/webhook-configs/{id}
Authorization: Bearer {api_key}

All fields optional — supplied fields are updated, others left unchanged.

json
{
  "url": "https://yourapp.com/dispatch/webhook-v2",
  "is_active": true,
  "events": ["delivered", "bounced", "failed", "opened"]
}

Delete

DELETE /api/v1/webhook-configs/{id}
Authorization: Bearer {api_key}

Event payload

When Dispatch sends a webhook, the body is a JSON object:

json
{
  "event": "delivered",
  "message_id": "msg_abc123",
  "recipient": "[email protected]",
  "subject": "Hello World",
  "status": "delivered",
  "provider": "ses",
  "timestamp": 1741363205
}
FieldDescription
eventEvent type — see Event Types
message_idUUID of the Dispatch message
recipientDestination address
subjectEmail subject
statusCurrent message status
providerDelivery provider that produced the event
timestampUnix epoch seconds
errorPresent only on failure events

Headers

HeaderValue
Content-Typeapplication/json
User-AgentDispatch-Webhook/1.0
X-Webhook-Signaturehex(hmac_sha256(body, secret)) when a secret is configured

Signature verification (Node.js example)

js
import crypto from 'node:crypto'

function verify(rawBody, signatureHeader, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex')
  return crypto.timingSafeEqual(
    Buffer.from(expected, 'hex'),
    Buffer.from(signatureHeader, 'hex')
  )
}

Compute the HMAC over the exact raw request body before any JSON parsing.

Event Types

EventTriggered when
queuedMessage accepted into the task queue
sendingWorker begins provider delivery
sentProvider accepted the message
deliveredConfirmed delivered to recipient
bouncedHard or soft bounce reported by the provider
failedPermanent delivery failure
openedRecipient opened the email (if tracking pixel was included)

An empty events array subscribes to all event types above.

Retries

Dispatch retries failed deliveries with exponential backoff. Treat your endpoint as idempotent — the same message_id + event combination may arrive more than once.

Response expectations

Return 2xx within 10 seconds to acknowledge receipt. Any other response (or a timeout) is treated as failure and will be retried.

TechTrans Lab