What’s new. What’s next for you.

Product releases and developer updates from Bird.

improvement

Voice outbound price ranges

The Voice pricing page now shows a price range when the rate depends on the destination number prefix.

feature

Email inbox gets folders, read state, and a recoverable trash

Email conversations move from a single labels list to dedicated folder and read fields. Get, list, and update a thread now return folder (inbox, archive, spam, blocked, sent, or trash) and read, with labels reserved for your own custom tags. List threads by folder with folder=, filter by read state with read_state=read|unread, and match custom labels with labels=.

Trash is no longer a dead end: DELETE moves a conversation's messages to trash, and the new restore a thread endpoint (POST /v1/email/threads/{thread_id}/restore) brings back whatever hasn't passed its trash deadline or the mailbox's retention period, with folder, read state, and labels intact.

Also in this release:

  • Replies can add their own Cc and Bcc. Reply to a thread message now accepts cc and bcc on top of reply_all, each capped at 50 merged addresses. Bcc recipients stay out of conversation participants and visible headers, and their delivery outcomes are excluded from the sent message's per-recipient recipients list, which now only tracks the To and Cc lines.
  • Mailboxes split sender name from dashboard name. Create and update a mailbox take a name field for the sender name shown on outgoing mail; display_name is now what your team sees in the dashboard and defaults to name when no override is set.
  • Number ownership status explains unrecoverable cases. Get and list workspace numbers can now return ownership.unavailable_at for a number that can't be activated and ownership.registration_due_at, the deadline for completing ownership details before a number is removed.
  • WhatsApp template language pages link straight to Meta. Get a template version language adds whatsapp_manager_url, a direct link into Meta's WhatsApp Manager for that language.

feature

Answer incoming calls in the browser with ring groups

Your team can now answer incoming calls in the browser phone. Choose Online in the dashboard phone, and a call for one of your ring groups rings with the ringtone you picked and shows a system notification with the caller's number and contact name. The first member to select Accept takes the call, and it stops ringing for everyone else. Choose Busy to keep placing calls without being rung.

Every workspace starts with a Default group that rings everyone online. Add your own, such as support or sales, and point a number or your workspace's default inbound route at the group that should answer it. Members are rung five at a time until one of them answers, and after three missed calls in a row the phone stops ringing that member until they choose Back online.

Manage groups from Voice → Ring groups in the dashboard, or through the API, SDKs, CLI (bird voice ring-groups), and MCP: create a group and add members by user ID, then set a number's or the workspace's route type to ring_group (see update a number and update voice settings). A workspace can have up to 50 groups beyond the default, each with up to 200 members. See the ring groups guide for the full walkthrough.

Also in this release:

  • Email template personalization isn't just for broadcasts anymore. An individual, batch, or scheduled send can now use {{ bird.contact.* }} placeholders: Bird looks up each To address's contact in your workspace, and Cc/Bcc recipients receive a personalized copy for every To. A To with no matching contact rejects the send with 422 (E04099). See personalizing with variables and create an email message.
  • Broadcast templates can loop again. A broadcast template can now use {% for %} over a local list built with split, and, when it takes no caller parameters, literal ranges and {% tablerow %} too. Broadcast parameters stay scalar-only; arrays and objects still aren't supported.
  • Large files can upload to the media library in the background. New asset upload session endpoints let a client transfer bytes directly to temporary storage and complete the upload asynchronously, instead of a single multipart request, with sessions capped per workspace and organization.
  • SMS and WhatsApp message history masks sensitive template values instead of fully redacting them. A one-time code sent through a system template now reads with one asterisk per digit in its surrounding text; only authentication messages without declared sensitive variables still read **REDACTED**.

improvement

Guidance for building automatic SMS replies with Automations

Send messages in an automation now documents a complete pattern for auto-replying to an inbound SMS: start from an Incoming SMS trigger, map the reply's recipient to the incoming sender, and choose the receiving number as the reply's sender, noting that a number can accept inbound SMS without being eligible to send outbound. It also covers using a trigger filter to scope replies to one receiving number and to exclude opt-out and help keywords, so a STOP or HELP reply doesn't trigger your general acknowledgement. The SMS overview now links to this pattern as the no-code way to handle replies.

Also clarified in the same guide:

  • The WhatsApp messaging step can respond to incoming messages, but built-in steps can't label a WhatsApp conversation or assign it to a teammate, that's still a dashboard action under WhatsApp conversations.
  • The failure path on a send step now explicitly covers sends blocked by your workspace's send limits, not just channel rejections.

fix

Corrected field paths for Apple Messages for Business interactive replies

The API reference for send message, get message, list messages, list conversation messages, and get template version language previously described a customer's quick reply, list picker, or time picker selection as arriving on interactive_data.data.*. That field no longer exists; selections arrive on interactive_reply.

The docs now point to the right paths:

  • A quick reply selection is interactive_reply.quick_reply.selected_identifier.
  • A list picker selection is interactive_reply.list_picker.sections[].items[].
  • A time picker selection is interactive_reply.reply_message.title or a slot identifier under interactive_reply.
  • An image identifier referenced from a row or button resolves against interactive.images on the outbound message, or interactive_reply.images on a reply.

If you were parsing replies against the old interactive_data.data path, switch to interactive_reply.

Start building with Bird in minutes.