Webhooks

Webhooks

Webhooks let your system react to email events as they happen instead of polling GET /v1/emails/{id}. Register an HTTPS endpoint and MailStack will POST a signed JSON payload whenever a subscribed event occurs.

Status: Webhook delivery is on the roadmap. The shapes below reflect the planned contract so you can design against them today; the changelog will announce availability.

Event types

  • email.delivered — accepted by the receiving mail server.
  • email.bounced — rejected (hard or soft); hard bounces auto-suppress.
  • email.complained — recipient marked it as spam; auto-suppresses.
  • email.opened — recipient opened the message (when tracking is enabled).
  • email.clicked — recipient clicked a tracked link.

Subscribing

Register an endpoint with the planned management endpoint:

curl https://api.mailstack.voostack.com/v1/webhooks \
  -H "Authorization: Bearer ms_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/hooks/mailstack",
    "events": ["email.delivered", "email.bounced", "email.complained"]
  }'

Payload

Each delivery is a JSON envelope with the event type, a timestamp, and the message data:

{
  "type": "email.bounced",
  "createdAt": "2026-06-18T10:00:05Z",
  "data": {
    "id": "8f3a1c2e-…",
    "toEmail": "user@example.com",
    "status": "Bounced",
    "errorMessage": "550 5.1.1 mailbox does not exist"
  }
}

Verifying signatures

Every request carries an X-MailStack-Signature header — an HMAC-SHA256 of the raw request body using your webhook signing secret. Recompute it and compare in constant time before trusting a payload. Reject anything that doesn't match.

Retries & idempotency

If your endpoint doesn't return a 2xx within a few seconds, MailStack retries with exponential backoff. Use the event id to de-duplicate, since an event may be delivered more than once.