Passcodes overview

Our flexible one-time passcodes (OTP) can be sent via SMS, WhatsApp, or email, and allows you to use this method as the primary factor or as a two-factor authentication to strengthen security.

Types of passcodes

Passcodes type icon

SMS OTP

Build an authentication flow that texts a one-time, numeric code to your users' mobile devices, which they can then enter to log in.

Passcodes type icon

WhatsApp OTP

For reliable deliverability and an international user audience, leverage our WhatsApp OTPs.

Passcodes type icon

Email OTP

Enable seamless cross device logins across desktop and mobile with our Email OTPs.


Example apps with Passcodes

Learn more about how Stytch works and get up and running quickly using an example app. Want to dive into the products but not the code? Try out our demo app.

Backend example apps

Leverage Stytch's flexibility to control authentication from your backend.

T3 stack

OTP via email or SMS


Mobile example apps

Leverage Stytch's flexibility to control authentication from your backend.


SMS one-time passcodes

Step-by-step guides to quickly get up and running with Stytch SMS one-time passcodes.


Setting up a new auth solution with SMS

Integrate Stytch one-time passcodes as your authentication solution.

  1. Step 1: Build your UI for SMS login

    Here’s an example of an authentication flow. One screen accepts the user’s phone number and the other accepts their one-time passcode.

    Step description
    Step description
  2. Step 2: Login or create user

    The LoginOrCreateUserBySMS endpoint will be used to log in or sign up a user. This request will send a one-time passcode to the provided phone number. By default, the code will expire in 2 minutes. You can alter the expiration with the ExpirationMinutes request field. If the phone number isn’t associated with a user yet, a user will be created. If the user_created attribute in the response is true, save the user ID and phone ID from the response. We recommend saving these IDs in new columns of your users table or within a new table linking your users with their Stytch IDs.

    curl --request POST \
    	--url https://test.stytch.com/v1/otps/sms/login_or_create \
    	-u 'PROJECT_ID:SECRET' \
    	-H 'Content-Type: application/json' \
    	-d '{
    	    "phone_number": "+12025550162"
    	}'
  3. Step 3: Authenticate one-time passcode

    The AuthenticateOTP endpoint will be used in conjunction with all LoginOrCreateUserBySMS requests. The user should be prompted to enter the one-time passcode sent to them via SMS. After the user enters their code, send an AuthenticateOTP request with the code along with the phone ID used. If the response is a 200, the user is verified and can be logged in. If you'd like to keep this user logged-in for a while, include "session_duration_minutes": 60 (an hour, for example). Check out the session management guide to learn how to handle the session.

    curl --request POST \
    	--url https://test.stytch.com/v1/otps/authenticate \
    	-u 'PROJECT_ID:SECRET' \
    	-H 'Content-Type: application/json' \
    	-d '{
    	    "method_id": "phone-number-test-d5a3b680-e8a3-40c0-b815-ab79986666d0",
            "code": "123456"
    	}'

Getting started with a SDK

This guide is coming soon.


Add multi-factor authentication (MFA) with SMS

Integrate Stytch one-time passcodes (OTP) as your multi-factor authentication solution.

  1. Step 1: Build your UI for multi-factor authentication

    Here’s an example of a multi-factor authentication flow. One screen accepts the user’s phone number and the other accepts their one-time passcode.

    Step description
    Step description
  2. Step 2: Create or update user

    The user you want to authenticate needs to be a Stytch user with an associated phone number. If they are, continue to Step 3. If the user already has a Stytch ID, send a UpdateUser request to add a phone number. If they don’t, send a CreateUser request to create a user with a phone number. We recommend saving the user and phone IDs in new columns of your users table or within a new table linking your users with their Stytch IDs.

    curl --request POST \
    	--url https://test.stytch.com/v1/users \
    	-u 'PROJECT_ID:SECRET' \
    	-H 'Content-Type: application/json' \
    	-d '{
    		"phone_number": "+12025550162"
    	}'
  3. Step 3: Send one-time passcode

    Now that the phone number is associated with a Stytch user, send a SendOTPBySMS request. This will send a one-time passcode to the provided phone number. By default, the code will expire in 2 minutes. You can alter the expiration with the ExpirationMinutes request field.

    curl --request POST \
    	--url https://test.stytch.com/v1/otps/sms/send \
    	-u 'PROJECT_ID:SECRET' \
    	-H 'Content-Type: application/json' \
    	-d '{
    	    "phone_number": "+12025550162"
    	}'
  4. Step 4: Authenticate one-time passcode

    The AuthenticateOTP endpoint will be used in conjunction with all SendOTPBySMS requests. The user should be prompted to enter the one-time passcode sent to them via SMS. After the user enters their code, send a AuthenticateOTP request with the code along with the phone ID used. If the response is a 200, the user is verified and can be logged in.

    curl --request POST \
    	--url https://test.stytch.com/v1/otps/authenticate \
    	-u 'PROJECT_ID:SECRET' \
    	-H 'Content-Type: application/json' \
    	-d '{
    	    "method_id": "phone-number-test-d5a3b680-e8a3-40c0-b815-ab79986666d0",
            "code": "123456"
    	}'

Unsupported countries

Stytch does not support sending SMS passcodes to the following countries:
  • Afghanistan
  • Albania
  • Andorra
  • Angola
  • Aruba
  • Azerbaijan
  • Bahamas
  • Barbados
  • Belarus
  • Belize
  • Bermuda
  • Bhutan
  • Bosnia and Herzegovina
  • Botswana
  • British Virgin Islands
  • Burma (Myanmar)
  • Cambodia
  • Cape Verde
  • Cayman Islands
  • China – including Hong Kong
  • Congo, Dem Rep
  • Cote D’Ivoire (Ivory Coast)
  • Cuba
  • Curaçao and Caribbean Netherlands (Bonaire, Sint Eustatius, Sint Maarten, Saba)
  • Cyprus
  • Democratic Republic of Congo
  • Denmark
  • Dominica
  • Equatorial Guinea
  • Eritrea
  • Estonia
  • Faroe Islands
  • Fiji
  • French Polynesia
  • Gabon
  • Gambia
  • Gibraltar
  • Greenland
  • Guadeloupe
  • Guam
  • Guinea
  • Haiti
  • Indonesia
  • Iran
  • Iraq
  • Ivory Coast
  • Jordan
  • Korea Dem People's Rep
  • Kosovo
  • Kuwait
  • Kyrgyzstan
  • Laos PDR
  • Lebanon
  • Lesotho
  • Liberia
  • Libya
  • Macau
  • Macedonia
  • Madagascar
  • Malawi
  • Malaysia
  • Maldives
  • Mali
  • Martinque
  • Mongolia
  • Montserrat
  • Mozambique
  • Namibia
  • Nepal
  • New Caledonia
  • Niger
  • North Korea
  • Northen Mariana Islands
  • Oman
  • Pakistan
  • Palestine
  • Papua New Guinea
  • Philippines
  • Republic of North Macedonia
  • Reunion/Mayotte
  • Russia
  • Rwanda
  • Senegal
  • Serbia
  • Sierra Leone
  • Solomon Islands
  • Somalia
  • Sri Lanka
  • St Vincent Grenadines
  • Sudan
  • Sweden
  • Syria
  • Tajikistan
  • Thailand
  • Turkmenistan
  • Turks and Caicos Islands
  • U.S. Virgin Islands
  • Uganda
  • Uzbekistan
  • Venezuela
  • Vietnam
  • Yemen
  • Zimbabwe

If you attempt to send an SMS to an international code which corresponds with a country listed above the API will return an invalid_phone_number_country_code error. Please reach out to support@stytch.com if you have any questions.