---
title: "List callback delivery attempts"
canonical: "https://bird.com/docs/api/reference/list-webhook-callback-attempts"
---

# List callback delivery attempts

`GET /v1/webhook-callbacks/attempts`

Returns the workspace's recent delivery attempts to SMS callback URLs, newest first. Each
entry is one HTTP request, so a retried event appears once per try. The `url` is the
callback URL the request was sent to. Use this list to see what failed and why before
requesting redelivery with the callback replay operation.

Cap the page with `limit`, and pass `next_cursor` from the response as `starting_after` to
get the next, older page. Narrow the time window with the `before`/`after` timestamps;
they combine with a cursor. Send only one of `starting_after` and `ending_before`; passing
both returns 422.

Attempts to webhook endpoints are not included; list them with
[List delivery attempts](/docs/api/reference/list-webhook-attempts).

## Servers

- `https://{region}.platform.bird.com`: Regional API endpoint. Use the host for the region your organization is hosted in. Official Bird SDKs and the CLI select it automatically from your API key, so you rarely need to set it by hand.
  - `region`: `us1`, `eu1`. Default: `us1`. The region your organization's data is hosted in.
- `https://platform.bird.com`: Region-independent endpoint for authentication and account administration.
- `http://localhost:8080`: Local development.

## Authentication

Use one authentication option:

- `BearerAuth`: HTTP bearer authentication. Pass the API key as a bearer token in the `Authorization` header. Workspace
keys use `bk_{region}_*`; organization master keys use `bm_{region}_*`.
The prefix identifies the region and selects the
API endpoint. Official Bird SDKs and the CLI derive the region from the key.

- `CookieAuth`: Send `bird_session` in cookie. Session cookie set after signing in to the Bird dashboard. The cookie
value is an opaque session token; no session data is stored in the cookie
itself.

## Code samples

**CLI**

```sh
bird webhooks callbacks attempts
```

Examples: [CLI](/docs/api/reference/list-webhook-callback-attempts.cli.md) · [MCP](/docs/api/reference/list-webhook-callback-attempts.mcp.md) · [cURL](/docs/api/reference/list-webhook-callback-attempts.curl.md)

## Example response `200`

```json
{
  "data": [
    {
      "id": "msgatt_3FdaB1NkOmM6m8AxhgEYTJgqHU3",
      "event_id": "whe_01krdgeqcxet5s7t44vh8rt9mg",
      "event_type": "amb.accepted",
      "status": "delivered",
      "url": "https://example.com/webhooks",
      "failure_reason": "The endpoint's connection changed after this delivery was queued.",
      "response_status_code": 200,
      "response_body": "{\"ok\":true}",
      "response_duration_ms": 87,
      "attempted_at": "2026-05-22T11:50:38.080Z"
    }
  ],
  "next_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE0OjAzOjEwWlwiIiwiaSI6IjAxOTJmM2IxLTRjN2UtN2EyYi05ZDYxLThmM2E1YzJlN2I0MCJ9",
  "prev_cursor": null,
  "refresh_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE2OjQyOjAxWlwiIiwiaSI6IjAxOTJmM2IxLTllMDQtN2NkMy1iODE3LTJhNmY0ZDFjOGUwOSJ9"
}
```

## Query parameters

- `limit` (integer, optional): Maximum number of attempts to return. Defaults to 50, capped at 100.
- `before` (string, optional): Only return attempts strictly before this timestamp.
- `after` (string, optional): Only return attempts strictly after this timestamp.
- `starting_after` (string, optional): Cursor from the `next_cursor` field of a previous list response. Returns items immediately after the cursor position in the current sort order.
- `ending_before` (string, optional): Cursor from the `prev_cursor` or `refresh_cursor` field of a previous list response. Returns items immediately before the cursor position in the current sort order. `prev_cursor` returns the preceding page. `refresh_cursor` anchors at the first row of that response, which on a newest-first sort is how to fetch the items that have appeared since.

## Header parameters

- `X-Workspace-Id` (string, optional): Workspace context for the request. Required for dashboard authentication and master keys. Workspace keys and access tokens already identify their workspace; send that workspace or omit the header. A different one is rejected.
- `X-Organization-Id` (string, optional): Organization context for the request. Required for dashboard authentication. An API key or access token carries its own organization, so send either that organization or no header at all; a different one is rejected.

## Response body

- `data` (array of object, required): Delivery attempts, newest first.
- `data.id` (string, required): Identifier of this individual delivery attempt. Each retry is a separate attempt with its own id; use `event_id` to group the attempts for one event.
- `data.event_id` (nullable string): Bird's source event ID, stable across retries of the same event. Null only for older attempts recorded before event IDs were available.
- `data.event_type` (string, required)

  Webhook event type. This is an open enum, so accept unrecognized values in deliveries. Subscribing to a type outside the event catalog returns a `422`.

  Possible values (may grow over time): `amb.accepted`, `amb.conversation_closed`, `amb.conversation_reopened`, `amb.conversation_started`, `amb.received`, `amb.rejected`, `amb.send_failed`, `amb.sent`, `amb_suppression.created`, `domain.failed`, `domain.verified`, `email.accepted`, `email.bounced`, `email.canceled`, `email.clicked`, `email.complained`, `email.deferred`, `email.delivered`, `email.list_unsubscribed`, `email.opened`, `email.out_of_band_bounce`, `email.processed`, `email.received`, `email.rejected`, `email.scheduled`, `email.unsubscribed`, `email_mailbox.message_delivered`, `email_mailbox.message_failed`, `email_mailbox.message_received`, `email_mailbox.message_sent`, `email_mailbox.suspended`, `email_mailbox.thread_created`, `email_suppression.created`, `preference.deleted`, `preference.granted`, `preference.revoked`, `sms.accepted`, `sms.delivered`, `sms.expired`, `sms.failed`, `sms.received`, `sms.rejected`, `sms.sent`, `sms.undelivered`, `sms_suppression.created`, `verify.attempt.delivered`, `verify.attempt.sent`, `verify.attempt.undelivered`, `verify.verification.created`, `verify.verification.failed`, `verify.verification.verified`, `voice_call.answered`, `voice_call.ended`, `voice_call.initiated`, `whatsapp.accepted`, `whatsapp.delivered`, `whatsapp.failed`, `whatsapp.group.join_request_created`, `whatsapp.group.join_request_revoked`, `whatsapp.reacted`, `whatsapp.read`, `whatsapp.received`, `whatsapp.rejected`, `whatsapp.sent`, `whatsapp_suppression.created`
- `data.status` (string, required)

  Outcome of this attempt.

  - `delivered`: your endpoint accepted it with a `2xx` response.
  - `pending`: the attempt is still in flight.
  - `failed`: it returned a non-`2xx` response or no response at all. Automatic
    retries appear as further attempts with the same `event_id`, so a `failed`
    attempt is final for the event only once the retry schedule is spent. A
    replayed delivery takes a single attempt and is never retried.

  Possible values: `delivered`, `pending`, `failed`
- `data.url` (string, required): URL the request was sent to. For a webhook endpoint, its `url` at the time of the attempt, which can differ from the current configuration after an update. For an SMS callback, the callback URL resolved for the message's event.
- `data.failure_reason` (string): Why the attempt failed when no HTTP response explains it: a failure before any request was sent, such as a connector body that could not be rendered, or a TLS failure, such as an endpoint certificate that could not be verified. Absent for other attempts.
- `data.response_status_code` (nullable integer, required): HTTP status returned by the receiver. Null when no response was received (timeout, connection error, DNS failure).
- `data.response_body` (string): Response body your endpoint returned, which may be truncated. Omitted when no body was returned.
- `data.response_duration_ms` (integer, required): Round-trip duration in milliseconds.
- `data.attempted_at` (string, required): When this attempt was made. Attempts are listed newest first by this timestamp, and the list's `before`/`after` parameters bound it.
- `next_cursor` (nullable string, required): Cursor for the next page. Pass back as `starting_after` to advance forward. `null` when no next page exists.
- `prev_cursor` (nullable string, required): Cursor for the previous page. Pass back as `ending_before` to step backward. `null` when no previous page exists.
- `refresh_cursor` (nullable string, required): Refresh anchor, the first row of this response. Pass back as `ending_before` to fetch what precedes it in the current sort order. On a newest-first sort those are the items that have appeared since; on any other sort they are the items that sort earlier, so refreshing such a list means re-fetching it instead. Non-`null` whenever `data` is non-empty; `null` only on an empty page. Distinct from `prev_cursor`.

## Related resources

- [Should I use a Bird SDK or call the API directly?](/explained/platform/should-i-use-an-sdk-or-call-the-api-directly) (answer)
- [Build your first integration](/learn/paths/integration) (course)
- [Send your first email](/docs/get-started/send-your-first-email) (docs)

[Get an implementation brief](/learn/workspace?topic=api-basics)
