Migration guide

How to migrate from Bird to Sinch

A developer-focused guide to moving an SMS integration from Bird to Sinch, covering channel and compliance differences, request-format changes, and a step-by-step migration checklist.

Bird is a communications infrastructure platform (formerly MessageBird) offering unified APIs for SMS, WhatsApp, voice, and email. Sinch is a cloud communications platform covering messaging, voice, and email APIs. On the messaging.dev Score, Bird rates 76/100 and Sinch 92/100; this guide covers what actually changes at the API level when you move an existing Bird integration to Sinch.

What changes, and what stays the same

Channels. Moving from Bird to Sinch, you lose no channel: SMS, WhatsApp, voice, and email are supported on both. You gain MMS, RCS, Viber, Facebook Messenger, Telegram, and Apple Messages for Business, none of which Bird’s dataset entry lists.

Compliance. Identical — both are GDPR, ISO 27001, SOC 2, and HIPAA aligned. No certification is lost in the move.

Data residency. Both offer US and EU servers with a data-residency choice. Sinch additionally lists APAC, Australia, and Brazil regions; Bird lists none beyond US/EU.

Pricing and credit. Both are usage-based. Bird lists about $0.0073 per US SMS message; Sinch about $0.0075 per US SMS segment (carrier fees extra on both), and Sinch adds committed-use pricing on top of pay-as-you-go. Both provide self-onboarding, a sandbox, high-quality docs, and free developer credit — Bird’s is a free email tier (1,000/month), while Sinch’s trial-credit amount isn’t published.

SDKs and protocols. Bird ships TypeScript, Python, and Go; Sinch ships Java, Python, C#, Node.js, and PHP. Python carries over; if you use Bird’s Go or TypeScript SDK, you’ll switch languages. Sinch also supports SMPP alongside REST and SMTP.

How the send request differs

Bird’s SMS quickstart:

curl -X POST "https://us1.platform.bird.com/v1/sms/messages" \
  -H "Authorization: Bearer bk_us1_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155550100",
    "from": "Bird",
    "text": "Your Bird verification code is 481920. It expires in 10 minutes.",
    "category": "authentication"
  }'

Sinch’s SMS quickstart:

curl -X POST 'https://us.sms.api.sinch.com/xms/v1/YOUR_SERVICE_PLAN_ID/batches' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"from":"+15005550006","to":["+15551234567"],"body":"Hello from Sinch"}'

Endpoint. Bird posts to https://us1.platform.bird.com/v1/sms/messages. Sinch posts to https://us.sms.api.sinch.com/xms/v1/{service_plan_id}/batches — note the service_plan_id embedded in the path, which Bird has no equivalent for.

Authentication. Both use a Bearer token in the Authorization header. Bird’s key is region-prefixed (bk_us1_... / bk_eu1_...) and the prefix encodes the regional host. Sinch uses a plain API token, and the region is selected by the hostname (us.sms.api.sinch.com) rather than by the key.

Payload mapping. The sender field is from on both. The recipient field is to on both, but Bird takes a single string while Sinch takes an array of strings. The message body is text in Bird and body in Sinch. Bird’s category field (e.g. "authentication") has no direct equivalent in the Sinch batch example, so drop it.

Migration checklist

  1. Create a Sinch account, generate an API token, and note your service_plan_id (see the Sinch quickstart).
  2. Choose your region host (us / eu) to match your current Bird residency setup.
  3. Map the request fields: toto (wrap as an array), fromfrom, textbody; drop category.
  4. Re-point sending code to the /batches endpoint with service_plan_id in the path.
  5. Swap the SDK — Python carries over; otherwise move to Node.js, Java, C#, or PHP.
  6. Re-test in Sinch’s sandbox before sending live traffic.
  7. Update delivery/webhook callbacks to Sinch’s format.
  8. Run both providers in parallel, compare delivery, then cut over.

Watch out for

  • Recipient must be an array. Sinch’s to requires a JSON array even for a single number; passing a bare string as Bird does will fail.
  • service_plan_id lives in the URL path — a new required value with no Bird equivalent, not a header or body field.
  • No Go or TypeScript SDK. If your Bird integration uses either, you’ll rewrite against a different Sinch language SDK or raw REST.
  • Free-credit amount is unpublished. Bird’s free email tier (1,000/month) doesn’t carry over, and Sinch’s trial-credit value isn’t stated.
  • The category field is dropped. Any message-category logic you relied on in Bird needs re-checking against Sinch’s own API.

For a full side-by-side, see the Bird vs Sinch comparison.