Changelog

Recently shipped.

improvement

Grant SMS management without granting the right to send

SMS had one scope. A key that could send a message could also delete a suppression, change a sender, edit the destination allowlist, and file a 10DLC registration. There was no way to hand someone SMS configuration without also handing them the ability to send, and no way to give support read-only access without write.

That splits today, the way Email and WhatsApp already did. sms keeps sending and the message log. Everything that configures the channel moves to a new sms_management scope.

What moves

sms_management now covers senders and their country registrations, 10DLC brands and campaigns, toll-free verification, suppressions, keyword replies, the destination allowlist, and templates.

sms keeps POST /v1/sms/messages, the batch send, the message log and its events, and SMS statistics.

Both scopes take read and write, and every built-in role holds the same level on both, so nothing changes for people in the dashboard. Admins and developers manage SMS as before; analysts still read it.

If you call these from an API key

Four operations change what they require, and existing keys are affected. GET /v1/sms/templates, GET /v1/sms/templates/{template_ref}, GET /v1/sms/destinations and PUT /v1/sms/destinations now need sms_management and return 403 for a key holding only sms. The same applies to bird sms templates and bird sms destinations on the CLI, and to the matching MCP tools.

A key's scopes are fixed when it is issued and cannot be changed, so the fix is a new key. Create one with both sms and sms_management from Developers → API keys, swap it in, and revoke the old one. On the CLI, bird login again: a fresh token carries sms_management:read.

The other management endpoints are reachable only from the dashboard, which already carries the new scope.

Granting less

The point of the split is the key you can now mint. A service that only sends holds sms:write and cannot touch a suppression. A support tool that reads senders and registrations holds sms_management:read and can send nothing. Grant the narrowest pair that works.

feature

Verify: passcodes over Telegram

Verify now delivers one-time passcodes over Telegram, alongside email, SMS, and WhatsApp. The channel is available in every country and sits after WhatsApp and SMS but before email, so no verification changes the channel it starts on. Where a recipient has both a phone number and an email address, Telegram is now tried before the email fallback. If you have pinned a channel order for a country, Telegram joins the end of that pin instead, until you save a new order placing it where you want it.

Codes arrive from Telegram's own verified notification account. There is no Bird sender and no sender of your own to configure, which is a property of the Telegram Gateway rather than something still to come. A number is checked for whether it can receive a Telegram message before one is sent, and where it cannot, the verification moves to the next channel without a message going out.

Using it

Nothing is required to turn it on. To reach Telegram earlier for a given country, reorder that country's channels in country configuration, or name the order per request with options.channels on POST /v1/verify/verifications. telegram is a valid channel name everywhere a channel name is accepted.

One thing to check if you call the API directly

A per-country channel order must name every channel available in that country. Telegram has now joined that set, so orders you saved before this release keep working, but re-submitting one is rejected with a 422 until you add telegram to it. Reading the country's current channels and submitting them back is enough. The dashboard handles this for you.

feature

Email Metrics gets an Inbound tab

The email Metrics page (Email → Metrics) now splits into an Outbound tab, everything you send, and a new Inbound tab covering what your workspace receives. Inbound shows a Messages received count for the selected range plus a volume-over-time chart, once you've set up a forward address or your own domain for receiving. See email metrics.

Also in this release:

  • New guide: SMS character limits lays out GSM-7 versus UCS-2 encoding, which characters (curly quotes, emoji, the euro sign and other extension-table characters) push a message into the pricier alphabet or eat two character slots, and the 12-segment cap on a single send.

feature

Contacts: import a list from a CSV or Excel file

Getting a list into Bird no longer needs a developer. Import on the Contacts page now takes a CSV, TSV or Excel file of up to 50,000 contacts, reads the header row to work out which column is the email address and which is the phone number, and shows you the first rows as the contacts they will become before anything is written.

Until now the dashboard took contacts pasted one per line as email, first name, last name, so anything that was not already in that exact shape meant editing a spreadsheet by hand first, and anything with custom fields meant calling the API. Most lists arrive as an export from another tool, with the columns that tool happened to name.

What's new

  • The columns are matched for you. "Email Address", "E-Mail", "Correo electrónico" and "email_address" all land on the email field, and a single column holding a whole name is split into a first and a last. Where two columns could fill the same field, the one whose values back up its name wins. Every match is a dropdown you can change.
  • You see the contacts, not the file. The preview shows the first ten rows as the contacts they will become, so a name column splitting the wrong way or a date reading as text is something you catch before you commit rather than after.
  • Rows that cannot be imported say why, and where. Each one is listed with the line number to open in your own file and what is wrong with it, both on the preview and again when the run finishes. Nothing is skipped silently.
  • Custom properties and audiences come along. Any column can map to one of your typed contact properties, and everyone in the file can be added to one or more audiences as part of the same import.
  • Re-importing is safe. Each row is matched against the identifiers it carries and updated, so importing a corrected file updates the contacts rather than duplicating them.

Importing and syncing contacts covers the flow. To sync from your own database instead, POST /v1/contacts/batch still upserts up to 1,000 contacts a call and now accepts 30 calls a minute.

feature

Receive SMS replies on your numbers

Bird SMS used to be outbound only. Now, when someone texts one of your numbers, Bird stores the message beside your sends and pushes it to your endpoint as sms.received, so you can answer a reply without polling for it.

What's new

  • The sms.received webhook. Subscribe from the API, the SDKs, bird webhooks create, or the MCP server. The payload carries the body, the segment breakdown, both numbers, and the sending operator where the carrier reports one, so you can act on a reply without a second request.
  • Inbound messages in the API and the log. GET /v1/sms/messages?direction=inbound returns what you received, and each message opens in the SMS log with its body and timeline.
  • Received-message metrics. The SMS Metrics page shows received volume with its period-over-period change, and a Received messages page breaks it down by number, country and sending operator, so you can see which of your numbers is taking the traffic.

Replies are yours to act on

Bird records a reply and passes it to you; it does not interpret it. A STOP arrives as an ordinary sms.received, and suppressing future sends to that number is your integration's job for now. We will say so clearly here when that changes.

One change to existing webhooks

carrier and mcc_mnc are now omitted from sms.sent, sms.delivered and sms.received payloads when the carrier does not report them, rather than arriving as null. That matches the way the message resource has always reported these fields. If you branch on null for either, check for absence instead. sms.accepted now also carries segments, the count your send is billed on.

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