Bird vs Prelude

Bird vs Prelude for Verify

Prelude is built around a risk verdict you can branch on, and Bird has no equivalent to it. The two APIs are otherwise close enough that porting is mostly a rename. This page is about which of those two facts matters more for what you are building.

What Prelude is great at.
Where Bird is different.

What Prelude is great at

A verdict you can branch on. The create call accepts IP, device and fingerprint signals and answers with a routing verdict, with risk factors when it refuses. Bird's create answers with the verification itself: there is no verdict, no signals object, and no shadow block. A signup that gates on that decision has to make it before it calls Bird.

Channels Bird does not reach. A voice call, RCS, Viber, Zalo and silent network authentication, across 230+ countries. Both platforms carry SMS, WhatsApp and Telegram, so the gap is those five rather than the whole mix: a number Prelude reached over Viber or Zalo falls back to SMS here, which is a delivery-rate question worth measuring in a pilot rather than discovering at full volume.

The message and the fallback are yours to shape. A template with variables, a locale, your own sender ID and a custom code are all per-request, and max_auto_fallbacks and force_challenge tune the escalation per call. On Bird the passcode text is Bird's and the fallback is the country's channel plan; senders are configured per channel rather than per request, and only the email one can be an address of your own.

Where Bird is different

A failed check says which kind of failure it was. Prelude folds a wrong code and exhausted attempts into one failure status. Bird answers with a reason of incorrect_code, expired or attempts_exhausted, and returns attempts_remaining beside it, so the screen can tell a user how many tries are left without counting them yourself.

Delivery events are a workspace subscription, signed. Prelude posts to a callback_url you set per verification. Bird's endpoints are registered once, each subscribed to the event types it wants, and every delivery is signed per Standard Webhooks, so the URL leaves the request body and the receiver has something to verify.

An agent can run the flow. Bird's hosted MCP server gives an agent three verification tools against a real workspace: start one, check a code, and advance to the next channel. It cannot reconfigure the policy behind them, which is deliberate rather than an omission.

The matrix

Capability by capability.

The two APIs are shaped alike, so most rows are even and the differences are narrow. Read the safe-retries row against the Twilio Verify page: it is a Bird win there and even here, because Prelude has a deduplication mechanism and Twilio Verify documents none. Prelude's risk layer is a concession above rather than a row, because Bird ships nothing to compare it against.

CapabilityBirdPreludeWho wins?
Create requestJSON to /v1/verify/verifications with a bearer key. The recipient is to.phone_number or to.email, and calling create again for a live recipient retries rather than starting a new verification.JSON to a v2 verification endpoint with a bearer key. The recipient is target.type and target.value, and calling create again for a live recipient retries in the same way.
Safe retriesAn Idempotency-Key header on the create makes a retry safe.A dispatch_id on the create deduplicates a repeated request. It is a field on the body rather than a header, and it does the same job.
What a failed check tells yousuccess is false with a reason of incorrect_code, expired or attempts_exhausted, and attempts_remaining beside it.A status of failure covers both a wrong code and exhausted attempts, with expired_or_not_found as a separate value. The two failure kinds are not distinguished.
Channels a passcode can arrive onEmail, SMS, WhatsApp and Telegram. Voice is labelled Rolling out rather than shipped.Their published channel mix is SMS, voice, RCS, WhatsApp, Telegram, Viber, Zalo and silent network authentication, across 230+ countries, with automatic fallback between them.
Delivery eventsA workspace webhook subscribed to the verify event types you name, such as verify.verification.verified and verify.attempt.delivered, signed per Standard Webhooks.A callback_url set per verification on the create request, so the destination travels with each call.
Fallback controlThe country's channel plan sets the order, and a next-channel call advances one verification to the next channel in it.max_auto_fallbacks and force_challenge tune the escalation on the create request itself.
Hosted MCP serverThree verification tools on the hosted server at mcp.bird.com: start a verification, check a code, and advance to the next channel. Configuration is not among them.Prelude publishes backend SDKs for Node.js, Python, Go, Kotlin/Java and Ruby, and mobile SDKs for iOS and Android, so the agent story is a library your own runtime calls.
Code lengthoptions.code_length on the create, else the workspace default.options.code_size on the create.

The same verification

Starting one verification.

The shapes are close enough that this is mostly a rename: target becomes to, code_size becomes code_length, and dispatch_id becomes an Idempotency-Key header. What does not appear on the Bird side is the signals object, and there is no verdict on the response to branch on.

Prelude

verify.ts
const signupId = crypto.randomUUID();

const response = await fetch("https://api.prelude.dev/v2/verification", {
  method:  "POST",
  headers: {
    Authorization:  `Bearer ${process.env.PRELUDE_API_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    target:      { type: "phone_number", value: "+15551234567" },
    dispatch_id: signupId,
    options:     { code_size: 6 },
  }),
});

const verification = await response.json();
console.log(verification.id, verification.status);

Bird

verify.ts
import { BirdClient } from "@messagebird/sdk";

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

const signupId = crypto.randomUUID();

const { data, error } = await bird.verify.verifications
  .create(
    {
      to:      { phone_number: "+15551234567" },
      options: { code_length: 6 },
    },
    { idempotencyKey: signupId },
  )
  .safe();

if (error) console.error(error.message);
else console.log(data.id, data.status);

Switching cost

Low, unless you use the risk layer.

Both APIs key on the recipient rather than a verification ID, so the calls port almost as they stand: target.value becomes to.phone_number or to.email, code_size becomes code_length, dispatch_id becomes an Idempotency-Key header, and the per-verification callback_url becomes a workspace webhook subscribed to the verify event types you name.

The risk layer is the part that is not a port at all. If you branch on Prelude's verdict, send signals with the create, or rely on a shadow block, there is nothing on the Bird side to move that logic to and the decision has to happen before the call. Size that gap first, because everything else here is an afternoon.

Questions people actually ask

Is Bird a good Prelude alternative?
If you use Prelude as a verification API, yes: the calls are shaped alike, the port is close to a rename, and Bird tells you more about a failed check than Prelude does. If you use Prelude as a fraud product, no. The signals, the routing verdict and the shadow block have no Bird equivalent, and that is the question to settle before anything else.
What happens to Prelude's signals and verdict?
Nothing carries over. Bird's create takes no signals object and answers with the verification rather than a decision, so an integration that gates sign-ups on Prelude's verdict has to make that decision itself before it calls Bird. What Bird offers in that space is narrower and mostly configuration: per-country enablement so you can shut off destinations you never serve, and platform send and check caps.
Do I lose safe retries by moving?
No, and this is the row where Bird and Prelude are even rather than one winning. Prelude deduplicates a repeated create with a dispatch_id on the body; Bird does it with an Idempotency-Key header. Different placement, same guarantee, and a retry after a timeout does not put a second code on the handset either way.
Which channels do I lose?
A voice call, RCS, Viber, Zalo and silent network authentication. SMS, WhatsApp and Telegram are on both, and Bird adds email, so the gap is narrower than the channel counts suggest. A number that Prelude reached over Viber or Zalo falls back to SMS on Bird, so measure the delivery rate for those markets in a pilot rather than at full volume.

Mulai dengan satu channel.
Tambahkan yang lain saat Anda siap.

API key uji coba langsung tersedia untuk Anda. Akses produksi terbuka setelah Anda menambahkan metode pembayaran dan memverifikasi pengirim.

Menggunakan Claude Code, Cursor, atau Codex? Salin prompt pengaturan dan agen Anda akan menginstal Bird CLI dan skill untuk Anda. Pilih milik Anda:

Cursor