When it fires
Emitted by the delivery worker when a single delivery hits the max retry count (5) without a 2xx response. The endpoint's consecutiveFailures counter has been incremented on each failure.
To prevent infinite recursion, a failed webhook.delivery_failed delivery does not itself emit a new webhook.delivery_failed. Loops are avoided.
Payload
ts
{
type: 'webhook.delivery_failed',
data: {
delivery: {
id: string // the failed WebhookDelivery uuid
eventId: string // the underlying WorkspaceEvent uuid
eventType: string // the event type that failed to deliver
endpointId: string
endpointName: string
attempts: number // always equals max attempts (5)
responseStatus: number | null // last HTTP status, null if request errored before response
error: string | null // last error message
}
}
}The actor is always null, a system event from the worker. The failing endpoint is identified by endpointId and endpointName only: its URL is withheld because the same event is delivered to every other endpoint in the workspace.
Example
json
{
"type": "webhook.delivery_failed",
"actor": null,
"data": {
"delivery": {
"id": "0192a1b2-c3d4-7000-8000-0000000000e0",
"eventId": "0192a1b2-c3d4-7000-8000-0000000000e1",
"eventType": "project.created",
"endpointId": "0192a1b2-c3d4-7000-8000-0000000000d0",
"endpointName": "Customer receiver",
"attempts": 5,
"responseStatus": 503,
"error": "Receiver returned 503"
}
}
}Suggested handling
- Page on-call for important consumers
- Auto-disable the endpoint if
consecutiveFailuresis unreasonably high (we don't auto-disable; you decide based on your SLAs) - Notify the workspace owner via email/Slack so they can fix the receiver