---
title: List webhook deliveries — GET /api/v1/webhook_deliveries
description: Delivery attempts across all of the calling api_client's subscriptions, newest first. The event payload and the subscriber's response body are…
canonical_url: "https://cascades.crscreditapi.com/docs/api/webhooks/list-webhook-deliveries"
doc_version: "1.0.0"
last_updated: "2026-10-09T18:04:24Z"
source: "public/api-docs/v1/swagger.yaml#listWebhookDeliveries"
---

# List webhook deliveries — GET /api/v1/webhook_deliveries

`GET https://cascades.crscreditapi.com/api/v1/webhook_deliveries`

- Operation id: `listWebhookDeliveries`
- Scopes: `webhooks:read`
- Idempotent: no
- OpenAPI: https://cascades.crscreditapi.com/openapi.json · https://cascades.crscreditapi.com/openapi.yaml (operationId `listWebhookDeliveries`)

Delivery attempts across all of the calling api_client's
subscriptions, newest first. The event payload and the subscriber's
response body are deliberately omitted. CSV filters accept several
comma-separated values; unknown values return `422`. Requires
`webhooks:read`.

## Query parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `page` | integer | no | 1-based page number. |
| `per_page` | integer | no | Items per page. Values above 100 are clamped to 100. |
| `filter[webhook_subscription_id]` | integer | no |  |
| `filter[event_type]` | string | no | CSV of event names |
| `filter[status]` | string | no | CSV of pending, retrying, succeeded, failed, dead |

## Responses

### 200 — Delivery list

`application/json`

| Field | Type | Required | Description |
|---|---|---|---|
| `data` | array of WebhookDelivery | no |  |
| &nbsp;&nbsp;`id` | integer | no |  |
| &nbsp;&nbsp;`object` | string | no |  |
| &nbsp;&nbsp;`webhook_subscription_id` | integer | no |  |
| &nbsp;&nbsp;`event_type` | string | no | Lifecycle events Cascades can deliver. See `x-webhooks` for each payload. One of: `"execution.completed"`, `"execution.failed"`, `"adverse_action.triggered"`, `"adverse_action.completed"`, `"adverse_action.failed"`, `"adverse_action.retry_scheduled"`. |
| &nbsp;&nbsp;`status` | string | no |  One of: `"pending"`, `"retrying"`, `"succeeded"`, `"failed"`, `"dead"`. |
| &nbsp;&nbsp;`attempts` | integer | no |  |
| &nbsp;&nbsp;`max_attempts` | integer | no |  |
| &nbsp;&nbsp;`last_response_status` | integer, nullable | no |  |
| &nbsp;&nbsp;`last_attempted_at` | string (date-time), nullable | no |  |
| &nbsp;&nbsp;`next_retry_at` | string (date-time), nullable | no |  |
| &nbsp;&nbsp;`delivered_at` | string (date-time), nullable | no |  |
| &nbsp;&nbsp;`created_at` | string (date-time) | no |  |
| &nbsp;&nbsp;`updated_at` | string (date-time) | no |  |
| `meta` | Meta | no |  |
| &nbsp;&nbsp;`request_id` | string | yes | Correlation id for this request. Also sent as the `X-Request-Id` response header; quote it when contacting support. |
| &nbsp;&nbsp;`page` | integer | yes |  |
| &nbsp;&nbsp;`per_page` | integer | yes |  |
| &nbsp;&nbsp;`total_count` | integer | yes |  |
| &nbsp;&nbsp;`total_pages` | integer | yes |  |
| &nbsp;&nbsp;`object` | string | yes | The object type of every item in `data`. |

```json
{
  "data": [
    {
      "id": 1,
      "object": "webhook_delivery",
      "webhook_subscription_id": 1,
      "event_type": "execution.completed",
      "status": "pending",
      "attempts": 1,
      "max_attempts": 6,
      "last_response_status": 1,
      "last_attempted_at": "2026-05-08T18:41:05Z",
      "next_retry_at": "2026-05-08T18:41:05Z",
      "delivered_at": "2026-05-08T18:41:05Z",
      "created_at": "2026-05-08T18:41:05Z",
      "updated_at": "2026-05-08T18:41:05Z"
    }
  ],
  "meta": {
    "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
    "page": 1,
    "per_page": 25,
    "total_count": 142,
    "total_pages": 6,
    "object": "execution"
  }
}
```

### 401 — Missing, malformed, expired or revoked bearer token. The `WWW-Authenticate` header carries the RFC 6750 challenge.

`application/json` — `ErrorEnvelope`

```json
{
  "error": {
    "code": "unauthorized",
    "message": "A valid bearer token is required.",
    "details": [],
    "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
    "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/unauthorized"
  }
}
```

### 403 — Token does not hold the required scope. `details` lists the scope(s) that were checked.

`application/json` — `ErrorEnvelope`

```json
{
  "error": {
    "code": "insufficient_scope",
    "message": "This token does not have the required scope.",
    "details": [
      {
        "field": "scope",
        "message": "executions:write"
      }
    ],
    "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
    "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/insufficient_scope"
  }
}
```

### 422 — Request body or params failed validation

`application/json` — `ErrorEnvelope`

```json
{
  "error": {
    "code": "validation_failed",
    "message": "The request could not be processed.",
    "details": [
      {
        "field": "execution_mode",
        "message": "must be test or live"
      }
    ],
    "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
    "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/validation_failed"
  }
}
```

### 429 — Rate limit exceeded (60 req/min per IP on `/api/v1`, 600 req/hour
per token prefix, or 300 req/5 min per IP globally). The body is the
standard error envelope and `Retry-After` gives the seconds until
the window resets.


`application/json` — `ErrorEnvelope`

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Retry later.",
    "details": [],
    "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
    "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/rate_limited"
  }
}
```

## Code samples

### cURL

```shell
curl "https://cascades.crscreditapi.com/api/v1/webhook_deliveries" \
  -H "Authorization: Bearer {{API_KEY}}"
```

### Node.js

```javascript
const response = await fetch("https://cascades.crscreditapi.com/api/v1/webhook_deliveries", {
  method: "GET",
  headers: {
    "Authorization": "Bearer {{API_KEY}}"
  }
});

const { data, meta } = await response.json();
console.log(response.status, data, meta.request_id);
```

### Python

```python
import requests

response = requests.get(
    "https://cascades.crscreditapi.com/api/v1/webhook_deliveries",
    headers={
        "Authorization": "Bearer {{API_KEY}}",
    },
)
response.raise_for_status()
payload = response.json()
print(payload["data"], payload["meta"]["request_id"])
```

### Ruby

```ruby
require "net/http"
require "json"

uri = URI("https://cascades.crscreditapi.com/api/v1/webhook_deliveries")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer {{API_KEY}}"

response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end
payload = JSON.parse(response.body)
puts payload["data"], payload.dig("meta", "request_id")
```

### Go

```go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, err := http.NewRequest("GET", "https://cascades.crscreditapi.com/api/v1/webhook_deliveries", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer {{API_KEY}}")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	out, _ := io.ReadAll(resp.Body)
	fmt.Println(resp.StatusCode, string(out))
}
```

### Agent

```shell
claude mcp add cascades \
  -e CASCADES_API_KEY={{API_KEY}} \
  -e CASCADES_PROD_BASE_URL=https://cascades.crscreditapi.com \
  -- npx -y @crscreditapi/cascades-mcp-server

# Then ask your assistant:
#   "List webhook deliveries using the Cascades API."
# No MCP tool covers this endpoint yet; the assistant can call GET /webhook_deliveries with curl.
```

## Related

- [Webhooks](https://cascades.crscreditapi.com/docs/concepts/webhooks)
- [Pagination and filtering](https://cascades.crscreditapi.com/docs/concepts/pagination-and-filtering)

## Sitemap

See the full [sitemap](https://cascades.crscreditapi.com/sitemap.md) for all pages.
