Stop brute-force guessing and automated OTP abuse.
Protect signup, login, and step-up verification flows against brute-force code guessing, automated resend loops, and SMS pumping without adding friction for legitimate users. Bird Verify hashes passcodes at rest, enforces per-session attempt limits and expiration windows, caps repeat sends per recipient, and lets you block countries you do not serve before a message is sent.
verify.ts
200 · pendingimport { 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;
Your account
Confirm it’s you.
Enter the code sent to
+1 ••• ••• 4567
verify.ts
200 · pendingimport { 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;
Your account
Confirm it’s you.
Enter the code sent to
+1 ••• ••• 4567
verify.ts
200 · pendingimport { 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;
Your account
Confirm it’s you.
Enter the code sent to
+1 ••• ••• 4567
Lock down OTP flows without building custom rate limiters.
Securing verification in-house means maintaining Redis counters for resend cooldowns, tracking failed guesses per session, hashing codes before database writes, and filtering out traffic to countries where you do not operate. With the Bird Verify API, those guardrails run automatically on each verification session. Plaintext passcodes stay out of API responses and application logs, check endpoints enforce bounded attempt budgets and per-minute rate limits, and workspace settings let you tune expiration windows and allowed destinations across two-factor login and passwordless sign-in.
How Bird protects verification sessions from abuse.
Default guardrails and workspace controls that stop code guessing, resend floods, and unwanted international traffic.
- 01
Generate unpredictable passcodes.
Generate 6-digit numeric passcodes by default (or 4 to 8 digits per request) from a cryptographic random source across the full code space so attackers cannot predict codes from timestamps or sequential counters.
- 02
Keep plaintext codes out of logs and responses.
Store passcodes as HMAC-SHA256 hashes at rest and omit the plaintext from API responses, webhook payloads, and dashboard logs so leaked application logs or support views cannot expose active codes.
- 03
Check submitted codes in constant time.
Evaluate user-submitted digits in constant time across active attempts in the session so response latency gives attackers zero signal about how many digits matched.
- 04
Lock out brute-force guessing and expire stale sessions.
Cap each session at 5 check attempts and a 10-minute expiration window by default, or tune both limits in your workspace settings. Once the attempt budget or timer runs out, the session closes and further checks are rejected, backed by per-minute check throttling.
- 05
Cap repeat sends and block unused countries.
Enforce a 60-second resend cooldown (configurable up to an hour) and a rolling cap of 5 sends per recipient address per hour so bots cannot flood a user's phone or drain your balance. Disable countries you do not serve in the dashboard to block SMS pumping to unserved destinations before a message is sent.
Guide real users on typos while locking out brute-force loops.
When a user mistypes a digit, the check response tells your app how many attempts remain so you can prompt them to try again. Once the session's attempt budget is spent, the verification closes automatically and blocks further guesses until a new session is started.
const { data, error } = await bird.verify.verifications.check({
to: { phone_number: "+15551234567" },
code: guess,
}).safe();
if (error) throw error;
// wrong code, attempts left → { success: false, reason: "incorrect_code", attempts_remaining: 2 }
// budget spent, session done → { success: false, reason: "attempts_exhausted", attempts_remaining: null }Coming next: automated risk signals and spend ceilings.
Alongside the country controls and per-recipient send caps available today, we are building a fraud layer directly into the verification lifecycle. Because it runs on the same send and check endpoints, your team will be able to turn on risk rules in configuration without changing application code.
Risk signals on verification requests. Pass device, IP, and request context when starting a verification so high-risk attempts can be blocked before a message goes out and incurs carrier charges.
Prefix velocity caps and spend ceilings. Combine per-country and per-prefix send limits with workspace verification caps to shut down artificially inflated traffic (AIT) attacks targeting premium carrier ranges before they drain your budget.
Decisioning backed by delivery history. Score new verification requests against the attempt and conversion history Bird Verify records across channels and surface blocked outcomes directly through your existing status handler.
Build it on the Verify platform
Multi-channel delivery, fallback routing, and authentication flows built on the same API.
Scale without
losing control.
Organize teams in workspaces, control API access, and trace changes through audit logs.
Organization
Harbor
Access stays in its workspace.
Production/API keys
Signup service
ActiveAlex Lee
Admin
Today · UTC
Audit log
Organization
Harbor
Access stays in its workspace.
Production/API keys
Signup service
ActiveAlex Lee
Admin
Today · UTC
Audit log
Organization
Harbor
Access stays in its workspace.
Production/API keys
Signup service
ActiveAlex Lee
Admin
Today · UTC
Audit log