List recent webhook delivery attempts for the authenticated account
Two independent response shapes, selected by ?order=:
- Default (order key absent entirely): offset mode. created_at descending, ?limit=/?offset=, WebhookDeliveryListResponse. Unchanged since before issue #396 apart from the added enqueued_at field on each delivery. A present order key — even an empty ?order= or a bare ?order — never falls back to this mode; see below.
- order=id: cursor mode (issue #396). id ascending, keyset-paginated via ?cursor=, WebhookDeliveryCursorListResponse. Any ?offset= (any value, including 0) is rejected with 400. A malformed or empty ?cursor= is rejected with 400 — presence of the parameter is checked independently of its value, so a present-but-empty ?order=id&cursor= is rejected the same as a malformed one, not treated as "no cursor". ?cursor= without order=id is also rejected with 400, empty value included — a cursor only has meaning in keyset order. order itself must be present exactly once with the value id; a present but empty ?order=, a bare ?order, a repeated order= key, or any other value is rejected with 400 rather than silently running offset mode. A malformed query string itself (e.g. an unescaped ;) is rejected with 400 before any parameter is inspected.
?recipient_id= filters to one recipient's own deliveries (webhook_deliveries.webhook_id), still scoped to the caller's account. ?status= is repeatable (OR-union) — a single status=x behaves exactly as before issue #396.
Recipient-queue drain recipe. To prove a recipient's pre-attachment backlog is drained before deleting it (e.g. rotating to a replacement recipient via DELETE /api/v1/recipients/{id}?replaced_by=): scan ?recipient_id={id}&status=pending&status=retrying&order=id, following next_cursor until it is null. Only an empty scan result proves the queue is literally empty; any row the scan returns proves the opposite, since the status filter selects live rows by construction. The backlog is considered drained once every returned row's enqueued_at is non-null and greater than the replacement's attached_at on every monitor (GET /api/v1/monitors/{id}/recipients's attached_at field) — but that timestamp comparison alone does not prove sibling coverage (that each row has a counterpart delivery enqueued for the replacement); it only establishes that a live row postdates the replacement's attachment. DELETE /api/v1/recipients/{recipientID} is the authoritative check for a safe rotation — it verifies sibling coverage server-side, in one transaction, rather than trusting a client-computed timestamp comparison. See that endpoint for the full recipe and its guarantees/limits.
Request
- Base URL: https://api.uptimemonitoring.com
- URL: https://api.uptimemonitoring.com/api/v1/webhook-deliveries
- Auth: HTTP bearer
Query parameters
Filter to one recipient's deliveries (issue
Repeatable (issue #396): status=pending&status=retrying returns the OR-union. A single status=x behaves exactly as on master.
Offset-mode only. Rejected with 400 (any value, including 0) when combined with order=id.
Omit for the default offset-mode shape. id switches to cursor mode (issue #396). When present, the parameter must appear exactly once with the value id — an empty ?order=, a bare ?order, a repeated order= key, or any other value is rejected with 400 rather than silently falling back to offset mode.
Cursor-mode only (issue #396) — the opaque next_cursor value from a previous page. Requires order=id.
Response
Deliveries
Example response
{
"deliveries": [
{
"event_type": "down"
}
]
}Changes
No recorded changes to this operation across all 1 revision of this API.