Email OTP

Verify by email, on a real email network.

Set up in:
Cursor

Email verification sends a one-time code to an email address: no phone number required, and the channel reaches anyone with an inbox. Bird sends it on the same infrastructure that carries transactional email at scale, from a shared sender or your own verified domain, and checks it by recipient.

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

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

The verification channel that needs no phone number.

Email is a first-class channel on the Bird Verify API: post a verification with an email address and we send the code from a Bird-managed shared sender, otp@verify.bird.com by default or Authifly's otp@verify.authifly.com, or from your own verified domain. It's country-independent, so it works the same everywhere, and it rides the same network Bird runs for transactional email at scale.

For the meaning of OTP and how a one-time code works, read What does OTP mean?.

What you get on an email verification.

Built in, on every send.

  1. 01

    Addressed by email.

    Pass a single email address. No phone number, no country: email is the one channel that reaches anyone with an inbox.

  2. 02

    Shared or your own domain.

    Send from a Bird-managed shared sender out of the box (otp@verify.bird.com, or Authifly's otp@verify.authifly.com), or override to a domain you've already verified for sending.

  3. 03

    A ready-made OTP email.

    The code lands in a clean, mobile-ready default template: the code up front, an expiry note, and a reminder never to share it. Nothing to design before you ship.

  4. 04

    On the Bird email network.

    Your codes ride the same delivery infrastructure as your product's transactional email: signed, routed, and monitored.

  5. 05

    Server-generated, hashed codes.

    A 6-digit code by default (4–10 configurable), generated with a cryptographic random source and stored only as an HMAC.

  6. 06

    Check by recipient.

    Confirm the code by the email address it went to: no verification id to keep, and re-posting the create resends within the session.

Send to an address, check by the same address.

An email verification is the same two calls as any other channel: only the recipient shape changes from a phone number to an email address.

email-otp.ts
200
await bird.verify.verifications.create({
  to: { email: "ada@example.com" },
}).safe();

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

// data.success is true or false; data.reason elaborates ("incorrect_code", "expired", "attempts_exhausted")

Your verification codes on the network that runs your email.

Email is one channel of Bird Verify: SMS and WhatsApp ship with it, and voice is rolling out, all on the same two endpoints.

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