Coming Soon

The SMS API for developers who actually need to ship.

150+ countries, 240 direct-to-carrier connections, one auth model. About 40% of the world's commercial SMS volume transits the Bird network — we've been at this a decade. 95% of messages delivered in under 2.5 seconds.

send-otp.ts
200 · 0.4s
import { BirdClient } from "@bird/sdk";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

const code = generateOtp();

const { data, error } = await bird.sms.send({
  from: "Bird",
  to:   "+15005550006",
  text: `Your Bird verification code is ${code}. Reply STOP to opt out.`,
}).safe();

if (error) throw error;
console.log(data.id);
// → "sms_4kT01Lq2m..."

5 minutes from npm install to first send

Send an SMS from the language you already use.

SDKs in every major runtime. The first send goes to a sanctioned test recipient (+15005550006) so you can ship a CI check before you provision a number.

1
2
3
4
5
6
7
8
9
import { BirdClient } from "@bird/sdk";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

const { data, error } = await bird.sms.send({
  from: "Bird",
  to:   "+15005550006",
  text: "Hello from Node.",
}).safe();

Ten things we file, configure, and route so you don't.

Routing, compliance, and inbound primitives, named and audit-able.

  1. 01

    150+ country coverage

    One unified API, one billing relationship — no per-region contracts to chase down.

  2. 02

    240 direct-to-carrier links

    No middleman aggregator skimming margin or dropping receipts between us and the MNO.

  3. 03

    Operator-grade routing

    Real-time route reselection when a carrier path degrades; failover happens before you notice.

  4. 04

    Two-way SMS inbound

    Inbound messages arrive as HMAC-signed webhooks on the number you provisioned.

  5. 05

    Numbers of every shape

    Long codes, short codes, toll-free, and alphanumeric sender IDs — provisioned via one endpoint.

  6. 06

    A2P 10DLC in-dashboard

    Brand and campaign registration handled in the console; status is queryable from the API.

  7. 07

    MNP lookup before send

    We resolve the recipient's current carrier on every send so the route is always right.

  8. 08

    STOP / HELP compliance

    Opt-out keywords honored automatically per recipient; suppression list is queryable.

  9. 09

    Delivery receipts as webhooks

    Every state transition fires a signed event — sms.queued through sms.delivered or sms.failed.

  10. 10

    Segment and Unicode safety

    The SDK counts segments before send and warns on encoding flips that would split a message.

Why we build SMS

SMS is the messy channel. We built the API that makes it boring.

Every country has different rules, every carrier has different routes, every region has different sender-ID conventions. We've been running SMS for ten years, so that knowledge lives behind one endpoint, one auth model, one webhook contract. Whatever changes upstream, the call you wrote against bird.sms.send doesn't.

send-otp.ts
200 · 0.4s
import { BirdClient } from "@bird/sdk";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

const code = generateOtp();

const { data, error } = await bird.sms.send({
  from: "Bird",
  to:   "+15005550006",
  text: `Your Bird verification code is ${code}. Reply STOP to opt out.`,
}).safe();

if (error) throw error;
console.log(data.id);
// → "sms_4kT01Lq2m..."

Every state change is a webhook.

HMAC-signed payloads, replay-protected, idempotent. The same envelope on every Bird channel — learn one, you've learned them all.

POST /webhooks/bird
signed
{
  "type": "sms.delivered",
  "id":   "evt_7jR42x...",
  "created_at": "2026-05-19T15:42:01.221Z",
  "data": {
    "sms_id":     "sms_4kT01Lq2m",
    "from":       "Bird",
    "to":         "+15005550006",
    "mcc_mnc":    "310-260",
    "country":    "US",
    "segments":   1,
    "latency_ms": 1284
  }
}

Retry schedule: 5s, 30s, 5m, 30m, 2h, 6h, 12h. Dead-letter after the final attempt; every dead-lettered event is replayable from the dashboard or API.

  • sms.queuedAccepted by the API and queued for the carrier hand-off.
  • sms.sentSubmitted to the destination carrier's SMSC.
  • sms.deliveredDelivery receipt received from the carrier (DLR).
  • sms.failedPermanent failure — carrier rejection, invalid number, suppression hit.
  • sms.receivedInbound message on one of your provisioned numbers.
  • sms.opted_outRecipient sent a STOP keyword; future sends to this number will be suppressed.

If you've integrated SMS, you've integrated WhatsApp.

Same auth model, same idempotency contract, same error envelope, same webhook shape. The difference is what each one does — not how you call it.

SMS.

sms
await bird.sms.send({
  from: "Bird",
  to:   "+15005550006",
  text: `Your code is ${code}.`,
});

One verb. Plain text. Numeric to/from. The shape every developer already has muscle memory for.

WhatsApp.

whatsapp
await bird.whatsapp.send({
  from: "+15551234567",
  to:   "+15005550006",
  template: { name: "otp", variables: { code } },
});

Same verb. Different payload — templated, opted-in, in the channel two billion people open daily.

Country-dependent. From sub-cent to a few cents per segment.

Priced by usage. SMS rates depend on destination country and route — the full grid is on the pricing page. Volume discounts auto-apply at the account level. No seat fee, no tier features locked behind annual commits.

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.

Get startedRead docsor

Using Claude Code, Cursor, or Codex? Point it at our MCP server — tools for every channel we expose, with scoped agent keys.

Cursor