List Webhook Subscriptions
GET/api/webhook-subscriptions
Paginated list of every webhook subscription on the tenant, newest first. The signing secret is never included here — it is shown only once in the create response.
webhooks:read|webhooks:manageGrant this scope to your token under Settings → Developer → Personal Access Tokens.
Searching, filtering and sorting all run server-side, so they cover the whole table rather than the page you happen to be looking at. filter[search] matches the event name and the target URL; narrow it with the top-level search_columns parameter (comma-separated subset of event, target_url).
Operator-aware filters use a filter[column.operator] key:
- Text columns
eventandtarget_urlacceptcontains,does_not_contain,is,is_not,is_one_of,is_not_one_of,starts_with,does_not_start_with,ends_with,does_not_end_with,is_empty,is_not_empty. - The numeric column
failure_countacceptsis,is_not,is_one_of,is_not_one_of,greater_than,less_than,greater_than_or_equal,less_than_or_equal,between,is_empty,is_not_empty. - Date columns
created_atandlast_delivery_atacceptis,is_not,before,after,on_or_before,on_or_after,between,is_empty,is_not_empty, plus the relative operatorstoday,yesterday,past_week,past_month,past_year,days_ago,past_days.
Note that the bare filter[event] key stays an exact match against the catalog event names — use filter[event.contains] or filter[event.starts_with] for a partial one.
For AND/OR trees, send filter_groups as base64-encoded JSON:
{
"conjunction": "or",
"children": [
{ "type": "condition", "condition": { "column": "event", "operator": "is", "value": "sales_order.created" } },
{ "type": "group", "group": { "conjunction": "and", "children": [] } }
]
}
A filter_groups value that cannot be decoded is ignored and the unfiltered list is returned rather than an error, so a truncated URL never blanks the page. An unregistered filter or sort key does return 400 — columns that are not listed above (including secret) are not filterable or sortable.
Requires webhooks:read or webhooks:manage.
Rejected filter values
A filter carrying a value outside its accepted set returns 422 naming the values that are accepted. It previously returned 200 with the filter quietly dropped, so a mistyped value came back as a full, unfiltered list that was indistinguishable from a real result. Sending a filter key with an empty value still means "no filter" and is not an error. An unknown filter name is still a 400.
Exact vs partial search
search_columns chooses which of event / target_url the search looks at; search_strict_columns makes the listed columns match the whole value rather than a fragment. Both take a comma-separated list, are matched case-insensitively, and ignore names that aren't searchable — a stale column name falls back to searching every column rather than none. Values are limited to 255 characters of A-Z a-z 0-9 _ . , - and spaces; anything else returns 422.
Request
Responses
- 200
- 401
- 403
- 422
- 429
OK
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden — the token lacks a required scope, the endpoint is not available to API tokens, or the user behind the token lacks the permission. A human must adjust the token scopes or user permissions; do not retry.
Unprocessable Content
Response Headers
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.