# List deliveries

> What BlueBot tried to deliver to this webhook in the last 30 days, newest first, with each answer’s status.

`GET /v1/webhooks/{id}/deliveries`

What BlueBot tried to deliver to this webhook in the last 30 days, newest first, with each answer’s status.

Needs a key with the `webhooks:manage` scope. [Keys and scopes](https://usebluebot.com/docs/concepts/api-keys)

## Path parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The webhook’s id. Starts with `wh_` |

## Query parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `state` | string | No | One of `pending`, `delivered`, `gave_up`, `dropped` |
| `limit` | integer | No | How many to return, 1 to 100. Default 25. 1 to 100. Default `25` |
| `cursor` | string | No | The `next_cursor` of the page before. Leave it out for the first page. Up to 200 characters |

## Example

```bash
curl "https://usebluebot.com/api/v1/webhooks/wh_1Hq2LxW9cVbN3mKpRtYs0a/deliveries" \
  -H "Authorization: Bearer $BLUEBOT_API_KEY"
```

```ts
import BlueBot from '@usebluebot/sdk';

const client = new BlueBot({ apiKey: process.env.BLUEBOT_API_KEY });

const page = await client.webhooks.deliveries.list('wh_1Hq2LxW9cVbN3mKpRtYs0a');
console.log(page.data);
```

```python
import os
from bluebot import BlueBot

client = BlueBot(api_key=os.environ["BLUEBOT_API_KEY"])

page = client.webhooks.deliveries.list("wh_1Hq2LxW9cVbN3mKpRtYs0a")
print(page.data)
```

## Response

`200`: A page of deliveries.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | "list" | Yes |   |
| `data` | array of WebhookDelivery | Yes |   |
| `data[].id` | string | Yes | A dlv_ id. Starts with `dlv_` |
| `data[].object` | "webhook_delivery" | Yes |   |
| `data[].webhook_id` | string | Yes | A wh_ id. Starts with `wh_` |
| `data[].event_id` | string | Yes | A evt_ id. Starts with `evt_` |
| `data[].event_type` | string | Yes | One of `message.queued`, `message.sent`, `message.delivered`, `message.read`, `message.failed`, `message.unconfirmed`, `message.expired`, `message.canceled`, `message.received`, `message.edited`, `message.unsent`, `reaction.added`, `reaction.removed`, `chat.created`, `contact.created`, `contact.stopped`, `contact.unstopped`, `sequence.completed`, `broadcast.completed`, `automation.matched`, `device.online`, `device.offline`, `device.check_failed` |
| `data[].test` | boolean | Yes | True for an example sent with `POST /v1/webhooks/{id}/test`. |
| `data[].state` | string | Yes | `pending` (trying, or waiting to try again), `delivered`, `gave_up` after the last retry, or `dropped`. One of `pending`, `delivered`, `gave_up`, `dropped` |
| `data[].attempts` | integer | Yes |   |
| `data[].last_status` | integer or null | Yes | The HTTP status of the last try. |
| `data[].last_error` | string or null | Yes | Why the last try failed, when there was no answer. |
| `data[].last_duration_ms` | integer or null | Yes |   |
| `data[].last_response_body` | string or null | Yes | The first 2 KB of what your endpoint answered on the last try, as text. Null when it answered with no body or not at all. |
| `data[].next_attempt_at` | timestamp or null | Yes | When it is tried next, while pending. |
| `data[].delivered_at` | timestamp or null | Yes | When a 2xx answered it. |
| `data[].replay_of` | string or null | Yes | The delivery this one repeats, for a replay. Starts with `dlv_` |
| `data[].created_at` | timestamp | Yes | When it was made. |
| `has_more` | boolean | Yes | Whether another page follows. |
| `next_cursor` | string or null | Yes | Send as `cursor` for the next page; null on the last. |

The answer, `200`:

```json
{
  "object": "list",
  "data": [
    {
      "id": "dlv_1Hq2LxW9cVbN3mKpRtYs0a",
      "object": "webhook_delivery",
      "webhook_id": "wh_1Hq2LxW9cVbN3mKpRtYs0a",
      "event_id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
      "event_type": "message.received",
      "test": false,
      "state": "delivered",
      "attempts": 1,
      "last_status": 200,
      "last_error": null,
      "last_duration_ms": 182,
      "last_response_body": "{\"ok\":true}",
      "next_attempt_at": null,
      "delivered_at": "2026-11-13T19:44:13.000Z",
      "replay_of": null,
      "created_at": "2026-11-13T19:44:12.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

## Errors

Every refusal has the same envelope and a page of its own. These are the ones this operation can give.

| Code                                                    | Status | What it means                                                                                                                                    |
| ------------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| [`unauthorized`](https://usebluebot.com/docs/errors/unauthorized)             | 401    | The request carried no key, or a key BlueBot doesn’t know: mistyped, revoked, or a test key sent to the live API.                                |
| [`insufficient_scope`](https://usebluebot.com/docs/errors/insufficient_scope) | 403    | The key doesn’t carry the scope the endpoint needs. Each endpoint’s reference names its scope.                                                   |
| [`rate_limited`](https://usebluebot.com/docs/errors/rate_limited)             | 429    | Too many requests. A key may make 120 requests a minute. The `RateLimit` header says how many are left, and `Retry-After` how long to wait.      |
| [`internal`](https://usebluebot.com/docs/errors/internal)                     | 500    | Something went wrong on BlueBot’s side. It was reported. Send the request again; with an Idempotency-Key that is always safe.                    |
| [`invalid_request`](https://usebluebot.com/docs/errors/invalid_request)       | 400    | Something in the request doesn’t fit: a missing or malformed field, a bad id, or a combination the endpoint refuses. `details` names each field. |
| [`not_found`](https://usebluebot.com/docs/errors/not_found)                   | 404    | There is no such thing on this account. Ids are prefixed by kind, so a message id starts with `msg_`.                                            |

## Try it
