Analytics

See what the carrier saw.

See accepted volume, carrier-reported delivery, non-delivery outcomes and latency in Bird. Use the dashboard for a quick review or the stats API for reporting. Recent sends can still be awaiting a receipt, so read the results alongside the message lifecycle.

Cursor

From a send to its outcome

Example report

Accepted

1,000

Delivery rate

96%

Delivered960

Non-delivery outcomes25

Still awaiting an outcome15

Illustrative data. Delivery uses accepted messages as its denominator. Recent sends can remain unsettled; carrier receipts do not measure opens or clicks.

Trusted every day by teams that build world-class software

Read more customer stories

The reporting side of the same API.

Nothing new to instrument.

Analytics is the reporting side of the Bird SMS API. The dashboard and stats API summarize accepted messages and observed outcomes. Use them to identify trends, then open an individual message when you need its reported delivery history.

What a delivery receipt tells you.

Read the metric alongside its definition.

  1. 01

    Delivery rate.

    Delivery rate is delivered divided by accepted, with no rate when the accepted denominator is zero. Counts use approximate distinct aggregation at scale. Recent cohorts can change as receipts arrive.

  2. 02

    Failure reasons by carrier.

    Compare failure codes and carrier breakdowns where the reported dimensions are available. A rise identifies where to investigate; sender registration, recipient conditions and provider failures require different remedies.

  3. 03

    Segments and cost.

    Inspect encoding, segments and the cost known so far on each message. The stats API counts message outcomes; it is not a billing ledger or a measure of invoiced segments.

  4. 04

    Latency to delivery.

    Inspect processing, carrier delivery and total latency at p50, p95 and p99. Compare the longer tail across periods to identify a destination or carrier that needs investigation.

Query the numbers from your own code.

Query time series and the supported country, carrier, originator, category, error and tag breakdowns. They summarize observed events for the acceptance cohort. Dimensions can overlap: adding tagged rows or terminal outcome counts does not reliably reconstruct a unique total.

delivery-by-route.ts
200 · stats
// One endpoint per dimension, and one dimension per row: "by country and
// carrier" is two calls, not one grouped query.
const { data: byCarrier, error } = await bird.sms.stats
  .byCarrier({ from: "2026-06-01", to: "2026-06-26" })
  .safe();

if (error) throw error;

console.log(byCarrier.data[0]);
// → {
//     carrier:  "Vivo",
//     delivery: {
//       accepted:      14820,
//       sent:          14810,
//       delivered:     14720,
//       undelivered:   60,
//       failed:        25,
//       delivery_rate: 0.9932,
//     },
//     latency: { processing: { p50_ms: 480, p95_ms: 2310, p99_ms: 4100 } },
//   }

Pull the timeline for one message.

For an individual message, retrieve its event timeline and current status. Public message reads cover 30 days. Events can arrive late or be duplicated; interpret occurrence time and reported errors rather than assuming webhook arrival order is delivery order.

message-timeline.ts
200 · events
const { data: events, error } = await bird.sms
  .listEvents("sms_01m11jw130e7svjzv70kgqr38w")
  .safe();
if (error) throw error;

console.log(events.data);
// → [
//     { id: "evt_01m11jw196...", type: "sms.accepted",  occurred_at: "2026-06-26T10:00:00.110Z" },
//     { id: "evt_01m11jw19h...", type: "sms.sent",      occurred_at: "2026-06-26T10:00:00.640Z" },
//     { id: "evt_01m11jx4c2...", type: "sms.delivered", occurred_at: "2026-06-26T10:00:02.300Z" },
//   ]

Slice the same sends however the question is shaped.

Choose the breakdown that matches your question and keep missing dimensions and overlapping counts visible.

DimensionWhat it tells you
CountryWhere delivery holds and where a destination is dragging the global rate down.
Reported carrierWhich reported carrier is associated with a delivery or failure trend.
SenderWhich sender IDs or numbers are associated with an outcome; this is not a reputation score.
Time bucketWhen a rate moved, so a drop lines up against a deploy, a registration change, or an outage.

Go deeper in the docs.

Build your own store from the delivery webhooks, read the deliverability guide for what the failure codes mean, and reconcile counts against billing and usage.

The receipts come from the routing layer.

Use routing guidance to understand the sending path. Incoming messages for two-way numbers have a separate inbound statistics family based on reception time. Outbound delivery metrics remain grouped by acceptance time.

Put it into practice.

Continue with the documentation, guides and examples for this topic. Resources are in English.

Get an implementation brief

Questions before you build

How is delivery rate calculated?
Delivered messages are measured against accepted messages in the selected send-time range. Recent sends can remain unsettled while carrier receipts arrive.
What counts toward the failure rate?
The documented failure-rate calculation includes undelivered, failed and expired outcomes. Rejected traffic is displayed separately, so it should not be added to that rate without changing its definition.
Can I break a report down by carrier?
The stats API exposes separate breakdowns for supported dimensions, including country, carrier and originator. Use the filters that endpoint supports. Two independent aggregate reports do not establish a combined carrier-by-country result.
Does SMS reporting include opens and clicks?
A carrier delivery receipt reports delivery, not a read or click. Measure link visits and conversions through an appropriately configured link and application analytics flow.
Can I inspect one message?
Open its message record and event timeline to follow acceptance, carrier handoff and the reported outcome. Use the stats API for aggregate trends and webhooks for events in your own application.

The metrics ship with the API that produces them.

Use reporting alongside the sending API. Move from an aggregate trend to an individual message, inspect its events and decide whether to change your audience, sender setup or integration.

Your details

All contact fields are required.

So our team can reach you about your demo.

Products of interest

Optional

We’ll contact you to arrange your demo.
Privacy policy

Start with one channel.
Add the others when you're ready.

A test API key is yours immediately. Production unlocks when you add a payment method and verify a sender.

Using Claude Code, Cursor, or Codex? Copy a setup prompt and your agent installs the Bird CLI and skills for you. Pick yours:

Cursor