Documentation
Sign inGet started

Verify your first customer

Bird Verify confirms that someone controls an email address or phone number: you ask Bird to send a one-time passcode, the person types it back into your app, and you ask Bird whether it matched. Bird generates the code, delivers it, stores only a hash, and enforces expiry and attempt limits — so your app never sees or stores the code itself.
This page takes you through it end to end by verifying your own email address, which needs no setup at all: email codes go out under Bird's shared Authifly sender, so there's no domain to verify and no balance to fund. Verifying a phone number is the same two calls once you've funded SMS.

1. Create an API key

In the dashboard, go to Developers → API keys and create a key. Keys are scoped to a region and look like bk_us1_... or bk_eu1_... — the region in the prefix tells you which API host to call: https://us1.platform.bird.com or https://eu1.platform.bird.com.
The API Keys page in the Bird dashboard, listing keys with their masked prefix, scopes, and last-used time
The full key is shown once, at creation time. Copy it somewhere safe, then export it for the snippets below:
Przykład kodu
export BIRD_API_KEY="bk_us1_..."

2. Send a code

Create a verification for the address you want to confirm. The only required field is to — put your own email address in it so you can read the code that arrives.

curl

Przykład kodu
curl -X POST https://us1.platform.bird.com/v1/verify/verifications \
  -H "Authorization: Bearer $BIRD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": { "email_address": "you@example.com" }
  }'
If your key starts with bk_eu1_, call https://eu1.platform.bird.com instead.

TypeScript

Przykład kodu
npm install @messagebird/sdk
Przykład kodu
import { BirdClient } from "@messagebird/sdk";

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

const verification = await bird.verify.verifications.create({
  to: { email_address: "you@example.com" },
});

console.log(verification.id, verification.status); // "vrf_…", "pending"
Bird accepts the request and sends the code right away:
Przykład kodu
{
  "id": "vrf_01jzp0dv4qf6vb1nc23yjc8f2e",
  "status": "pending",
  "to": { "email_address": "you@example.com" },
  "channels": [{ "channel": "email" }],
  "last_channel": "email",
  "expires_at": "2026-07-16T12:24:07Z"
}
There's no verification ID to store: the check in step 3 is keyed by the same recipient. The email arrives from Authifly OTP <otp@verify.authifly.com> with the subject "Your verification code" and a six-digit code that's valid for 10 minutes by default.

3. Check the code

Take the code from your inbox and submit it, keyed by the same recipient:

curl

Przykład kodu
curl -X POST https://us1.platform.bird.com/v1/verify/verifications/check \
  -H "Authorization: Bearer $BIRD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": { "email_address": "you@example.com" },
    "code": "482913"
  }'

TypeScript

Przykład kodu
const result = await bird.verify.verifications.check({
  to: { email_address: "you@example.com" },
  code: "482913",
});

console.log(result.success); // true
A correct code comes back success: true, and the embedded verification flips to verified:
Przykład kodu
{
  "success": true,
  "verification": { "id": "vrf_01jzp0dv4qf6vb1nc23yjc8f2e", "status": "verified" }
}
That's the whole flow. Two things worth knowing before you wire it into a signup:
  • A wrong code is a 200, not an error. You get success: false with a reason (incorrect_code, expired, attempts_exhausted) and an attempts_remaining count — a normal answer to branch on, not an exception. The verification fails for good after 5 wrong tries by default.
  • A verification resolves once. After it reaches verified (or fails or expires), checking it again returns a 404. Treat the first definitive answer as the answer. If the user needs a new code, call the create endpoint again with the same recipient — an in-progress verification is reused, and a fresh code goes out once the 60-second resend cooldown has passed.
Every verification you create shows up on the Verifications page in the dashboard, with its status, recipient, channel, and timing — everything except the code itself, which is never stored.
The Verifications page listing verifications with status, recipient, channel, and creation time columns

Verify a phone number instead

To verify over SMS, put a phone number in to in E.164 format instead of an email address:
Przykład kodu
curl -X POST https://us1.platform.bird.com/v1/verify/verifications \
  -H "Authorization: Bearer $BIRD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": { "phone_number": "+15551234567" }
  }'
The check is identical — swap email_address for the same phone_number. Two differences from the email path: SMS draws on your workspace's SMS balance (an unfunded workspace fails the send), and the code is delivered under the Authifly sender ID rather than a message you can brand yet.

Reach the user on both channels

You don't have to pick one channel up front. Put both an email_address and a phone_number in a single to, and Bird resolves a delivery plan from your country configuration — which channels are available for that destination and the order to try them. It works down that plan until a send is accepted, so if the code can't go out over one channel it fails over to the next (SMS to email, or email to SMS) rather than failing outright. Check the code exactly as above, with the same to you created the verification with — the user enters whichever code reached them.

Next steps