A one-time passcode is the most impatient text your product will ever send. A marketing message that lands 40 seconds late is fine. A login code that lands 40 seconds late gets a second request, then a third, and then a support ticket. OTP traffic also attracts its own kind of fraud, and it sits under the same carrier rules as every other business text in the US.

This guide is for product teams wiring passcodes into signup, login or account changes. It covers which 10DLC use case to register, what controls delivery speed, how SMS pumping drains budgets, and what to do when SMS fails. We make Ready, so we explain where it fits and where it doesn't. One limit up front: Ready has no hosted "Verify" product that generates and checks codes for you. You generate the code, store a hash, check it, and Ready delivers the text.

Register the right use case first

Every business text sent from a 10-digit long code in the US needs A2P 10DLC registration: a brand (your company) and a campaign (what you send). Unregistered traffic gets carrier-filtered. For OTP, a silently dropped login code locks a user out.

Register a dedicated two-factor authentication campaign for passcodes. Don't fold codes into a mixed or marketing campaign. Carriers check that what you send matches what you declared, and mismatches get filtered. Our use-case picking guide covers why that matters. Keep OTP sample messages boring and literal: a code, your brand name, an expiry, a "don't share this" line.

On Ready, registration runs in-app, but the app and the API do not offer a 2FA campaign type yet (a campaign is Marketing, Customer care, Mixed, Delivery notifications, Account notifications or Fraud alerts). Email support@tryready.com before you route login codes through Ready.

  • Brand: ~$10/mo
  • Campaign: ~$20/mo
  • Each number: $2/mo
  • At submit: $25 for the first month, with no setup fee
  • Timing: most approvals take 2 to 7 days

You can test before approval. The first 20 one-to-one texts are free, which suits OTP testing, so use them before you register: they end the moment a registration is paid for. An account can send up to 500 texts a month before registering, at the normal rate. To send, you add a card and get a number, which is $2 a month with the first month charged when you get it.

If you're a platform sending codes for your customers' apps rather than your own login, each customer needs its own brand registration. Ready gives each one a sub-account with its own numbers and registration.

What actually controls delivery speed

Your code calls the API in milliseconds. The text reaching the phone depends on three things you only partly control.

Registration status

Registered routes are the baseline. Without registration, nothing else matters much.

Per-second throughput

Carriers meter campaigns in segments per second. A fresh standard campaign with no vetting typically gets roughly 1 to 4 segments per second. Higher use-case tiers get tens. These are approximations, since carriers publish no official rate card.

Worked example. Assume a fresh campaign at 3 segments per second. A login spike sends 600 OTP requests in one minute, each 1 segment. That's 600 segments against a ceiling of about 180 per minute. The last users in the queue wait over two minutes. Many will tap "resend," which makes the queue longer.

The fixes are:

  • Spread bursts where you can, such as not forcing a re-login for every user at the same moment after a deploy.
  • Look at brand vetting ($79 Standard or $179 Enhanced, one-time). Vetting raises your trust score, which can move T-Mobile's daily brand cap. That cap runs from about 2,000 messages a day at the lowest trust score up to about 200,000 at the highest. Vetting only moves the cap when your score crosses a tier, and it does not change the per-second rate.

The rate limits post goes deeper on this.

Message length

Keep OTPs to one GSM-7 segment: 160 characters, no emoji. An emoji switches the message to unicode, cuts the segment to 70 characters, and can turn a 1-segment code into 3 segments. That triples the cost and the throughput load. A good template:

482913 is your Acme login code. It expires in 10 minutes. Never share it.

That's under 80 characters and one segment.

Quiet hours: a real caveat

Ready enforces quiet hours by default. A one-to-one or API text sent during the recipient's local quiet hours is held only if the window opens within 6 hours; otherwise it is refused and not sent. That's the right behavior for promotions and the wrong one for a login code at 11 PM. Before you route OTP traffic through Ready, email support@tryready.com to confirm how quiet hours apply to your account. Also give every code a short expiry, so a delayed code is rejected rather than accepted hours later.

Sending the code: the request

Ready's API takes one text per call:

curl -X POST https://api.tryready.com/v1/messages \
  -H "X-API-Key: $READY_API_KEY" \
  -H "Idempotency-Key: 3f6b2c1e-8a4d-4f0e-9b7a-2d5c1e9f0a11" \
  -H "Content-Type: application/json" \
  -d '{"to": "+12125550199", "body": "482913 is your Acme login code. It expires in 10 minutes. Never share it.", "consent_attested": true}'

consent_attested. This is your statement that the recipient agreed to the text. A user who typed their number and pressed "send code" requested this message.

Idempotency-Key. This header matters more for OTP than for anything else. Generate one key per code issuance and reuse it on network retries. A retried request then never sends twice, while a user tapping "resend" gets a new key and a new code. Two different valid codes arriving out of order is a common cause of "the code didn't work" tickets. The duplicate texts post walks through the pattern.

Opt-outs. Opted-out and numbers on your Ban list are refused up front and not charged. A user who once texted STOP to your number won't receive codes. Your UI needs to catch that refusal and offer another factor, rather than spinning forever.

Full request details are in the messages docs and the quickstart.

SMS pumping: the fraud that targets OTP forms

SMS pumping (also called artificially inflated traffic) works like this: bots hit your "send code" endpoint with phone numbers whose carriers share revenue with the attacker. You pay for every text, and nobody ever enters a code. Any public form that sends a text on submit is a target.

Defenses that work, roughly in order of payoff:

  1. Restrict destinations in your own code. If your users are all in the US, reject non-US numbers before calling any API.
  2. Rate limit per number, per IP and per account. For example, allow 3 sends per number per hour with a 30 to 60 second resend cooldown. Pick your own thresholds, but set them.
  3. Add a CAPTCHA or proof-of-work before the send. Put it on signup especially, where there's no existing session to trust.
  4. Track your verify rate. Watch codes verified divided by codes sent. Learn your normal ratio. A spike in sends with a collapsing verify rate is the signature of pumping. Alert on it and pause automatically.
  5. Validate the number at entry. Ready's validation endpoint (GET /v1/validate/:phone) tells you whether a number is mobile, landline or disconnected before you spend a segment. See the number validation post for how to use it at signup.

None of these is a single fix. Layer them.

What OTP costs on Ready, and when it's not the right pick

Each OTP is one segment at $0.0075 plus a $0.0045 carrier fee. That all-in figure excludes the compliance surcharge: scrubbing and landline validation each cost $0.003 extra per segment when switched on, and both are off by default.

Worked example. Assume 40,000 verifications a month, with resends averaging 1.2 texts per verification.

Line itemMathMonthly
Segments sent40,000 × 1.248,000 segments
Ready rate48,000 × $0.0075$360
Carrier fee48,000 × $0.0045itemized separately
Registration$25 for registration + $2 number$27

Notice that resends are a cost line. Fewer resends, from faster delivery and short single-segment messages, cut the bill directly.

When to look elsewhere. If OTP is the only thing you'll ever text, a raw CPaaS like Twilio is a reasonable choice. Its per-segment price, around $0.0083, is lower than ours, and at high OTP volume that gap adds up. What Ready includes on top is self-serve registration, opt-out handling, number validation, sub-accounts for multi-tenant platforms, and one API for the rest of your product's texting. That bundle is worth it when you send more than codes. If you don't, say so to yourself honestly.

Fallback channels when SMS fails

SMS is convenient but not the strongest factor. Our SMS two-factor authentication post covers SIM-swap risk in detail. Plan a fallback for when a text doesn't arrive.

ChannelGood forWatch out for
Authenticator app (TOTP)Repeat logins, security-conscious usersSetup friction, lost-device recovery
PasskeysPhishing-resistant loginDevice and browser support varies
Email codeUsers without reliable mobile signalSlower, spam folders
Blue line (iMessage)Low-volume, conversational verificationLimits below make it a poor primary OTP channel

On the blue line specifically: it sends as iMessage, needs no 10DLC registration, and costs $99/mo per line plus 6 cents per segment. Each line can start up to 50 new conversations a day, and it sends at most 2 texts to someone until they reply. OTP recipients almost never reply. Treat it as an edge case, not a fallback for a login form. Details are in the blue line guide.

Ready has no automated voice-call OTP. The Ready Dialer is for people placing calls from a dial pad, not for robocalled codes. If you need voice delivery, use a provider built for it.

The practical takeaway

For SMS passcodes that arrive fast and don't drain your budget:

  • Register a dedicated 2FA campaign (on Ready, ask support first).
  • Keep every code to one plain segment.
  • Use idempotency keys so retries never double-send.
  • Rate limit and watch your verify rate for pumping.
  • Confirm how quiet hours treat your traffic.
  • Offer a non-SMS factor for when texts fail.

If Ready's included registration and compliance tooling suit the rest of your texting, create an account and test your OTP template with the free first 20 texts before you register.