SMS OTP
In previewSend a code by SMS. Check it by recipient.
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 } = await bird.verify.verifications.check({
to: { phone_number: "+15551234567" },
code: userInput,
}).safe();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 the shared Authifly SMS sender; 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 and a per-workspace daily quota bound send volume and runaway spend, each a 429 with Retry-After.
- 05
Reach that expands by country.
SMS sends on the shared Authifly sender today, deliverable where it's registered, 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 } = await bird.verify.verifications.check({
to: { phone_number: "+15551234567" },
code: userInput,
}).safe();
// data.result is true or false; data.reason elaborates ("expired", "already_verified", …)SMS OTP FAQ
What is SMS OTP?+
Do I need to store a verification id to check the code?+
Which countries can I reach?+
How do you stop SMS pumping and brute force?+
Who do my users see the code from?+
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.