SMS verification sends a one-time code to a phone number and confirms the person typing it back holds the line. Bird generates the code, sends it, enforces per-recipient caps, and checks it by recipient, so there's no id to store and no resend endpoint to wire.
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;
SMS OTP is one call to send and one to check.
SMS is a phone-family channel on the Bird Verify API: post a verification with a phone number and we send the code on a Bird-managed shared sender, Bird Verify by default or Authifly if you prefer it; check it by that same number. Re-posting the create is the resend (create-or-retry), and every code in the session stays valid until it verifies, expires, or runs out of attempts.
What you get on an SMS verification.
Built in, on every send.
- 01
Addressed by phone number.
Pass a single E.164 phone number. We normalize it and send over SMS on the sender resolved for its country.
- 02
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. You never see the plaintext.
- 03
Resend is the same call.
Re-post the create to resend once the 60-second cooldown passes: same session, new code, both still valid. No separate resend endpoint.
- 04
Per-recipient caps included.
A per-recipient send cap bounds send volume and runaway spend, with a 429 and Retry-After.
- 05
Reach that expands by country.
SMS sends on a Bird-managed shared sender today, Bird Verify or Authifly, showing a branded sender ID where a country permits one and a short code or local number where one is required, with dedicated and registered senders extending reach as they land.
The whole flow, two calls.
Create-or-retry sends the code to the phone number; check confirms it by that number. There's no id to thread between the two: the recipient is the key.
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;
// data.success is true or false; data.reason elaborates ("incorrect_code", "expired", "attempts_exhausted")Put it into practice.
Continue with the documentation, guides and examples for this topic. Resources are in English.
The rest of the Verify platform
One API, one set of keys. Explore the other capabilities.
The verification API with nothing to store.
SMS is one channel of Bird Verify: email and WhatsApp ship with it, and voice is rolling out, all on the same two endpoints.