Sign inGet Started

List delivery attempts

GET
/v1/webhooks/{webhook_id}/attempts
const attempts = await bird.webhooks.attempts(
  "whk_01krdgeqcxet5s7t44vh8rt9mg",
);
for (const attempt of attempts.data) {
  console.log(attempt.status, attempt.response_status_code);
}
Response200
{
  "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"
    }
  ]
}

Returns the endpoint's recent delivery attempts, newest first. Each entry is one HTTP request, so a retried event appears once per try; use it to see what failed and why before requesting redelivery with Replay failed deliveries.

Bound the window with the before/after timestamps and cap the page with limit. To page further back without a cursor, pass the oldest attempted_at you received as before.

Parameters

webhook_idstring

ID of the webhook endpoint (whk_ prefix), as returned when it was created.

Query Parameters

limitinteger

Maximum number of attempts to return. Defaults to 50, capped at 100.

beforestring

Only return attempts strictly before this timestamp.

afterstring

Only return attempts strictly after this timestamp.

Response Payload

data
array of object
required

Delivery attempts, newest first.

Show child attributes
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: the endpoint's url at the time of the attempt, which can differ from the current configuration after an update.

data.failure_reason
string

Why the attempt failed before any request was sent, for example a connector body that could not be rendered or an endpoint whose connection changed after the event was queued. Absent for an attempt that reached the network.

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.