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

List the deliveries of a webhook

Every event handed to the webhook, newest first, one page at a time, with the outcome of the last attempt.

Takes a server key (`sk_…`, or `sk_test_…` on a test server) as a bearer token. TypeScript: `sendora.webhooks.deliveries(webhookId, query)`. Python: `sendora.webhooks.deliveries(webhook_id, status=..., limit=..., after=...)`.

## Parameters

- `limit` (query, integer (1 to 1000)): Page size, 1 to 1000.
- `after` (query, string (uuid)): The `next` value of the previous page.
- `status` (query, "pending" | "delivered" | "dead")
- `id` (path, required, string (uuid)): The webhook id.

## Responses

### 200 A page of the webhook's deliveries, newest first.

- `deliveries` (array of object, required)
  - `deliveryId` (string (uuid), required)
  - `event` ("delivered" | "bounced" | "deferred" | "spam_complaint" | "unsubscribed" | "cap_warning" | "cap_reached" | "inbound", required)
  - `messageId` (string (uuid) or null, required): Null for an event about usage rather than a message.
  - `inboundMessageId` (string (uuid) or null, required): The received message an inbound event is about; null for every other event.
  - `status` ("pending" | "delivered" | "dead", required): pending is waiting for its next attempt; dead gave up and can be replayed.
  - `attempts` (integer, required)
  - `nextAttemptAt` (string (date-time) or null, required): When the next attempt is due, while pending.
  - `lastStatusCode` (integer or null, required): The HTTP status the endpoint last answered.
  - `lastError` (string or null, required): Why the last attempt failed, when it did.
  - `deliveredAt` (string (date-time) or null, required)
  - `createdAt` (string (date-time), required)
- `next` (string (uuid) or null, required): Pass as `after` for the next page; null on the last.

Example:

```json
{
  "deliveries": [
    {
      "deliveryId": "9e8d7c6b-5a4f-4e3d-9c2b-1a0f9e8d7c60",
      "event": "delivered",
      "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
      "inboundMessageId": null,
      "status": "delivered",
      "attempts": 1,
      "nextAttemptAt": null,
      "lastStatusCode": 200,
      "lastError": null,
      "deliveredAt": "2026-09-15T12:00:03.000Z",
      "createdAt": "2026-09-15T12:00:02.000Z"
    }
  ],
  "next": null
}
```

## Errors

Every error answers `error`, the code, and `message`, a sentence for a person. A code that adds fields is shown in full below the table.

| Code | Status | Meaning |
| --- | --- | --- |
| `invalid_request` | 400 | The body, the query or a header does not match what the route takes. |
| `unauthorized` | 401 | The key is missing, malformed or revoked. |
| `wrong_token_kind` | 403 | The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes. |
| `not_found` | 404 | No such webhook of this server. |

### `invalid_request`

- `issues` (array of object): One entry per invalid field; absent when a header is wrong.
  - `path` (string, required): The field, dotted, such as to.0.email; empty when the whole body is wrong.
  - `message` (string, required)

Example:

```json
{
  "error": "invalid_request",
  "message": "The request is invalid: to.0: Invalid email address",
  "issues": [
    {
      "path": "to.0",
      "message": "Invalid email address"
    }
  ]
}
```
