How-to · 7 min read

How does OTP work? HOTP vs TOTP vs SMS one-time passwords

A developer’s guide to one-time passwords — how HOTP, TOTP and SMS OTP are generated and verified, their trade-offs, and when to use each.

An OTP (one-time password) is a code valid for a single login or action, then discarded. It is the second factor in most two-factor authentication (2FA) flows: something you have (the code) on top of something you know (your password). There are three common ways to produce one.

The three kinds of OTP

  • HOTP (HMAC-based, RFC 4226) — counter-based. Each code advances a counter shared between the device and the server.
  • TOTP (time-based, RFC 6238) — the authenticator-app standard. The "counter" is the current time in 30-second steps, so codes expire on their own.
  • SMS OTP — the server generates a random code and delivers it to the user's phone by SMS. No secret lives on the device.

How HOTP and TOTP are generated

Both derive the code from a shared secret with HMAC-SHA1, then truncate to 6 digits. HOTP uses a counter; TOTP uses floor(unixSeconds / 30) as that counter:

import { createHmac } from "node:crypto";

// TOTP is HOTP where the counter is the current 30-second time step.
function totp(secret, step = 30, digits = 6) {
  const counter = Math.floor(Date.now() / 1000 / step);
  const buf = Buffer.alloc(8);
  buf.writeBigInt64BE(BigInt(counter));
  const hmac = createHmac("sha1", secret).update(buf).digest();
  const offset = hmac[hmac.length - 1] & 0x0f;
  const code = (hmac.readUInt32BE(offset) & 0x7fffffff) % 10 ** digits;
  return code.toString().padStart(digits, "0");
}

The verifier runs the same computation and compares, allowing a small window for clock drift (TOTP) or counter desync (HOTP).

SMS OTP is different

With SMS OTP there is no shared secret on the device. The server generates a random code, stores a hashed copy with a short expiry, sends the plain code by SMS, and compares the hash when the user types it back. That is the flow Eveses powers on the receiving side — receive the OTP via API on a real number, no SIM.

HOTP vs TOTP vs SMS — trade-offs

HOTP TOTP SMS OTP
Based on Counter Time (30s) Random server code
Secret on device Yes Yes No
Works offline Yes Yes No
Main weakness Counter desync Clock drift SIM swap / SS7
Best for Legacy tokens Authenticator apps Onboarding, reach, no-app

When to use which

  • TOTP for app-based 2FA where users can install an authenticator.
  • SMS OTP for onboarding and the widest reach — nearly everyone has a phone and no app is needed. It is weaker against SIM-swap, so pair it with rate limiting and fraud checks for sensitive actions.
  • HOTP mainly for legacy hardware tokens.

Receiving SMS OTPs programmatically

To test or automate SMS OTP flows across countries you need a real number you can read the code from. See live pricing by country and the OTP API.


Ready to build? Create a free Eveses account, top up a wallet, and grab your API key — no KYC. See the API docs or live pricing.

FAQ

▸What does OTP mean?
OTP stands for one-time password — a code valid for a single login or action, then discarded.
▸Is OTP the same as 2FA?
OTP is one method used for two-factor authentication. 2FA combines something you know (a password) with something you have (the OTP); the OTP is the second factor.
▸What is the difference between HOTP and TOTP?
HOTP increments a counter for each code; TOTP uses the current time (a 30-second step) as the counter, so codes expire automatically. TOTP is what authenticator apps use.
▸How long is an SMS OTP valid?
Typically 5–10 minutes. The server stores a hashed copy with a short expiry and rejects the code once it lapses or is used.
▸Is SMS OTP secure?
It is convenient and widely reachable but weaker than app-based TOTP because of SIM-swap and SS7 risks. Layer rate limiting and fraud checks for sensitive actions.
Related guides