All guides

OTP SMS Verification: Best Practices for Delivery and Cost

Practical guide to sending OTP codes by SMS: message length, expiry windows, retry logic, sender ID, and how pay-per-delivered pricing changes the economics of verification texting.

Keep the message small and single-purpose

A single SMS segment is 160 characters (70 if you use non-GSM characters like emoji or Bangla script). Every character beyond that doubles your cost by splitting into a second segment. A tight code message fits in one segment with room to spare:

"Your verification code is 482913. It expires in 10 minutes." — 59 characters, one segment, universal delivery.

Never put the code in the middle of marketing copy. Verification messages should contain exactly four things: the code, the brand name, the expiry, and nothing else.

Set an expiry window and enforce it

Ten minutes is the industry norm for OTP validity. Shorter windows frustrate users on slow networks; longer windows turn a leaked code into an account-takeover risk. Whatever you choose, enforce expiry server-side — a code that your API still accepts after an hour is not an expiry policy, it is a suggestion.

Limit verification attempts too. Five attempts per code, and rate-limit code requests per phone number (three per hour is a reasonable default) so a spammer cannot turn your OTP endpoint into someone else's SMS bill.

Retry intelligently, not automatically

When a user reports a missing code, waiting 30–60 seconds and resending once beats instant double-sends: carrier queuing often delays the first message rather than losing it. Auto-retrying in a loop is the fastest way to burn balance on congested routes.

This is where pay-per-delivered pricing changes behavior. On Koipabo, a failed send is refunded automatically, so retries are cheap — but delivery reports still take a few seconds to come back, and a resend sent blindly can arrive before the original, leaving the user with two codes and your app rejecting the first.

  • Wait for the delivery report (or ~60s) before resending
  • Cap manual resends at 2–3 per verification session
  • Rate-limit code generation per number, per hour
  • Log delivery status per message — your audit trail for support

Use a sender ID users recognize

An alphanumeric sender ID (your brand name) gets dramatically better open and copy rates than a random short number, provided the destination country supports alphanumeric IDs. Some markets (notably the US and Canada) force numeric senders — plan your UX around the code being the star, not the sender.

Finally, tell users in your UI which channel to expect: 'We texted a code to +46 ••• 9921'. Masked numbers reduce duplicate requests, and a resend timer on the button reduces angry double-taps.

Cost example at real volumes

At Koipabo's flat $0.005 per delivered SMS, a product verifying 50,000 sign-ups a month costs $250 — and less on bundled volume pricing. On providers charging $0.0079+ per message and billing failures, the same volume runs noticeably higher before a single undelivered route is accounted for.

Run your own numbers on the pricing calculator — the per-destination rate card is public, and the API responds with the exact price of every send.

Ready to send cheaper SMS?

Flat $0.005 per delivered message. No monthly fee. Top up from $10.

Get started