OTP SMS in the UK: Sending Codes, Timing and Fallbacks

November 06, 2026

OTP SMS in the UK: Sending Codes, Timing and Fallbacks

To send a one-time password by SMS in the UK, generate the code on your server, send it through an SMS gateway to the number in international format, and verify it against your own store — not the provider’s — with a short expiry and a single use. The parts that decide whether it works are the expiry, the resend policy, the sender ID, and what happens when the message does not arrive. None of them are the API call.

This is the build order, with the UK specifics that matter.

What to build, in order

Generate server-side, never in the app. A code created by the client can be read by the client. Use a cryptographically secure random source, and keep the code shorter than intuition suggests: a six-digit code has a million possibilities, which is plenty when it is single-use and expires.

Store a hash, not the code. The same discipline as passwords. If the database leaks, the codes in it are useless.

Expire quickly and allow one attempt at success. Five to ten minutes is the common window; a code that works twice is a code that can be replayed.

Rate limit by number and by IP, not only per session. Otherwise an attacker with one handset and patience gets unlimited guesses at six digits.

Do not tell the client whether the number exists. “If that number is registered, a code has been sent” is the right response to a login form.

Why arrival times vary, and what to promise

Ask Google how long an OTP takes and you will get one to five seconds, attributed to a bank. Ask a bank and it will tell you to allow a minute. Both are true: one describes a normal case, the other a commitment. The gap between them is routing, congestion, ported numbers and the handset itself, none of which your application can see.

So build for the range rather than the best case:

  • A resend timer of 30 to 60 seconds, with the button disabled until it expires, so the customer does not request five codes and then use the third one to arrive.
  • A visible fallback path, such as an alternative email or a different number, rather than a page that simply does not advance.
  • A receipt-driven view of what happened. Delivery receipts tell you DELIVRD, EXPIRED, REJECTD or UNDELIV, and the difference between “we sent it” and “it arrived” is exactly the question your support queue will ask. Message state and error codes explains what each means.

If a code is EXPIRED more often than it is DELIVRD for a given country or network, that is a routing problem, not a user problem, and it is worth knowing before a customer tells you.

The UK specifics

Sender identity. A code from an alphanumeric ID such as ExampleShop is recognisable, and UK networks carry it for both local and international traffic. It has to be registered with us before traffic flows, typically in a working day, and generic names — Alert, Info, Verify, Security — are commonly blocked by operators precisely because phishing uses them. UK SMS rules has the full picture.

Cost. A six-digit code with a short brand prefix is one part, and UK destinations are 10.71 credits per part. Two things quietly double that: an emoji or a symbol outside the GSM alphabet, which switches the message to Unicode and cuts the capacity from 160 characters to 70, and a template long enough to split. SMS length has the tables.

Encoding. Codes are digits, so GSM 7-bit is right and needs no special handling — as long as nobody adds a ”✅” to the template. If the copy must contain characters outside GSM, set the encoding deliberately rather than letting a template change it by accident.

SMS is one layer, not the security model

The NCSC’s guidance is that multi-factor authentication should not rest on a single factor, and SMS OTP has specific weaknesses: SIM swapping, interception, and the plain fact that a code read aloud to someone on the phone is no longer a secret. Where the account matters, pair the SMS code with something else — a device binding, a risk score, or an in-app approval — and treat the code as evidence rather than proof.

The same reasoning says keep a second channel available. Not because SMS is unreliable, but because a handset with no signal is common and a login that cannot complete is a support ticket.

What to measure

Four numbers tell you whether the flow works, and all of them come from receipts and your own logs: codes sent, codes verified, codes expired without verification, and resends per verification. A rise in the last one is usually a delivery or template problem; a rise in expiries with no rise in resends is usually a user-experience problem.

What you cannot measure from here is whether the message arrived quickly. That is why the resend timer exists: it makes the customer’s wait something you control rather than something you hope for.

The short version

Generate server-side, hash what you store, expire in minutes, allow one success, rate limit by number, and tell nobody whether the account exists. Then register the sender ID, keep the template in GSM characters, and build the resend timer before launch rather than after the first complaint. If the account is valuable, add a second factor — SMS is a good one, not a sufficient one.

Transform Messaging with World-Text

Send SMS messages from one platform. Use the HTTP API for alerts and notifications, or two-way messaging for conversations. Volume pricing and delivery reporting included.