Sign inGet started

Migrate SMS from Bird Connectivity Platform

This page maps the Bird Connectivity Platform API at rest.messagebird.com, the one you may still know as the MessageBird API, to Bird. Follow the main migration guide in order and use these mappings for steps 3, 4, and 5.
Both platforms are Bird's, and the API is the part that changes. Three differences affect every call. Requests go to your regional host, https://us1.platform.bird.com or https://eu1.platform.bird.com, rather than one global host. Authentication is a bearer API key (Authorization: Bearer bk_us1_…) rather than Authorization: AccessKey. And the send is asynchronous: POST /v1/sms/messages returns 202 Accepted with the message queued, where the Connectivity Platform returned the message object with a per-recipient status already attached.

Hand this to your agent

Paste this into Claude Code, Cursor, or Codex. The agent works through this page against your own repository, using whichever Bird surface it already has: the MCP server if one is connected, the CLI if it is installed and signed in.
Code example
I am moving an SMS integration from the MessageBird Connectivity Platform to Bird. Route through it with me.
1. Check what you already have before setting anything up. If Bird's MCP server is connected, use its tools. If the Bird CLI is installed and signed in, use that. Either one is enough, and every step below is an action you take with whichever you have. Only if neither is present, follow https://bird.com/docs/ai/set-up-your-agent.md to set one up and sign me in. Every Bird docs page serves Markdown at its own URL with `.md` appended, so fetch that rather than the HTML.
2. Read https://bird.com/docs/guides/sms/migrate/connectivity-platform.md for the field, status and opt-out mapping, and https://bird.com/docs/guides/sms/migrate.md for the order the steps go in.
3. Find and list my Connectivity Platform usage in this repository before you change anything: the send call sites, the originators they send from and whether each is a number or an alphanumeric sender ID, and the status-report URLs they register.
4. Tell me early if I use any of flash, binary, mclass or typeDetails on my sends. None of them carries over, and they need raising with Bird support before a cutover date exists, so I would rather know now than at the end.
5. Then take only the paths that apply to me.
   - If I send with an alphanumeric sender ID: it does not move with the account. Each one is re-created on Bird and re-registered wherever the destination country requires registration, so tell me which countries I send to and what each of them will need, following the sender section of https://bird.com/docs/guides/sms/migrate.md.
   - If I send to US long codes: read https://bird.com/docs/guides/sms/10dlc.md and work through the brand and campaign registration. Read the requirements first. A registration attempt is chargeable and a rejected brand is charged again on resubmit, so show me the exact payload, then wait for me to reply with the words submit the brand, or submit the campaign. A reply that agrees without naming what it is authorising is not authorisation for a chargeable step, and a bare ok go ahead is that shape. One authorisation covers one submission, so ask me again before the campaign even if I have already authorised the brand.
   - Carry over my opt-outs following https://bird.com/docs/guides/sms/opt-outs-and-keywords.md. A Bird suppression is one sender-and-subscriber pair rather than a global list, so if what I kept is a single list of numbers, ask me which originators it should apply to and import it once per originator.
   - Ask me which numbers I want to keep, then open a Bird support ticket for the port, listing those numbers and saying they port from the Connectivity Platform. Route it to a person rather than an automated answer. Give me the ticket ID. The port runs on Bird support's schedule rather than yours, so plan the cutover around it.
6. Test the ported path against Bird's simulated destinations before any real traffic, following https://bird.com/docs/guides/sms/migrate.md. They exercise the send and the webhook handler against real API responses and real signed deliveries without reaching a handset, but a simulated send is billed at the destination's normal rate, so tell me how many you plan to send and keep the smoke test to that. The United States must be enabled and `from` must be a sender valid for the US, or the test numbers reject.
7. Stop and ask me wherever a step needs a decision. Do not point production traffic at Bird until I have seen the simulated-destination results and replied with the words cut over to Bird. Retiring the Connectivity Platform path is a separate step that comes later: ask me again and wait for me to reply with the words retire the Connectivity Platform path. A reply that agrees without naming what it is authorising is not authorisation. Finish by telling me what is left that only a person can do.

Map the send call

What it doesConnectivity PlatformBird
Recipientrecipients (up to 50)to, one per request
Senderoriginatorfrom
Bodybodytext
Intent(none)category, required on free text
Encodingdatacodingdetected automatically
Transliteration(none)options.smart_encoding (default false)
Client referencereferencemetadata, or tags when you filter on it
Status reportsreportUrla workspace webhook subscribed to the delivery events below
Safe retries(none)Idempotency-Key header
SchedulingscheduledDatetimeno equivalent: scheduled_at is rejected
Validityvalidityno equivalent: validity_period is rejected
Route selectiongatewayBird selects the route
Message classmclassno equivalent
Binary and flashtype, typeDetailstext only
Both rejected fields are reserved and answer 422 SMSUnsupportedFeature.
Porting notes:
  • The recipients array becomes one call per recipient. A Connectivity Platform call with 50 recipients becomes 50 sends, or one batch of independent messages. The batch is not a fan-out of one body: each entry carries its own recipient, sender, and text.
  • datacoding has no equivalent, and that is deliberate. Bird detects the encoding from the body and reports the segment count on the message. If you set datacoding: auto to keep messages inside GSM-7, the closest behavior is options.smart_encoding, which replaces characters outside the GSM-7 alphabet with their nearest equivalent before sending.
  • reference splits into two fields. Put an internal identifier in metadata, which is echoed on every webhook event, and use tags for the low-cardinality labels you want to filter and slice analytics by.
  • Flash messages, binary payloads, and UDH concatenation do not port. If you rely on mclass or typeDetails today, raise it with support before you plan the cutover rather than after.
  • Also on the Connectivity Platform Verify API? The port is a separate job with its own guide: see Migrate Verify from another provider.

Carry over opt-outs

The Connectivity Platform left stop-keyword handling to you, whether you built it in Flows or in your own application against inbound messages. Bird does that job itself: it recognizes stop, start, and help keywords on your numbers in supported countries, records the suppression, and enforces it on every send. That code retires with the migration.
What does not retire is the list. Export whatever you keep today, as pairs of subscriber number and the originator they stopped, and import it through the suppression loop before your first production send. If you only ever kept a global list of subscribers who opted out, import each subscriber once per originator you still send from.

Translate status reports

OutcomeConnectivity PlatformBird
Accepted by the API(synchronous)sms.accepted
Handed to the carriersent, bufferedsms.sent
Carrier confirmed deliverydeliveredsms.delivered
Delivery faileddelivery_failedsms.failed
Validity window elapsedexpiredsms.expired
Refused before sending(request error)sms.rejected
Waiting to be sentscheduledno equivalent yet
The delivery mechanism changes more than the vocabulary:
  • Signed JSON posts replace reportUrl GET callbacks. Status reports arrived as GET requests with the outcome in the query string (status, statusReason, statusErrorCode, mccmnc, price[amount]). Bird POSTs a JSON event to endpoints your workspace registers, signed per Standard Webhooks. The handler is a rewrite rather than a URL change.
  • Correlation no longer depends on reference. A status report was only useful if you had set a reference; a Bird event always carries sms_id, both numbers, and your echoed metadata and tags.
  • Retry semantics differ. The Connectivity Platform retried a failed report up to 10 times. Bird's deliveries are at-least-once and unordered, so deduplicate on the webhook-id header and sort by the payload timestamp.
  • Price is not on the event. The Connectivity Platform report carried price[amount] and price[currency]. Read cost from the message itself with GET /v1/sms/messages/{id} or in aggregate from the Stats API.
Inbound messages work the same way: subscribe to sms.received once for the workspace instead of pointing each number at a URL.

Cut over

Destinations, senders, and the traffic ramp are provider-independent and covered in the main guide. The item to raise early is your originators: alphanumeric sender IDs are re-created and, where the country requires it, re-registered here, and numbers you hold on the Connectivity Platform move by a port that support arranges rather than a setting you flip.

Next steps