Passwordless login

Make the code the credential.

Set up in:
Cursor

Passwordless login drops the password entirely: the user proves they hold a phone number or email by entering a one-time code, and that's the credential. With Bird Verify it's the same send-then-check flow: no password to store, reset, or breach, and silent network authentication on the roadmap to remove even the typing.

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: { email_address: "ada@example.com" },
}).safe();

const { data } = await bird.verify.verifications.check({
  to:   { email_address: "ada@example.com" },
  code: userInput,
}).safe();

The code isn't a second factor here. It's the only one.

Passwordless is the Bird Verify API used as the login itself: create a verification for the address the user signs in with, then check the code they enter: verified means logged in. There's no password row to protect and no verification id to store, and which channel each user gets is configurable per country. Keep a password in front instead and the same calls power two-factor authentication.

What passwordless gets you.

Less to store, less to steal.

  1. 01

    No password to breach.

    There's no password hash to leak, no reset flow to phish, and no credential reuse across sites. The factor is possession of a channel.

  2. 02

    One flow for signup and login.

    The same create-then-check verifies a new address at signup and re-verifies it at login. One path, not two.

  3. 03

    SMS, email, or WhatsApp as the credential.

    Sign users in with the channel you already have for them (SMS, email, or WhatsApp), with voice rolling out as more options.

  4. 04

    Silent auth on the roadmap.

    Carrier-network (silent) verification, which proves the number with no code to type, is designed in as a future channel, so the friction can drop further without a rewrite.

How passwordless login works

  1. 01

    The user enters the email or phone they want to sign in with.

  2. 02

    One create call sends a one-time code to that address.

  3. 03

    The user enters the code on your screen.

  4. 04

    One check call by recipient. A verified result grants the session, with no password compared and nothing stored.

Sign in with a code, not a password.

Send the code to the address the user enters, then check it. A verified result is the login: there's no password to compare against.

passwordless.ts
200
await bird.verify.verifications.create({
  to: { email_address: input.email },
}).safe();

const { data } = await bird.verify.verifications.check({
  to:   { email_address: input.email },
  code: submitted,
}).safe();

// a true result is the login — no password to compare
if (data.result) grantSession(input.email);

Drop the password. Keep the API simple.

Bird Verify is the login itself when you go passwordless: SMS and email now, with silent network auth designed in for later.

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