Documentation
Sign inGet started

Migrate Verify from Twilio

This page maps Twilio Verify v2 to Bird Verify. Follow the main migration guide in order and use these mappings for steps 1 and 3.
The Service is the piece with no counterpart. Twilio addresses POST https://verify.twilio.com/v2/Services/{ServiceSid}/Verifications, and the Service holds code length, TTL, lookup, landline handling, and rate limits. Bird addresses POST /v1/verify/verifications with no service segment: those settings are workspace configuration. If you ran several Services to separate brands, apps, or environments, that separation becomes separate workspaces, each with its own API key and settings, rather than an ID in the path.

Map the create call

What it doesTwilio VerifyBird
RecipientToto.phone_number or to.email
ChannelChanneloptions.channels, else the country's configured order
Code lengthService CodeLengthoptions.code_length, else the workspace default
Code lifetimeService TTLthe workspace Duration setting
Attempt limitService max attemptsthe workspace Maximum Retries setting
CorrelationTagsmetadata
Safe retries(none)Idempotency-Key header
Custom passcodeCustomCodeno equivalent
LocalizationLocaleno equivalent
Message contentTemplateSid, CustomFriendlyName, ChannelConfigurationno equivalent, apart from a branded email sender
Per-key throttlesRateLimitsfixed platform guardrails
Fraud controlsRiskCheck, Fraud Guard, DeviceIpnot exposed on the API
SMS autofillAppHashno equivalent
PSD2Amount, Payeeno equivalent
The channels do not line up one to one either:
Twilio ChannelBird
smssms
emailemail
whatsappwhatsapp
callno equivalent
sna, autono equivalent
rcsno equivalent
(none)telegram, available for numbers registered with Telegram
A flow that uses call as the accessibility fallback, or sna and auto for a codeless path, needs rethinking before you commit to a date. Everything else is a channel-order change on the Countries page rather than a per-request parameter.

Map the check call

Twilio's POST /v2/Services/{ServiceSid}/VerificationCheck takes To or VerificationSid, plus Code. Bird's POST /v1/verify/verifications/check takes only the recipient and the code, so the VerificationSid path disappears along with the column you stored it in. Supply exactly the address set you created the verification with.
The result shape differs where it matters most:
  • Twilio answers with a status field; Bird answers with a boolean. success: true means verified. success: false carries a reason of incorrect_code, expired, or attempts_exhausted, plus attempts_remaining, so the "how many tries left" figure you may be counting yourself comes back on the response.
  • Both go to 404 once the verification is spent. Twilio deletes the verification when it is approved, expired, or out of attempts; Bird stops accepting checks in any final state. Store the first definitive answer rather than re-checking.

Translate statuses

Twilio statusBird statusBird reason
pendingpendingnone
approvedverifiednone
max_attempts_reachedfailedattempts_exhausted
expiredexpiredttl_elapsed
canceledno equivalent: a verification is not cancellable
There is no update endpoint, so the Twilio pattern of forcing a verification to approved or canceled from your backend has no counterpart. A verification ends when the user verifies it, exhausts the attempts, or lets it expire.

Move the event stream

Twilio Verify reports activity through Event Streams: a sink plus a subscription to verification status events, configured outside the Verify API. Bird uses the same webhook mechanism as every other channel. Subscribe an endpoint to verify.verification.* for session events and verify.attempt.* for individual passcode deliveries, and verify the signature per Standard Webhooks. See Verify events.
The two axes matter when you port dashboards. Twilio's verification status events line up with Bird's session events, and Bird's attempt events add per-send delivery outcomes on the same session, including the sends that a resend or a channel failover produces.

Cut over

The cutover rule in the main guide is the one to plan around: a code issued by Twilio cannot be checked by Bird, so switch at the create call and keep routing checks to whichever provider issued the verification until the last Twilio code expires.
Also budget for the sender change. Twilio Verify delivers under your Service's friendly name and your own sender pool; Bird delivers under Authifly on email, SMS, and WhatsApp, with your own domain available for the email channel. Users mid-signup see a different sender, and support scripts that say "look for a text from us" need updating.

Next steps