Documentation
Sign inGet started

List events for a message

GET
/v1/email/messages/{message_id}/events
curl -X GET "https://us1.platform.bird.com/v1/email/messages/{message_id}/events" \
  -H "Authorization: Bearer $TOKEN" \
  --url-query "limit=25"
Response200
{
  "data": [
    {
      "id": "ev_01krdgeqcxet5s7t44vh8rt9mg",
      "type": "email.delivered",
      "recipient_id": "er_01krdgeqcxet5s7t44vh8rt9mg",
      "bounce_type": "hard",
      "bounce_code": "5.1.1",
      "rejection_reason": "recipient_suppressed",
      "link_name": "Faster exports, docs",
      "country": "US"
    }
  ],
  "next": [
    {
      "kind": "operation"
    }
  ],
  "next_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE0OjAzOjEwWlwiIiwiaSI6IjAxOTJmM2IxLTRjN2UtN2EyYi05ZDYxLThmM2E1YzJlN2I0MCJ9",
  "prev_cursor": null,
  "refresh_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE2OjQyOjAxWlwiIiwiaSI6IjAxOTJmM2IxLTllMDQtN2NkMy1iODE3LTJhNmY0ZDFjOGUwOSJ9"
}
Returns the message's per-recipient event timeline, oldest first, as a cursor page. Lifecycle, failure, and engagement events interleave as they happen, and engagement events (email.opened, email.clicked) can repeat per recipient. Filter to one event type with type. For each recipient's current state rather than its history, use List recipients of a message.
Parameters
message_id
string
ID of the message whose timeline to read, from the send response's id field.
Query Parameters
limit
integer
Maximum number of items to return per page.
starting_after
string
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
Cursor from the prev_cursor field of a previous list response. Returns items immediately before the cursor position in the current sort order.
type
string
Filter by event type, for example email.bounced or email.opened.
Possible values (may grow over time): 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.rejected, email.scheduled, email.unsubscribed
Response Payload
data
array of object
required
Page of timeline events for this email send, in chronological order.
Show child attributes
data.id
string
required
Event ID.
data.type
string
required
The event's type. email.processed, for example, means the message has been processed and queued for delivery.
Possible values (may grow over time): 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.rejected, email.scheduled, email.unsubscribed
data.occurred_at
string
required
When this event occurred.
data.recipient_id
string
required
Recipient this event applies to.
data.bounce_type
nullable string
Bounce classification. Present on email.bounced, email.out_of_band_bounce, and email.deferred events.
  • hard: a permanent failure (invalid address or non-existent domain).
  • soft: a transient failure (mailbox full or server temporarily unavailable).
  • block: the receiving mail server blocked the sending IP for reputation reasons.
  • admin: an administrative refusal (relaying denied or blocklisted domain).
  • undetermined: the receiving server's response is ambiguous.
Possible values: hard, soft, undetermined, admin, block, null
data.bounce_class
nullable integer
A more detailed numeric bounce code, useful for telling apart failures that share the same bounce_type. For example, a DNS failure and a spam block can both come through as bounce_type: soft or bounce_type: block; this field tells you which one actually happened. Present on email.bounced, email.out_of_band_bounce, and email.deferred events.
data.bounce_code
nullable string
SMTP status code returned by the receiving mail server. Present on email.bounced and email.deferred events.
data.bounce_description
nullable string
The bounce reason, in plain language, as reported by the mail server. Present on email.bounced and email.deferred events.
data.rejection_reason
nullable string
Specific cause of rejection. Present on email.rejected events only.
  • recipient_suppressed: The recipient is on the workspace suppression list.
  • transmission_failed: The message could not be transmitted for delivery.
  • generation_failure: The message could not be built for delivery, because of a template or content issue.
  • policy_rejection: The message was refused by sending policy.
  • domain_unverified: The sending domain was not verified.
  • quota_exceeded: The organization's send quota was reached.
  • recipient_not_allowed: This recipient was not allowed for this send. For a send from the shared onboarding domain, every recipient has to be a verified member of the workspace.
Possible values: recipient_suppressed, transmission_failed, generation_failure, policy_rejection, domain_unverified, quota_exceeded, recipient_not_allowed, null
data.sending_ip
nullable string
The IP address used to send this message. Useful for spotting a deliverability problem that is tied to one specific sending IP rather than affecting all of them. Present on email.delivered, email.bounced, email.out_of_band_bounce, and email.deferred events.
data.mailbox_provider
nullable string
The recipient mailbox provider, as a lowercased classifier bucket (e.g. gmail, yahoo, microsoft, apple). Present on email.processed, email.delivered, email.complained, email.bounced, email.out_of_band_bounce, email.deferred, email.rejected, email.unsubscribed, email.list_unsubscribed, email.opened, and email.clicked events when the receiving mail system could be classified; null when it could not.
data.mailbox_provider_region
nullable string
The provider region, as reported by the receiving mail system (for example NA, EU, APAC). The set is open and provider-specific. Present on email.processed, email.delivered, email.complained, email.bounced, email.out_of_band_bounce, email.deferred, email.rejected, email.unsubscribed, email.list_unsubscribed, email.opened, and email.clicked events when reported; null otherwise.
data.is_prefetched
nullable boolean
True when the open was auto-fetched by an inbox privacy feature (Apple Mail Privacy Protection, the Gmail image proxy) rather than a person actually opening the message. Use it to calculate open rate accurately. Present on email.opened events only.
data.url
nullable string
The clicked URL. Present on email.clicked events, and on email.unsubscribed events when the recipient unsubscribed through a link in the message.
data.link_name
nullable string
The clicked link's own name, when the link in the message carried one, so a click can be reported by what the link said rather than where it pointed. Absent when the link had no name. Appears alongside url on email.clicked events, and on email.unsubscribed events when the recipient unsubscribed through a link.
data.country
nullable string
ISO 3166-1 alpha-2 country code derived from the client IP. Present on email.opened and email.clicked events when available.
data.ip_address
nullable string
Client IP address (IPv4 or IPv6). Present on email.opened and email.clicked events when available.
data.user_agent
nullable string
Client user-agent string. Present on email.opened and email.clicked events when available.
next
array of object
What to do next, given what this page reports. Present only where the read computes it: an empty list means the answer you were looking for is here and there is nothing further to do. Absent entirely on reads that do not report next actions.
Show child attributes
next.kind
string
required
What you do about this step.
  • operation: call the operation named in operation, then read again.
  • external: act somewhere this API does not reach, then read again.
  • wait: nothing is asked of you, so read again later.
  • terminal: nothing you do resolves this, so stop retrying.
Tolerate a value you do not recognize: show the description and offer no action.
Possible values (may grow over time): operation, external, wait, terminal
next.description
string
required
A short, human-readable label for the step, suitable for display.
next.operation
string
The operationId to call. Present only when kind is operation. The operation's own schema says how to call it; this says only which one, and what to address it with.
next.params
object
The parameters that address the operation, by name: {"sender_id": "…"} for an operation on /v1/sms/senders/{sender_id}/requirements. A parameter the operation takes in its query string is given the same way, so an operation addressed as ?subject_id= carries {"subject_id": "…"}. Every parameter the call needs is here, whether its value came from the thing you were acting on or is fixed for this step, so you can make the call from this object alone. Present only when kind is operation and the operation names a subject. A request body, when the operation takes one, is described by the operation's own schema and never appears here.
next.url
string
A URL to open. Present only when kind is external, and only when the step has one. An external step whose description says to go and do something with no URL to open is normal.
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. Pass back as ending_before later to fetch items that have appeared since this response. Non-null whenever data is non-empty; null only on an empty page. Distinct from prev_cursor.