Twilio SMS & Voice
Send SMS and build voice applications with Twilio: OTP verification, two-way messaging, webhooks, and phone number management.
Twilio provides programmable SMS, voice, and verification APIs. SMS has near-100% open rates and is the preferred channel for OTPs, authentication, and time-sensitive notifications. Correct Twilio integration handles inbound messages, delivery status, and number compliance.
Use Twilio Verify for OTP/phone verification - it handles rate limiting, fraud prevention, and carrier routing for you. Use two-way messaging patterns for support workflows. Always check opt-in status before sending marketing SMS (legal requirement).
Workflow
- Send SMS with the Twilio SDKThe SDK handles authentication and retries over the REST API.
- Implement phone verification with Twilio VerifyRolling your own OTP has rate limiting, fraud, and carrier compliance issues Twilio Verify solves.
- Handle inbound SMS with webhooksTwo-way messaging enables SMS-based support, confirmations, and opt-out handling.
- Manage phone numbers and complianceSending SMS without proper number configuration causes carrier filtering and legal issues.
- Build voice with TwiMLTwiML is Twilio's XML-based voice scripting - no telephony expertise needed to build IVRs.
Output Format
SMS sending with messaging service, Verify for OTP (no custom OTP code), inbound webhook with opt-out handling, TwiML for voice flows, 10DLC registration for US.
Examples
OTP verification: `await client.verify.v2.services(SID).verifications.create({ to: `+${phoneNumber}`, channel: "sms" }); // later: const check = await client.verify.v2.services(SID).verificationChecks.create({ to: `+${phoneNumber}`, code: userEnteredCode }); if (check.status !== "approved") throw new Error("Invalid code")`Inbound handler: `app.post("/sms", (req, res) => { const twiml = new MessagingResponse(); if (req.body.Body.trim().toUpperCase() === "STOP") { markUnsubscribed(req.body.From) } else { twiml.message("Got it! We'll be in touch.") }; res.type("text/xml").send(twiml.toString()) })`TwiML voice: `<Response><Say voice="alice">Thanks for calling MyApp support.</Say><Dial><Number>+15005550006</Number></Dial></Response>`Edge Cases & Gotchas
- Phone number formatting: always normalize to E.164 format (+country_code + number) before passing to Twilio; use `libphonenumber-js` for parsing and formatting
- Delivery receipts: Twilio delivers status callbacks asynchronously; don't wait for delivery to return a success to the user - store message SID and update status via webhook
- US 10DLC: unregistered numbers are filtered by carriers in the US; register your brand and campaign before production SMS traffic
When to Break These Rules
- For email-based OTP where SMS friction would reduce conversion (B2C checkout), skip SMS and use email or authenticator apps.
Reference Files
Twilio Node SDK: https://www.twilio.com/docs/libraries/nodeTwilio Verify: https://www.twilio.com/docs/verify/api10DLC registration: https://support.twilio.com/hc/en-us/articles/1260800720410-What-is-A2P-10DLC-TwiML reference: https://www.twilio.com/docs/voice/twiml