Articles · App ExamplesUpdated September 2026

You can add OTP login to an app in an afternoon, but the text message is never free.

A one time password login works like this. The user types a phone number. Your server makes a random code and a delivery provider sends it as a text. The server then accepts that code once, inside a short window. There is no password to store, no reset flow and no strength meter. That is why teams reach for it after adding user login the ordinary way. What surprises people is the invoice. Every code is a paid message, a share of them never arrive, and both of those are your problem rather than the provider's.

Below you get the published price of a text, the five things the server does, and the rules a code must follow. Then the failures that end up in your support inbox. That should be enough to decide whether to build it, buy it or skip it.

Work out what the codes will cost

The short version

The screen takes an afternoon, the bill and the failures take longer.

On the app side this is a phone number field, a six box code field and a resend button. Everything that decides whether it works sits on a server you run and in a messaging account you pay for by the message.

So the real question is not how to build it. It is whether you can live with what comes attached. A cost on every single use. Silent failures for a slice of your users. And an account tied to a phone number somebody else can take over.

Start with what one code costs

SMS delivery is a paid third party service and the prices are public. Twilio lists outbound SMS in the United States at $0.0083 per segment, the same rate on long codes, toll-free numbers and short codes. US carriers add a pass-through fee on top, listed at $0.0035 per outbound message on AT&T and $0.0045 on T-Mobile and Verizon. A leased long code number is $1.15 a month and a toll-free number is $2.15. Figures checked in September 2026.

That puts a delivered SMS code in the United States at a little over one cent. Two thousand logins a month, with roughly one in seven people asking for a second code, is about 2,300 messages and close to thirty dollars. Small. It stops being small the hour a script starts requesting codes, because those messages are still sent and you are still billed for them. Put the rate limit on the send, not only on the check.

Two details move the number more than people expect. Messages are charged per segment, so a chatty message can cost twice a short one: send the code and almost nothing else. US application-to-person traffic on 10DLC numbers is also subject to registration onboarding fees before you can send at all. Month one is not just the per message line. Outside the United States, price and deliverability vary by country and by carrier, sometimes by a factor of ten.

Twilio, SMS pricing for the United States

Try it

What the codes cost you in a month

Twilio list prices for the United States, plus the carrier fee and one leased long code number at $1.15 a month.

$30.59 a month

2,300 messages at 1.28 cents each. Every resend, every mistyped number and every bot request adds to this line, which is why the rate limit belongs on the send and not only on the check.

What the server does between the two screens

The screens are the easy half. A phone number field, then a code field with a countdown on the resend button. None of the logic can live in the app itself. Anything shipped inside an app binary can be read by whoever downloads it, including the person trying to get past it.

The server does five things in order. It makes a random code. It stores a hash of that code against the phone number with an expiry time. It hands the message to the delivery provider. It compares what the user typed against the stored hash. Then it deletes the record and issues a session token. Two mistakes turn all of this into theatre. Storing the code in plain text, and returning the code in the API response so the app can check it itself.

Only the first of those five steps is specific to one time passwords. Everything after the code is accepted is ordinary session handling. That is the same work you would do for a password or a social sign-in. The general shape of it is covered in app authentication. Which backend runs it is a choice you make. Nothing about passwordless login on mobile decides that for you.

The rules a one time code is expected to follow

There is a written standard for this exact pattern and it is short enough to implement in a sitting. NIST Special Publication 800-63B requires the code to be at least six decimal digits, generated with an approved random bit generator. The authentication is invalid unless it is completed within 10 minutes. A given code is accepted only once inside that window, so a code that has been used is dead even if it has not expired.

Rate limiting is the rule people skip and it is the one that matters. Because a six digit code is short, the verifier has to limit consecutive failed attempts on an account. The published cap is no more than 100 before that authenticator is switched off. Generating a new code must not reset the failure count. Without that last clause an attacker simply presses resend and keeps guessing.

The same document carries the honest limit. Use of the public switched telephone network for out of band verification is restricted. Verifiers are told to weigh signals such as a device swap, a SIM change or a number port before sending a code that way. They are also told to keep an alternative sign-in method for people who cannot receive a text at all. A text proves somebody holds that SIM right now. It proves nothing else. If you are still choosing between channels rather than shipping the first one you thought of, start from app security basics.

NIST SP 800-63B, digital identity guidelines for authentication

The failures that end up in your support inbox

Some codes never arrive and the causes are boring. A mistyped digit, a landline, a carrier filter, a phone with no signal, a number ported last week. Your app looks broken and the user cannot tell a slow text from a dead one. Show the number you sent to. Put a visible countdown on the resend button. Let people fix a wrong number without starting the whole flow again.

International numbers are a separate project. Store every number in one canonical format. Ask for the country as its own field rather than hoping people type a plus sign. Then confirm your provider actually delivers to the countries your users live in. A test message to a real handset in each country is worth more than any coverage table.

One small change removes most of the remaining friction. Both platforms can offer the incoming code straight from the keyboard when the input is marked as a one time code field. In a React Native project that means textContentType set to oneTimeCode on iOS, and autoComplete set to sms-otp on Android. That is one attribute per platform and it is the highest return edit on the screen.

Last, be clear about what a verified number is not. It shows that whoever holds the SIM could read a text a moment ago. It says nothing about who the code identifies, or what that person is allowed to do once they are inside. Keep the way in and the permissions as separate layers, or the first shared family phone will teach you why.

What each way in actually costs you

Way inCost per attemptWorks on wifi aloneSurvives a SIM swapUser sets up first
SMS codeabout 1.3 cents in the USNoNonothing
Email codeemail provider rates, far lowerYesYesnothing
Magic link by emailemail provider rates, far lowerYesYesnothing
Authenticator app codenothingYesYesone QR scan
PasskeynothingYesYesone prompt

Building the app the login belongs to

A sign-in screen is never the product. What decides whether this ships is the cost of everything around it. That is the argument for describing the app in plain English and letting a builder write the project.

Newly is an AI app builder. You describe the app you want and it writes a real React Native and Expo project you own. It runs on a cloud iPhone or Android simulator while it builds. It ships to TestFlight through your own Apple Developer account, and to Google Play internal testing. Plans are $25 a month and there is no free plan. The code leaves as a ZIP from Settings, through the CLI, or through two way GitHub sync from the Deploy tab. The login flow stays yours to change.

Two honest limits for this feature in particular. The messaging account is still yours to open and pay for, and no builder makes a text free. And the server that generates and checks the code is a decision you make, not something that arrives in the box. Settle where it lives before you start drawing screens.

Questions people ask about OTP login

A one time password login replaces the password with a short code that works once and only for a few minutes. The user gives a phone number or an email address and the server sends a code to it. Typing that code back proves the user controls the address. There is nothing for the user to remember and nothing for you to reset.

Describe the app, not just the login

Write down what happens after the code is accepted, because that is the actual product. Then build it and watch the sign-in screen run in a real project.

Start building