Werkmail Docs
Contents

API

Webhooks API

See the narrative Webhooks guide for verification code and the full event list.

Create

POST /api/practices/{id}/webhooks

json
{
  "name": "ops",
  "url": "https://example.com/hooks/werkmail",
  "events": [
    "message.created",
    "message.sent",
    "message.delivered",
    "message.hard_bounced",
    "message.soft_bounced",
    "message.spam_complaint",
    "message.suppressed",
    "message.failed",
    "message.content_blocked",
    "suppression.added",
    "suppression.removed"
  ]
}

Response includes secret once (whsec_…). HTTPS only. The secret is stored encrypted and is never listed again.

List / delete / test / deliveries

Method Path
GET /api/practices/{id}/webhooks
DELETE /api/practices/{id}/webhooks/{webhookID}
POST /api/practices/{id}/webhooks/{webhookID}/test
GET /api/practices/{id}/webhooks/{webhookID}/deliveries
POST /api/practices/{id}/webhooks/{webhookID}/deliveries/{deliveryID}/replay
POST /api/practices/{id}/webhooks/{webhookID}/enable
POST /api/practices/{id}/webhooks/{webhookID}/rotate-secret

GET .../deliveries?limit=50&cursor=… returns the delivery log, latest first: id, event_type, status (succeeded or failed), response_status, attempt (the real retry number), created_at. Secrets and request bodies are not included. When another page exists the response header X-Next-Cursor carries the value for cursor.

POST .../deliveries/{deliveryID}/replay queues the same event again as a new delivery (header X-Werkmail-Replay-Of names the original). It returns 409 while the endpoint is disabled.

POST .../rotate-secret returns a new secret once. Signing switches to it immediately, so update your receiver first or verify with both secrets for a short time.

Automatic disable

An endpoint that keeps failing is disabled automatically: by default after 25 consecutive failed delivery attempts spread over at least 24 hours. The list then shows enabled: false, disabled_at and disabled_reason, and an alert with event webhook.disabled is sent to your Slack or Teams alert endpoints. Fix the receiver and call POST .../enable. Any successful delivery resets the failure count. Destinations must resolve to public addresses at connection time; private and internal addresses are always refused.

Signature

X-Werkmail-Signature = hex HMAC-SHA256 of {timestamp}.{raw-body} with the webhook secret. Timestamp is X-Werkmail-Timestamp (unix seconds). Event name is X-Werkmail-Event.

Envelope:

json
{ "id": "…", "event": "message.delivered", "timestamp": "…", "data": { } }

Suppression payloads include scope, project_id, route_id, and slugs when available.

Alerts

POST /api/practices/{id}/alerts — { "name", "kind": "slack"|"teams", "url" }.
POST …/alerts/{id}/test, DELETE …/alerts/{id}, GET …/alerts.

View this page as Markdown · llms.txt · full corpus