> For a complete page index of the Captain API documentation, fetch https://docs.captain.dev/llms.txt?excludeSpec=true

# List Deliveries

GET https://api.captain.dev/v2/webhooks/endpoints/{endpoint_id}/deliveries

List the messages sent, or being sent, to an endpoint, newest first. Each row has the message id (the `webhook-id` header), the event id (`evt_` followed by the job id, `null` for tests), the event type, the delivery status and when the next retry is due.

Page with `cursor` until `next_cursor` is `null`.

Reference: https://docs.captain.dev/reference/webhooks/deliveries/list

## Request

### Path parameters

- `endpoint_id` (string, required) — The endpoint's id (`whe_...`).

### Query parameters

- `limit` (integer, optional, default: 25) — Rows per page (1-100). Defaults to 25.
- `cursor` (string, optional, nullable) — `next_cursor` from the previous page.

## Response

### 200

Successful Response

- `deliveries` (list of WebhookDelivery, required)
- `next_cursor` (string, required, nullable) — Pass as `cursor` for the next page. `null` on the last page.

## Errors

### 401 Unauthorized Error

Missing or invalid API key.

- `error` (string, required) — Error kind. `HTTP_ERROR` for errors raised by the route.
- `message` (string, required) — What went wrong.
- `path` (string, required) — The request path.
- `status_code` (integer, optional) — The HTTP status code.

### 404 Not Found Error

`Webhook endpoint not found.` The id does not exist, or belongs to another organization.

- `error` (string, required) — Error kind. `HTTP_ERROR` for errors raised by the route.
- `message` (string, required) — What went wrong.
- `path` (string, required) — The request path.
- `status_code` (integer, optional) — The HTTP status code.

### 429 Too Many Requests Error

`Too many webhook management requests. Try again shortly.` Retry after the `Retry-After` header.

- `error` (string, required) — Error kind. `HTTP_ERROR` for errors raised by the route.
- `message` (string, required) — What went wrong.
- `path` (string, required) — The request path.
- `status_code` (integer, optional) — The HTTP status code.

### 503 Service Unavailable Error

Webhooks are temporarily unavailable. Retry shortly.

- `error` (string, required) — Error kind. `HTTP_ERROR` for errors raised by the route.
- `message` (string, required) — What went wrong.
- `path` (string, required) — The request path.
- `status_code` (integer, optional) — The HTTP status code.

## Types

### WebhookDelivery

- `message_id` (string, required) — The message id, also sent as the `webhook-id` header.
- `event_id` (string, required, nullable) — The event's `id` (`evt_` followed by the job id). `null` for test events.
- `event_type` (enum, required)
  - Allowed values: `job.completed`, `job.completed_with_errors`, `job.failed`, `job.timed_out`, `job.cancelled`
- `status` (enum, required) — `pending` and `sending` mean attempts are still scheduled or in flight; `failed` means every attempt failed.
  - Allowed values: `succeeded`, `failed`, `pending`, `sending`
- `test` (boolean, required) — `true` for a test event.
- `created_at` (string, required, nullable) — When the message was created.
- `next_attempt_at` (string, required, nullable) — When the next retry is due, or `null` when none is scheduled.

## Examples

**Response**

```json
{
  "deliveries": [
    {
      "message_id": "msg_2mXq8vTn4bK9cR1sZp7Lw3YhJd",
      "event_id": "evt_4f7c2a91-8d3e-4b6a-9f12-7e5d8c0b3a64",
      "event_type": "job.completed_with_errors",
      "status": "succeeded",
      "test": false,
      "created_at": "2026-09-23T10:05:12Z",
      "next_attempt_at": null
    },
    {
      "message_id": "msg_2mXnC4uR8kT1vY6bQ3wE9sZ0Hd",
      "event_id": "evt_9a1e5c3b-2f7d-4e8a-b6c0-1d4f7a2e9b35",
      "event_type": "job.failed",
      "status": "pending",
      "test": false,
      "created_at": "2026-09-23T09:41:57Z",
      "next_attempt_at": "2026-09-23T10:16:57Z"
    }
  ],
  "next_cursor": "eyJpIjoibXNnXzJtWG5DNHVSOGtUMXZZNmJRM3dFOXNaMEhkIn0"
}
```

**SDK Code**

```python Python
import requests

BASE_URL = "https://api.captain.dev"
API_KEY = "your_api_key"
ENDPOINT_ID = "whe_3f9a1c7e5b2d4a6c8e0f1a2b"

response = requests.get(
    f"{BASE_URL}/v2/webhooks/endpoints/{ENDPOINT_ID}/deliveries",
    headers={"Authorization": f"Bearer {API_KEY}"},
    params={
        "limit": 25
    },
    timeout=30.0,
)
response.raise_for_status()
data = response.json()
for delivery in data["deliveries"]:
    retry = f", next retry {delivery['next_attempt_at']}" if delivery["next_attempt_at"] else ""
    print(f"{delivery['message_id']} {delivery['event_type']}: {delivery['status']}{retry}")

```

```typescript TypeScript
const BASE_URL = "https://api.captain.dev";
const API_KEY = "your_api_key";
const ENDPOINT_ID = "whe_3f9a1c7e5b2d4a6c8e0f1a2b";

const response = await fetch(`${BASE_URL}/v2/webhooks/endpoints/${ENDPOINT_ID}/deliveries?limit=25`, {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${API_KEY}`,
  },
});
if (!response.ok) throw new Error(`Request failed: ${response.status} ${await response.text()}`);
const data = await response.json();
interface Delivery {
  message_id: string;
  event_type: string;
  status: string;
  next_attempt_at: string | null;
}

for (const delivery of data.deliveries as Delivery[]) {
  const retry = delivery.next_attempt_at ? `, next retry ${delivery.next_attempt_at}` : "";
  console.log(`${delivery.message_id} ${delivery.event_type}: ${delivery.status}${retry}`);
}

```