Skip to the documentation
API

Webhook deliveries and activity

Every delivery attempt and every change to an endpoint, filtered the way the console filters them.

GETapi.openemail.uk/webhooks/deliveries

Runs any of the 6 calls on this page against your workspace, with your own key.

Deliveries

GET /webhooks/{id}/deliveries reads one endpoint’s delivery log and GET /webhooks/deliveries reads every endpoint’s at once, optionally narrowed by endpointIds. Both take status (failed is the console’s "only failed" switch), since and until, page with limit and cursor, and keep the cursor valid under every filter as long as each page sends the same ones. Each row carries its endpointId. Nothing is pruned.

GET /webhooks/deliveries?status=failed&since=2026-09-22T00:00:00Z
{  "object": "list",  "data": [    { "object": "webhook_delivery", "id": "whd_8c1e4a7f2b9d3e6a0c5f1b28", "endpointId": "whe_3f9c2a7b1e4d8f60a5c7b92d", "eventType": "email.bounced", "status": "failed", "responseCode": 503, "attempt": 2, "maxAttempts": 8, "nextAttemptAt": "2026-09-23T10:35:00.000Z" }  ],  "hasMore": true,  "nextCursor": "whd_8c1e4a7f2b9d3e6a0c5f1b28"}

Reading and replaying one

GET /webhooks/{id}/deliveries/{deliveryId} returns the body that was sent, what the receiver answered and every try of the event, and POST …/replay sends that event again, one at a time. The body names the addresses the event is about, so a key narrowed to some addresses may open a delivery only on an endpoint whose own allowlists sit inside the key’s, and holding one address never covers its whole domain. Over OAuth only the owner of the workspace may open or replay one, the same rule the console applies.

Activity

GET /webhooks/activity and GET /webhooks/{id}/activity read the audit log: created, updated, enabled, disabled, auto_disabled, secret_rotated, tested, replayed and removed. actor names who did it, a person as @username and a key as API key <name>, and is null when OpenEmail did it on its own. endpointIds, since and until narrow it, and a removed endpoint keeps its history.