API reference › Webhooks › Deliveries
List webhook deliveries
/v1/webhooks/:id/deliveriesEvery attempt made against one endpoint, newest first. This is the answer to "why did that webhook never arrive", which is a customer question rather than an ops question — so it lives in the API rather than only in a dashboard.
Deliveries are nested under the endpoint rather than listed account-wide, for
two reasons. A delivery belongs to exactly one endpoint, and "did this
endpoint receive it" is the question being asked. And an account-wide
/v1/webhooks/deliveries would collide with /v1/webhooks/:id in the route
table, where which one wins depends on declaration order rather than on
anything the URL says.
No CLI command yet — webhooks are managed over the API only.
| Field | Type | Description |
|---|---|---|
| status | string | One of pending, delivered, failed. |
| cursor | string | From a previous page's meta.nextCursor. |
| limit | number | Default 50, max 200. |
curl -s "https://api.propgate.dev/v1/webhooks/019fcf9a-3c4d-7e5f-a06b-7c8d9e0f1a2b/deliveries?status=failed" \
-H "authorization: Bearer pg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"{
"data": [
{
"attempts": 6,
"createdAt": "2026-08-03T12:05:00.000Z",
"deliveredAt": null,
"domainId": "019fcf7a-2b3c-7d4e-9f5a-6b7c8d9e0f1a",
"event": "domain.failed",
"id": "019fcfa1-4d5e-7f60-b17c-8d9e0f1a2b3c",
"lastError": "connect ECONNREFUSED",
"object": "webhook_delivery",
"payload": {
"type": "domain.failed",
"created_at": "2026-08-03T12:05:00.000Z",
"data": {
"id": "019fcf7a-2b3c-7d4e-9f5a-6b7c8d9e0f1a",
"domain": "yourdomain.dev",
"external_id": "cust_1",
"previous_state": "verified",
"state": "failed",
"reason": "3 consecutive failures, reaching the failed threshold"
}
},
"status": "failed"
}
],
"error": null,
"meta": {
"nextCursor": null
}
}lastError is what makes a dead-lettered delivery answerable — null while
pending and after an eventual success, and the transport error otherwise.
payload is the same body that was sent, byte for byte, so a delivery that
failed can be replayed by hand without recomputing it. See
Webhooks for the retry schedule and which status codes
trigger one.