threshold1

SMS OTP

A 6-digit code sent by SMS, for step-up verification on an already-authenticated user. The implementation is complete and behaves exactly like email OTP in shape — read on for what it does. Sending is currently unavailable for a specific, disclosed reason covered at the end of this page.

Setup — requires an existing session

Same shape as TOTP: threshold1's identity model requires an email, not a phone number, so SMS OTP is a step-up factor attached to an already-authenticated user, not a standalone way to sign up or log in from zero.

await auth.login("user@example.com"); // establish a session first

await auth.sendSmsOtp("+14155551234"); // E.164 format
const { phone } = await auth.verifySmsOtp("123456");

sendSmsOtp() does not establish a session on its own — it enrolls (or re-verifies) the phone as a step-up factor. verifySmsOtp() confirms the code.

Real configuration values

  • Code expiry: 5 minutes.
  • Code format: 6 digits, numeric, zero-padded — identical to email OTP.
  • Lockout: 5 attempts per code, same as email OTP.
  • Rate limits, three layers: 3 sends per phone number per 10 minutes, plus a project-wide cap of 200 sends per day and 2,000 sends per 30 days. The first limit hit applies.

None of these are currently configurable.

Current status: sends fail — provider account not funded

This is a real, disclosed limitation, and it's worth being precise about what kind: this is a business/funding dependency, not an engineering gap. The SMS provider integration (Plivo) is fully implemented and requires no further code to work. Sending fails today for one reason only: the Plivo account this SDK would send through hasn't been created and funded yet, so the credentials it needs (PLIVO_AUTH_ID, PLIVO_AUTH_TOKEN, PLIVO_SENDER_ID) aren't configured for this environment. Attempting sendSmsOtp() will fail until that account exists and those credentials are set — this is expected, not a bug to report.

If you need step-up verification working today, TOTP has no such dependency and is fully available now.

Failure codes

verifySmsOtp() returns invalid_code and rate_limited, same as email OTP. See the Error Reference for details.

What's next

  • TOTP — the step-up method that's fully available today with no external dependency.