Two-factor authentication

Add a second factor in two calls.

Two-factor authentication adds a second proof on top of a password: a one-time code on a channel the user controls. With Bird Verify it's a send call at the moment of login and a check call when the user types the code back: SMS, WhatsApp, or email today, per-country channel config, and nothing to store between the two.

Cursor
verify.ts
200 · pending
import { BirdClient } from "@messagebird/sdk";

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

// Send the code, then check it by recipient.
await bird.verify.verifications.create({
  to: { phone_number: "+15551234567" },
}).safe();

const { data, error } = await bird.verify.verifications.check({
  to:   { phone_number: "+15551234567" },
  code: userInput,
}).safe();
if (error) throw error;
Verification flow

Your account

Confirm it’s you.

Enter the code sent to

+1 ••• ••• 4567

Example verification code

482691
Code verified
Send a code. Confirm the recipient.

Trusted every day by teams that build world-class software

Read more customer stories

2FA is the verification flow, pointed at login.

Under the hood, 2FA is the same flow the Bird Verify API runs everywhere: create a verification for the user's phone or email when they sign in, then check the code they enter. Because the check is by recipient, your login handler keeps no per-attempt state, and the workspace's routing decides which channel a given user gets. Drop the password in front of it and the same flow becomes passwordless login.

What you wire up for 2FA.

Two calls and a configuration.

  1. 01

    Send on login, check on submit.

    Create a verification when the user authenticates with their first factor; check the code when they enter it. That's the whole integration.

  2. 02

    SMS, WhatsApp, or email as the factor.

    Use the channel you already have for the user: a phone number over SMS or WhatsApp, an email over email. Voice is rolling out for more options.

  3. 03

    One configuration, workspace-wide.

    Routing, code rules, and channel plan live in a single configuration for the whole workspace, already covering login, signup, and high-value actions.

  4. 04

    Brute force is bounded.

    Attempt lockout and per-recipient send caps come built in, so a second factor doesn't become a new attack surface.

The login-time flow.

Send the code once the password checks out; verify it when the user submits. A wrong code is a result you branch on, not an exception to catch.

two-factor.ts
200
// Send the second factor once the password checks out.
await bird.verify.verifications.create({
  to: { phone_number: user.phone },
}).safe();

const { data, error } = await bird.verify.verifications.check({
  to:   { phone_number: user.phone },
  code: submitted,
}).safe();
if (error) throw error;

if (data.success) grantSession(user);

Two-factor authentication, on the same API as your other channels.

Bird Verify is the code-based factor for your login and signup: SMS, email, and WhatsApp now, voice rolling out.

Your details

All contact fields are required.

So our team can reach you about your demo.

Products of interest

Optional

We’ll contact you to arrange your demo.
Privacy policy

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