List recent deliveries
Returns the last 90 days of delivery attempts for this endpoint, newest first. One row per attempt including retries - high volume; use limit=100 to drain faster.
Filters: status (pending / delivered / retrying / failed), event_type (catalog name), and created_after/created_before (unix seconds, inclusive - matches this row’s created_at). Compose with cursors.
Common pattern - audit all failures: ?status=failed&limit=100, follow starting_after until has_more=false. Each failed row carries the last response_code your receiver returned. Replay a failed delivery with POST /v1/webhook_endpoints/{id}/deliveries/{delivery_id}/retry, which enqueues a fresh attempt (a new delivery row).
Scope: webhooks:read.
There is intentionally no GET /v1/webhook_endpoints/{id}/deliveries/{delivery_id} - a single delivery is only reachable by paging this list (or via POST …/retry, which returns the new attempt). Do not build an integration that expects a single-delivery fetch. Only real event deliveries appear here. Test sends from POST /v1/webhook_endpoints/{id}/test are synchronous and create no delivery row, so an empty list right after a successful test send is expected, not a fault.
Authorizations
Your secret API key as a Bearer token: Authorization: Bearer vxn_sk_.... Keys are created and scoped in the dashboard - see Authentication.
Path Parameters
Endpoint identifier (whk_ prefix).
^whk_[A-Za-z0-9]+$Query Parameters
Filter: pending, delivered, retrying, failed.
pending, retrying, delivered, failed Filter by catalog event name.
The locked v1 event catalog - 22 events across 9 subjects. Names follow resource.action with past-participle actions (transaction.created), never the dotted verb-stems used by transaction types - the two vocabularies never mix. product.created/product.updated fire for dashboard and API-created catalog changes; POS-synced catalog changes do not emit (they mirror the till, and a first sync would flood your endpoint).
customer.created, customer.updated, customer.deleted, customer.pass_installed, customer.pass_uninstalled, card.created, card.updated, card.deleted, custom_field.created, custom_field.updated, custom_field.deleted, product.created, product.updated, transaction.created, transaction.reversed, notification.sent, notification.delivery_updated, location.updated, team_member.added, team_member.updated, team_member.removed, webhook_endpoint.delivery_failed "transaction.created"
Only delivery attempts created at or after this time (inclusive).
Only delivery attempts created at or before this time (inclusive).
Page size, 1-100. Default 25.
1 <= x <= 100Walk forward. Send the last id from the previous page's data[]. Numeric offset or page parameters are not supported; cursors are the only supported paging mechanism.
Reverse cursor - returns deliveries before this whd_ id.
^whd_[A-Za-z0-9]+$Response
The delivery record object.
Standard cursor-pagination envelope for list endpoints. See the Pagination guide.
Always "list".
"list"Array of the requested resource type.
True when more pages exist - pass the last item id as starting_after.
Cursor for the next page in the direction you are already paging, or null when this page ends the collection. has_more: true always comes with a non-null next_cursor.
Feed it back to the SAME parameter you used: starting_after when paging forward (the default), or ending_before when paging backward. Treat it as opaque and do not parse it.
You no longer need to take the last object's id yourself. That still works and is unchanged, but deriving the cursor from the page put the burden of knowing the sort direction on you, and it broke silently on any endpoint whose cursor is not the object id.
"cus_iofv5j4hn6bphinmmyat27tc5y"
Stable collection URL.