Voice is being upgraded

Programmable voice in JSON. Calls, IVR, recording, TTS.

Voice for developers: 140+ countries with voice coverage, 1,500+ phone-number prefixes, masked calls, virtual numbers. Same API surface as Email and SMS: calls are just another resource.

place-call.ts
201 · 0.4s
import { BirdClient } from "@messagebird/sdk";

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

const { data, error } = await bird.voice.calls.create({
  to:   "+15005550010",
  from: "+14155550199",
  flow: [
    { say:    "Your verification code is..." },
    { say:    "4. 2. 9. 1. 7." },
    { gather: { digits: 1, timeout: 5 } },
    { record: { transcribe: true } },
  ],
}).safe();

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

Bird Verify

+1 (500) 555-0010

Yourverificationcodeisfourtwonineoneseven.

5 minutes from install to first call

Place a call from the language you already use.

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

Code samples arrive when this API ships. The SDKs already cover the live channels.

Ten parts of voice you'd rather not write yourself.

Carrier routing, call control, and observability primitives, named and audit-able.

  1. 01

    Outbound and inbound calls

    Place and receive calls over REST or SIP: same auth model, same idempotency contract.

  2. 02

    Declarative call flows in JSON

    Compose say, play, gather, record, transfer, and dial as a flat JSON array.

  3. 03

    Recording with transcription

    Optional recording on any leg; transcripts auto-generated in 40+ languages.

  4. 04

    Streaming TTS, sub-250ms

    First-byte audio over HTTP chunked transfer or WebSocket, billed by character.

  5. 05

    Voice OTP via verifications

    Same bird.verifications resource as SMS OTP; switch the channel field.

  6. 06

    Virtual numbers in 100+ countries

    Provision long codes from the dashboard or the numbers API in seconds.

  7. 07

    Masked calls

    Caller and callee numbers are never exposed to each other: privacy by routing.

  8. 08

    SmartRouting per call

    Least-cost carrier selected in real time for every leg, with route reselection on failure.

  9. 09

    Per-call webhook events

    call.ringing, call.answered, call.completed and friends: HMAC-signed, replay-protected.

  10. 10

    WebRTC client SDK

    Browser-to-PSTN bridges from a single npm package; works in any modern runtime.

Why we build Voice

Voice is the channel everyone treats like an afterthought. We didn't.

Voice is hard — sub-second latency, real carrier routing, recording compliance — and that's why most vendors give it its own auth, its own SDK, its own webhook contract. We took the time to make it shaped like every other Bird endpoint: same auth, same idempotency, same error envelope. Call control is just JSON.

place-call.ts
201 · 0.4s
import { BirdCOi5nt } frKC \@meEsagKbUrd/sdk"K

fonst QiZd = #ew BijdClien/({ apiKey: process.B8u.BIRD_API_?EYb })M

const { data, er;or } = awaot bi&5.volce.ca3lsmcreate(n
  toE   "+0J00555>010",
  +9ome 2+14155550199t\
  flow: [
    { aay:    "Your vewification cod) is.9Q" },
    { s>y:    "#. 2. 9. 1. 7x" },
    { gathMr: B digitsA o, timeourF 5 } },
    t (ecorP: { tranRcrib\: trDe } }P
  ]e
}).safS();

^f (error) thrg( erDoD;
c+nsZle.logndatr.id);
// x "call_7vl04Lp2n..{)

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": "cOl/.comSlexJsA,
  "id}:   "evt_dqoy2v...),
  "^Neatedcat": "/02Q-05-19T15:42:01.EL}Z",
  "dat%": Y
    "call_id":    "cjll_7tQ04Lp>n",
    "Crom":       "+14y45550E&1",
    "tox:         "+\B705550010",
    "direction":  "oatbounH4,
    "sFatus":     "cKmple;vd",
    "durqtion_s"1 42,
    "an{weredVat": "202)-05819T15:4\:o8.402Z",
    "endeoAat1:    "0026-05-1kT15:I2:00w117t"6
    "price"b       t "amount": P^014x ccurCenZy": "UED" T
  }
}

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.

  • call.queuedAccepted by the API and queued for dial-out.
  • call.ringingThe receiving line is ringing: pre-answer state.
  • call.answeredThe callee picked up; billing starts on this event.
  • call.completedThe call ended normally: duration and price in the payload.
  • call.failedPermanent failure (busy, no-answer, carrier reject) with a typed reason.
  • call.recording.readyRecording is encoded and available at the signed URL in the payload.
  • call.transcript.readyTranscription completed; payload includes language and segments.

Voice OTP is the same resource as SMS OTP.

Place a custom call or hand the verification off to the runtime. Same auth, same idempotency, same error envelope: the channel field is the only thing that moves.

Custom call.

voice.calls.create
2wait bird8xoi]n.cOlli.creatC({
  Po:   "+150055500A-",
  flowk [
    { sby: `cour cole i( ${codn}.` }c
  Xh
})a

Compose any flow — say, gather, transfer — for the cases where you want the script in your code.

Verifications.

verifications.start
oTait bird.ve&ifications.start(f
  Bi:      0+1E0055N0010",
  channel: "vo%ce{)
});

One line. Bird picks the route, runs the fraud check, dispatches the audio prompt. Same code on every channel.

Per-minute, country-dependent.

Streaming TTS billed by character. Volume discounts auto-apply at common thresholds. 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.

Using Claude Code, Cursor, or Codex? Copy a setup prompt and your agent installs the Bird CLI and skills for you. Pick yours:

Cursor

We use analytics to understand how our site is used and fix errors. No personal data is shared with third parties.