One-time passcodes

One-time passcodes can be sent via email, phone number, or WhatsApp. One-time passcodes allow for a quick and seamless login experience on their own, or can layer on top of another login product like Email magic links to provide extra security as a multi-factor authentication (MFA) method.

Methods

To call these methods, One-time passcodes must be enabled in the SDK Configuration page of the Stytch dashboard.

Login or create via SMS


Method parameters


phone_number*string

Configurationobject

Additional configuration.

expiration_minutesint
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';
export const Login = () => {
  const stytchClient = useStytch();
  const sendPasscode = useCallback(() => {
    stytchClient.otps.sms.loginOrCreate('+12025550162', {
      expiration_minutes: 5,
    });
  }, [stytchClient]);
  return <button onClick={sendPasscode}>Send passcode</button>;
};

RESPONSE

200
{
      "status_code": 200,
      "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
      "method_id": "phone-number-test-d5a3b680-e8a3-40c0-b815-ab79986666d0"
    }

Send via SMS

Wraps Stytch's send via SMS API endpoint. Call this method to send an SMS passcode to existing users.

This method is also used when you need to add a phone number to an existing Stytch User. If there is a currently valid Stytch session, and the user inputs a phone number that does not match one on their Stytch User object, upon successful authentication the new phone number will be added to the existing user. Note, this does expose a potential account enumeration vector, see our article on preventing account enumeration for more details.

Cost to send SMS OTP

Before configuring SMS or WhatsApp OTPs, please review how Stytch bills the costs of international OTPs and understand how to protect your app against toll fraud.


Method parameters


phone_number*string

Configurationobject

Additional configuration.

expiration_minutesint
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';
export const Login = () => {
  const stytchClient = useStytch();
  const sendPasscode = useCallback(() => {
    stytchClient.otps.sms.send('+12025550162', {
      expiration_minutes: 5,
    });
  }, [stytchClient]);
  return <button onClick={sendPasscode}>Send passcode</button>;
};

RESPONSE

200
{
    "status_code": 200,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "method_id": "phone-number-test-d5a3b680-e8a3-40c0-b815-ab79986666d0"
  }

Login or create via email

Wraps Stytch's login_or_create via email API endpoint. Call this method to send an email passcode to new or existing users.


Method parameters


email*string

Configurationobject

Additional configuration.

expiration_minutesint
login_template_idstring
signup_template_idstring
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';
export const Login = () => {
  const stytchClient = useStytch();
  const sendPasscode = useCallback(() => {
    stytchClient.otps.email.loginOrCreate('sandbox@stytch.com', {
      expiration_minutes: 5,
    });
  }, [stytchClient]);
  return <button onClick={sendPasscode}>Send passcode</button>;
};

RESPONSE

200
{
    "status_code": 200,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "method_id": "email-test-81bf03a8-86e1-4d95-bd44-bb3495224953"
  }

Send via email

Wraps Stytch's send via email API endpoint. Call this method to send an email passcode to existing users.

This method is also used when you need to add a phone number to an existing Stytch User. If there is a currently valid Stytch session, and the user inputs a phone number that does not match one on their Stytch User object, upon successful authentication the new phone number will be added to the existing user. Note, this does expose a potential account enumeration vector, see our article on preventing account enumeration for more details.


Method parameters


email*string

Configurationobject

Additional configuration.

expiration_minutesint
login_template_idstring
signup_template_idstring
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';
export const Login = () => {
  const stytchClient = useStytch();
  const sendPasscode = useCallback(() => {
    stytchClient.otps.email.send('sandbox@stytch.com', {
      expiration_minutes: 5,
    });
  }, [stytchClient]);
  return <button onClick={sendPasscode}>Send passcode</button>;
};

RESPONSE

200
{
    "status_code": 200,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "method_id": "email-test-81bf03a8-86e1-4d95-bd44-bb3495224953"
  }

Login or create via WhatsApp

Wraps Stytch's login_or_create via WhatsApp API endpoint. Call this method to send an WhatsApp passcode to new or existing users.

Cost to send SMS OTP

Before configuring SMS or WhatsApp OTPs, please review how Stytch bills the costs of international OTPs and understand how to protect your app against toll fraud.


Method parameters


phone_number*string

Configurationobject

Additional configuration.

expiration_minutesint
import { useStytch } from '@stytch/react';
export const Login = () => {
  const stytchClient = useStytch();
  const sendPasscode = useCallback(() => {
    stytchClient.otps.whatsapp.loginOrCreate('+12025550162', {
      expiration_minutes: 5,
    });
  }, [stytchClient]);
  return <button onClick={sendPasscode}>Send passcode</button>;
};

RESPONSE

200
{
    "status_code": 200,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "method_id": "phone-number-test-d5a3b680-e8a3-40c0-b815-ab79986666d0"
  }

Send via WhatsApp

Wraps Stytch's send via WhatsApp API endpoint. Call this method to send an WhatsApp passcode to existing users.

This method is also used when you need to add a phone number to an existing Stytch User. If there is a currently valid Stytch session, and the user inputs a phone number that does not match one on their Stytch User object, upon successful authentication the new phone number will be added to the existing user. Note, this does expose a potential account enumeration vector, see our article on preventing account enumeration for more details.

Cost to send SMS OTP

Before configuring SMS or WhatsApp OTPs, please review how Stytch bills the costs of international OTPs and understand how to protect your app against toll fraud.


Method parameters


phone_number*string

Configurationobject

Additional configuration.

expiration_minutesint
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';
export const Login = () => {
  const stytchClient = useStytch();
  const sendPasscode = useCallback(() => {
    stytchClient.otps.whatsapp.send('+12025550162', {
      expiration_minutes: 5,
    });
  }, [stytchClient]);
  return <button onClick={sendPasscode}>Send passcode</button>;
};

RESPONSE

200
{
    "status_code": 200,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "method_id": "phone-number-test-d5a3b680-e8a3-40c0-b815-ab79986666d0"
  }

Authenticate

The Authenticate method wraps the authenticate one-time passcode API method which validates the code passed in.

If this method succeeds, the user will be logged in, granted an active session, and the session cookies will be minted and stored in the browser.

You can listen for successful login events anywhere in the codebase with the stytch.session.onChange() method or useStytchSession hook if you are using React.


Method parameters


method_id*string

code*string

Configuration*object

Additional configuration.

session_duration_minutes*int
import React, { useCallback, useState } from 'react';
import { useStytch } from '@stytch/react';

export const Authenticate = () => {
  const stytchClient = useStytch();
  const [code, setCode] = useState('');

  const method_id = 'phone-number-test-d5a3b680-e8a3-40c0-b815-ab79986666d0';
  // returned from calling loginOrCreate for OTPs on SMS, WhatsApp or Email

  const authenticate = useCallback(
    (e) => {
      e.preventDefault();
      stytchClient.otps.authenticate(code, method_id, {
        session_duration_minutes: 60,
      });
    },
    [stytchClient, code],
  );

  const handleChange = useCallback((e) => {
    setCode(e.target.value);
  }, []);

  return (
    <form>
      <label for="otp-input">Enter code</label>
      <input id="otp-input" autocomplete="one-time-code" inputtype="numeric" pattern="[0-9]*" onChange={handleChange} />
      <button onClick={authenticate} type="submit">
        Submit
      </button>
    </form>
  );
};

RESPONSE

200
{
    "status_code": 200,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
    "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
    "session_jwt": "eyJ...",
    "session": {...},
    "method_id": "phone-number-test-d5a3b680-e8a3-40c0-b815-ab79986666d0",
  }

UI components

The SDK also comes with a pre-built UI component for our Email Magic Links product. It wraps our login_or_create Email Magic Link API endpoint, which finds an existing user or creates a new user and sends them a magic link via email.

To add Email Magic Links to the login UI, add SDKProductTypes.emailMagicLinks to the products array in the configuration and the appropriate emailMagicLinksOptions.

To see all authentication and customization options, see the UI config section below.

import React from 'react';
import { Products } from '@stytch/vanilla-js';
import { StytchLogin } from '@stytch/react';

const config = {
  emailMagicLinksOptions: {
    loginExpirationMinutes: 30,
    loginRedirectURL: 'https://example.com/authenticate',
    signupExpirationMinutes: 30,
    signupRedirectURL: 'https://example.com/authenticate',
  },
  products: [Products.emailMagicLinks],
};

export const Login = () => {
  return <StytchLogin config={config} />;
};