JavaScript SDK

The JavaScript SDK provides a customizable pre-built login form to start a login flow, along with methods that communicate directly with the Stytch API. These help you get up and running with Stytch faster by avoiding the struggles associated with creating a login UI and removing the need to create endpoints on your backend to make requests to Stytch.

Compatibility and requirements

Languages

The SDK is available in vanilla Javascript along with specialized versions for React and Next.

Browsers

  • Chrome and Safari on all platforms
  • Firefox on desktop platforms
  • TLS 1.2 must be supported by the browser

Supported authentication products

  • Email magic links
  • One-time passcodes
  • OAuth
  • WebAuthn
  • TOTPs
  • Crypto wallets
  • Session management
  • User management
  • Passwords


Installation

Install the @stytch/vanilla-js, @stytch/react packages via npm or yarn.

npm install @stytch/vanilla-js @stytch/stytch-react --save

Initialize the SDK with the StytchUIClient constructor provided in the vanilla-js package.

Example

import { StytchProvider } from '@stytch/react';
import { StytchUIClient } from '@stytch/vanilla-js';

const stytch = new StytchUIClient('PUBLIC_TOKEN');

// Wrap your App in the StytchProvider
ReactDOM.render(
  <StytchProvider stytch={stytch}>
    <App />
  </StytchProvider>,
  document.getElementById('root'),
);

Example apps

Demo app

React app that shows all the functionality available in the SDK


HTML + Express.js

Email magic links using stytch.js


React + Express.js

Email magic links using stytch-react


Next.js

Email magic links, OAuth, SMS OTP, and more using stytch-react


UI customization

The JavaScript SDK provides the option for you to use pre-built login flows.

Customize on AuthKitUI config reference
UI customization image

Guides

If you are new to Stytch, the step-by-step guides below will walk you through the process from creating a project with Stytch to going live.



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

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

Method parameters


phone_number*string

The phone number of the user to send a one-time passcode.The phone number should be in E.164 format (i.e. +1XXXXXXXXXX). You may use +10000000000 to test this endpoint, see Testing for more detail.


Configurationobject

Additional configuration.

Collapse


expiration_minutesint

Set the expiration for the one-time passcode, in minutes. The minimum expiration is 1 minute and the maximum is 10 minutes. The default expiration is 2 minutes.

Example

React
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.

Method parameters


phone_number*string

The phone number of the user to send a one-time passcode.The phone number should be in E.164 format (i.e. +1XXXXXXXXXX). You may use +10000000000 to test this endpoint, see Testing for more detail.


Configurationobject

Additional configuration.

Collapse


expiration_minutesint

Set the expiration for the one-time passcode, in minutes. The minimum expiration is 1 minute and the maximum is 10 minutes. The default expiration is 2 minutes.

Example

React
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

The email address of the user to send the one-time passcode to. You may use sandbox@stytch.com to test this endpoint, see Testing for more detail.


Configurationobject

Additional configuration.

Collapse


expiration_minutesint

Set the expiration for the one-time passcode, in minutes. The minimum expiration is 1 minute and the maximum is 10 minutes. The default expiration is 2 minutes.

Example

React
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 an email address to an existing Stytch User. If there is a currently valid Stytch session, and the user inputs an email address that does not match one on their Stytch User object, upon successful authentication the new email address 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

The email address of the user to send the one-time passcode to. You may use sandbox@stytch.com to test this endpoint, see Testing for more detail.


Configurationobject

Additional configuration.

Collapse


expiration_minutesint

Set the expiration for the one-time passcode, in minutes. The minimum expiration is 1 minute and the maximum is 10 minutes. The default expiration is 2 minutes.

Example

React
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 a WhatsApp passcode to new or existing users.

Method parameters


phone_number*string

The phone number of the user to send a one-time passcode.The phone number should be in E.164 format (i.e. +1XXXXXXXXXX). You may use +10000000000 to test this endpoint, see Testing for more detail.


Configurationobject

Additional configuration.

Collapse


expiration_minutesint

Set the expiration for the one-time passcode, in minutes. The minimum expiration is 1 minute and the maximum is 10 minutes. The default expiration is 2 minutes.

Example

React
import React, { useCallback } from 'react';
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 a 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.

Method parameters


phone_number*string

The phone number of the user to send a one-time passcode.The phone number should be in E.164 format (i.e. +1XXXXXXXXXX). You may use +10000000000 to test this endpoint, see Testing for more detail.


Configurationobject

Additional configuration.

Collapse


expiration_minutesint

Set the expiration for the one-time passcode, in minutes. The minimum expiration is 1 minute and the maximum is 10 minutes. The default expiration is 2 minutes.

Example

React
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

The ID of the method used to send a one-time passcode.


code*string

The code to authenticate.


Configuration*object

Additional configuration.

Collapse

session_duration_minutes*int

Set the session lifetime to be this many minutes from now. This will return both an opaque session_token and session_jwt for this session, which will automatically be stored in the browser cookies. The session_jwt will have a fixed lifetime of five minutes regardless of the underlying session duration, and will be automatically refreshed by the SDK in the background over time.

This value must be a minimum of 5 and may not exceed the maximum session duration minutes value set in the SDK Configuration page of the Stytch dashboard.

A successful authentication will continue to extend the session this many minutes.

Example

React
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 One-time passcode product. It uses the methods mentioned above to send passcodes to users and authenticate the passcodes they enter.

To add One-time passcodes to the login UI, add SDKProductTypes.otp to the products array in the configuration.

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

Example

React
import React from 'react';
import { Products, OTPMethods } from '@stytch/vanilla';
import { StytchLogin } from '@stytch/react';

const config = {
  products: [
    Products.otp,
  ],
  otpOptions: {
    methods: [OTPMethods.SMS],
    expirationMinutes: 10,
  }
};

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

OAuth

OAuth is a popular authentication framework that delegates authentication to an external identity provider (often shortened to IdP) like Google, Facebook, Apple, and Microsoft. A user relies on their membership from that provider to sign in instead of creating another password, and developers can enrich their users' experiences with the information shared by the providers.

The JavaScript SDK provides a pre-built UI for OAuth flows, as well as methods to start and authenticate OAuth flows that you can connect to your own UI. Use either of these approaches to quickly get up and running with OAuth.

Methods

The SDK provides methods that can be used to get the URL to start an OAuth flow and authenticate tokens in the links later.

To call these methods, OAuth must be enabled in the SDK Configuration page of the Stytch dashboard.

start

The oauth.$provider.start() methods start OAuth flows by redirecting the browser to one of Stytch's oauth start endpoints. The method will also generate a PKCE code_verifier and store it in localstorage on the device (See the PKCE OAuth guide for details). If your application is configured to use a custom subdomain with Stytch, it will be used automatically.

  • oauth.amazon.start()
  • oauth.apple.start()
  • oauth.bitbucket.start()
  • oauth.coinbase.start()
  • oauth.discord.start()
  • oauth.facebook.start()
  • oauth.github.start()
  • oauth.gitlab.start()
  • oauth.google.start()
  • oauth.linkedin.start()
  • oauth.microsoft.start()
  • oauth.slack.start()
  • oauth.twitch.start()

Method parameters


Configurationobject

Additional configuration.

Collapse


login_redirect_urlstring

The URL Stytch redirects to after the OAuth flow is completed for a user that already exists. This URL should be a route in your application which will run oauth.authenticate (see below) and finish the login.

The URL must be configured as a Login URL in the Redirect URL page. If the field is not specified, the default Login URL will be used.


signup_redirect_urlstring

The URL Stytch redirects to after the OAuth flow is completed for a user that does not yet exist. This URL should be a route in your application which will run oauth.authenticate (see below) and finish the login.

The URL must be configured as a Sign Up URL in the Redirect URL page. If the field is not specified, the default Sign Up URL will be used.


custom_scopesstring

An optional list of custom scopes that you'd like to request from the user in addition to the ones Stytch requests by default.

Example

React
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();
  
  const startOAuth = () => stytchClient.oauth.google.start({
      login_redirect_url: 'https://example.com/authenticate',
      signup_redirect_url: 'https://example.com/authenticate',
      custom_scopes: [
        'https://www.googleapis.com/auth/documents.readonly',
        'https://www.googleapis.com/auth/drive.readonly'
      ]
  });

  return (
    <button onClick={startOAuth}>
      Log in with Google
    </button>
  );
};
Authenticate

The authenticate method wraps the authenticate OAuth API endpoint which validates the OAuth token 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


token*string

The OAuth token from the token query parameter in the URL.


Configuration*object

Additional configuration.

Collapse

session_duration_minutes*int

Set the session lifetime to be this many minutes from now. This will return both an opaque session_token and session_jwt for this session, which will automatically be stored in the browser cookies. The session_jwt will have a fixed lifetime of five minutes regardless of the underlying session duration, and will be automatically refreshed by the SDK in the background over time.

This value must be a minimum of 5 and may not exceed the maximum session duration minutes value set in the SDK Configuration page of the Stytch dashboard.

A successful authentication will continue to extend the session this many minutes.

Example

React
import React, { useEffect } from 'react';
import { useStytch, useStytchSession } from '@stytch/react';

export const Authenticate = () => {
  const stytchClient = useStytch();
  const { session } = useStytchSession();

  useEffect(() => {
    if (session) {
      window.location.href = 'https://example.com/profile'
    } else {
      const token = new URLSearchParams(window.location.search).get('token');
      stytchClient.oauth.authenticate(token, {
        session_duration_minutes: 60,
      });
    }
  }, [stytchClient, session]);

  return <div>Loading</div>;
};

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": {...},
  "provider_subject": "10769150350006150715113082367",
  "provider_type": "Google"
}

UI components

Our Javascript SDK wraps our start OAuth endpoint which kicks off the OAuth flow for your users. You'll want to set up each OAuth provider in your Dashboard before using it in the SDK. The SDK supports Google, Google One Tap, Amazon, Apple, Bitbucket, Coinbase, Discord, GitHub, GitLab, Facebook, LinkedIn, Microsoft, Slack, and Twitch OAuth.

To add OAuth to the login UI, add SDKProductTypes.oauth to the products array in the configuration and the appropriate oauthOptions.

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

Example

React
import React from 'react';
import { Stytch, SDKProductTypes, OAuthProvidersTypes, OneTapPositions } from '@stytch/stytch-react';

const loginOrSignupViewConfig = {
  oauthOptions: {
    loginRedirectURL: 'https://example.com/authenticate',
    signupRedirectURL: 'https://example.com/authenticate',
    providers: [
      {
        one_tap: true,
        position: OneTapPositions.embedded,
        type: OAuthProvidersTypes.Google,
      },
      {
        type: OAuthProvidersTypes.Amazon,
      },
      {
        type: OAuthProvidersTypes.Apple,
      },
      {
        type: OAuthProvidersTypes.Bitbucket,
      },
      {
        type: OAuthProvidersTypes.Coinbase,
      },
      {
        type: OAuthProvidersTypes.Discord,
      },
      {
        type: OAuthProvidersTypes.Facebook,
        custom_scopes: ['user_photos'],
      },
      {
        type: OAuthProvidersTypes.Github,
        custom_scopes: ['gist'],
      },
      {
        type: OAuthProvidersTypes.GitLab,
      },
      {
        type: OAuthProvidersTypes.LinkedIn,
      },
      {
        type: OAuthProvidersTypes.Microsoft,
        custom_scopes: ['https://graph.microsoft.com/calendars.read'],
      },
      {
        type: OAuthProvidersTypes.Slack,
      },
      {
        type: OAuthProvidersTypes.Twitch,
      },
    ],
  },
  products: [
    SDKProductTypes.oauth,
  ],
};

export const Login = () => {
  const STYTCH_PUBLIC_TOKEN = 'PUBLIC_TOKEN';

  return (
    <div className="sign-in-container">
      <Stytch
        loginOrSignupView={loginOrSignupViewConfig}
        // Include publicToken if you're not using <StytchProvider>
        publicToken={STYTCH_PUBLIC_TOKEN}
      />
    </div>
  );
};

WebAuthn

The Web Authentication API (WebAuthn) is a specification that allows web applications on supported browsers to authenticate a user via authenticator types such as built-in device biometrics (e.g. facial recognition on mobile and fingerprint readers on desktop) or secure hardware keys (e.g. YubiKeys). While WebAuthn has many benefits, developers need to understand the API to implement it securely. Stytch's WebAuthn product simplifies the process by abstracting the implementation details of WebAuthn for developers to make it as quick as possible to implement securely.

Methods

The Stytch SDK can be used to create new WebAuthn registrations for users and authenticate existing WebAuthn registrations.

To call these methods, WebAuthn must be enabled in the SDK Configuration page of the Stytch dashboard.

Register

Wraps Stytch's register_start and register WebAuthn endpoints and the navigator.credentials web API. Call this method to prompt the user to enroll a new WebAuthn factor and save the factor in Stytch.

Call webauthn.register inside an event callback triggered by a user gesture.

You can listen for successful user updates anywhere in the codebase with the stytch.user.onChange() method or useStytchUser() hook if you are using React.

Note: If a user has enrolled another MFA method, this method will require MFA. See the Multi-factor authentication section for more details.

Method parameters


domainstring

The domain for the WebAuthn registration. Defaults to window.location.hostname.


authenticator_typestring

The requested authenticator type of the WebAuthn device. The two valid value are platform and cross-platform. If no value passed, we assume both values are allowed.

Example

React
import React, { useCallback, useEffect, useState } from 'react';
import { useStytch } from '@stytch/stytch-react';

export const Login = () => {
  const stytchClient = useStytch();

  const trigger = useCallback(() => {
    stytchClient.webauthn.register();
  }, [stytchClient]);

  return (
    <button onClick={trigger}>
      Create WebAuthn Registration
    </button>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
  "webauthn_registration_id": "webauthn-registration-test-5c44cc6a-8af7-48d6-8da7-ea821342f5a6"
}
Authenticate

Wraps Stytch's authenticate_start and authenticate WebAuthn endpoints and the navigator.credentials web API. Call this method to prompt the user to authenticate an existing WebAuthn registration. In order to use this method, the user must have already logged in with a primary Stytch authentication factor (such as OAuth, OTPs, Passwords, or Magic Links). If this method succeeds, the WebAuthn credential will be added to the user's existing session as an authentication_factor.

Call webauthn.authenticate inside an event callback triggered by a user gesture.

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


Configuration*object

Additional configuration.

Collapse

session_duration_minutes*int

Set the session lifetime to be this many minutes from now. This will return both an opaque session_token and session_jwt for this session, which will automatically be stored in the browser cookies. The session_jwt will have a fixed lifetime of five minutes regardless of the underlying session duration, and will be automatically refreshed by the SDK in the background over time.

This value must be a minimum of 5 and may not exceed the maximum session duration minutes value set in the SDK Configuration page of the Stytch dashboard.

A successful authentication will continue to extend the session this many minutes.


domainstring

The domain for the WebAuthn authentication. Defaults to window.location.hostname

Example

React
import React, { useCallback, useEffect, useState } from 'react';
import { useStytch } from '@stytch/stytch-react';

export const Login = () => {
  const stytchClient = useStytch();

  const trigger = useCallback(() => {
    stytchClient.webauthn.authenticate({
      session_duration_minutes: 60,
    });
  }, [stytchClient]);

  return (
    <button onClick={trigger}>
      Authenticate WebAuthn Registration
    </button>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
  "user": {...},
  "webauthn_registration_id": "webauthn-registration-test-5c44cc6a-8af7-48d6-8da7-ea821342f5a6",
  "session_jwt": "",
  "session_token": "",
  "session": null
}

TOTPs

Time-based One-time Passcodes (TOTPs) are one-time passcodes that are generated based on a shared secret and the current time. TOTPs are also often referred to as Authenticator Apps and are a common form of secondary authentication. Creating a Stytch instance of a TOTP for a User creates a shared secret. This secret is shared by Stytch with the end user's authenticator application of choice (e.g. Google Authenticator). The authenticator app can then generate TOTPs that are valid for a specific amount of time (generally 30 seconds). The end user inputs the TOTP and the developer can use the authenticate method to verify that the TOTP is valid.

Methods

The Stytch SDK can be used to generate new TOTP secrets for users, and authenticate existing TOTP secrets.

To call these methods, TOTPs must be enabled in the SDK Configuration page of the Stytch dashboard.

Create

Wraps Stytch's create endpoint. Call this method to create a new TOTP instance for a user. The user can use the authenticator application of their choice to scan the QR code or enter the secret.

You can listen for successful user updates anywhere in the codebase with the stytch.user.onChange() method or useStytchUser() hook if you are using React.

Note: If a user has enrolled another MFA method, this method will require MFA. See the Multi-factor authentication section for more details.


expiration_minutesint

The expiration for the TOTP instance. If the newly created TOTP is not authenticated within this time frame the TOTP will be unusable. Defaults to 60 (1 hour) with a minimum of 5 and a maximum of 1440.

Example

React
import React, { useCallback, useEffect, useState } from 'react';
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();

  const trigger = useCallback(() => {
    stytchClient.totps.create({ expiration_minutes: 60 });
  }, [ stytchClient]);

  return (
    <button onClick={trigger}>
      Create TOTP
    </button>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "secret": "BTGNX5RKJRMQWQFRQKTG34JCF6XDRHZS",
  "totp_id": "totp-test-41920359-8bbb-4fe8-8fa3-aaa83f35f02c",
  "qr_code": "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAMgAAADIEAAAAADYoy0BAAAG8ElEQVR...8EAAD//7dQP/5Y00bRAAAAAElFTkSuQmCC",
  "recovery_codes": [
    "ckss-2skx-ebow",
    "spbc-424h-usy0",
    "hi08-n5tk-lns5",
    "1n6i-l5na-8axe",
    "aduj-eufq-w6yy",
    "i4l3-dxyt-urmx",
    "ayyi-utb0-gj0s",
    "lz0m-02bi-psbx",
    "l2qm-zrk1-8ujs",
    "c2qd-k7m4-ifmc"
  ]
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
  "user": {...},
}
Authenticate

Wraps Stytch's authenticate endpoint. Call this method to authenticate a TOTP code entered by a user.

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.


totp_code*string

The TOTP code to authenticate. The TOTP code should consist of 6 digits.


session_duration_minutes*int

Set the session lifetime to be this many minutes from now. This will return both an opaque session_token and session_jwt for this session, which will automatically be stored in the browser cookies. The session_jwt will have a fixed lifetime of five minutes regardless of the underlying session duration, and will be automatically refreshed by the SDK in the background over time.

This value must be a minimum of 5 and may not exceed the maximum session duration minutes value set in the SDK Configuration page of the Stytch dashboard.

A successful authentication will continue to extend the session this many minutes.

Example

React
import React, { useCallback, useState } from 'react';
  import { useStytch } from '@stytch/react';
  
  export const Authenticate = () => {
    const stytchClient = useStytch();
    const [totpCode, setTotpCode] = useState('');
  
    const authenticate = useCallback((e) => {
      e.preventDefault();
      stytch.totps.authenticate({ totp_code: totpCode, session_duration_minutes: 60 });
    }, [stytchClient, totpCode]);
  
    const handleChange = useCallback((e) => {
      setTotpCode(e.target.value);
    }, []);
  
    return (
      <form>
        <label for="totp-input">Enter code</label>
        <input
          id="totp-input"
          value={totpCode}
          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",
  "user": {...},
  "totp_id": "totp-test-41920359-8bbb-4fe8-8fa3-aaa83f35f02c",
  "session_jwt": "",
  "session_token": "",
  "session": null
}
Get recovery codes

Wraps Stytch's recovery_codes endpoint. Call this method to retrieve the recovery codes for a TOTP instance tied to a user.

You can listen for successful user updates anywhere in the codebase with the stytch.user.onChange() method or useStytchUser() hook if you are using React.

Note: If a user has enrolled another MFA method, this method will require MFA. See the Multi-factor authentication section for more details.

Example

React
import React, { useCallback, useEffect, useState } from 'react';
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();

  const trigger = useCallback(() => {
    stytchClient.totps.recoveryCodes();
  }, [ stytchClient]);

  return (
    <button onClick={trigger}>
      Get Recovery Codes
    </button>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
  "totps": [
    {
      "totp_id": "totp-test-41920359-8bbb-4fe8-8fa3-aaa83f35f02c",
      "verified": true,
      "recovery_codes": [
        "ckss-2skx-ebow",
        "spbc-424h-usy0",
        "hi08-n5tk-lns5",
        "1n6i-l5na-8axe",
        "aduj-eufq-w6yy",
        "i4l3-dxyt-urmx",
        "ayyi-utb0-gj0s",
        "lz0m-02bi-psbx",
        "l2qm-zrk1-8ujs",
        "c2qd-k7m4-ifmc"
      ]
    }
  ]
}
Recover

Wraps Stytch's recover endpoint. Call this method to authenticate a recovery code for a TOTP instance.

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.


recovery_code*string

The recovery code to authenticate.


session_duration_minutes*int

Set the session lifetime to be this many minutes from now. This will return both an opaque session_token and session_jwt for this session, which will automatically be stored in the browser cookies. The session_jwt will have a fixed lifetime of five minutes regardless of the underlying session duration, and will be automatically refreshed by the SDK in the background over time.

This value must be a minimum of 5 and may not exceed the maximum session duration minutes value set in the SDK Configuration page of the Stytch dashboard.

A successful authentication will continue to extend the session this many minutes.

Example

React
import React, { useCallback, useState } from 'react';
  import { useStytch } from '@stytch/react';
  
  export const Authenticate = () => {
    const stytchClient = useStytch();
    const [recoveryCode, setRecoveryCode] = useState('');
  
    const recover = useCallback((e) => {
      e.preventDefault();
      stytch.totps.recover({ recovery_code: recoveryCode, session_duration_minutes: 60 });
    }, [stytchClient, recoveryCode]);
  
    const handleChange = useCallback((e) => {
      setRecoveryCode(e.target.value);
    }, []);
  
    return (
      <form>
        <label for="recovery-code-input">Enter recovery code</label>
        <input
          id="recovery-code-input"
          value={recoveryCode}
          onChange={handleChange}
        />
        <button onClick={recover} type="submit">
          Submit
        </button>
      </form>
    );
  };

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "session_jwt": "",
  "session_token": "",
  "session": null,
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
  "user": {...},
  "totp_id": "totp-test-41920359-8bbb-4fe8-8fa3-aaa83f35f02c"
}

Crypto Wallets

Crypto wallets allow users to hold digital assets, like cryptocurrencies and NFTs, and easily cryptographically authenticate themselves on a blockchain.

Methods

The SDK provides methods that can be used to authenticate a user via their crypto wallet.

To call these methods, Crypto Wallets must be enabled in the SDK configuration page of the Stytch dashboard.

Authenticate

Wraps Stytch's authenticate_start and authenticate crypto wallet endpoints. Call this methods to prompt the user to sign a challenge using their crypto wallet.

Load the challenge data first by calling cryptoWallets.authenticateStart. Pass this challenge to your user's wallet for signing.

If this method succeeds and the user is not already logged in, the user will be logged in, granted an active session, and the session cookies will be minted and stored in the browser. If the user is already logged in, the crypto wallet will be added to the user.crypto_wallets[] array and associated with user's existing session as an authentication_factor.

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.

cryptoWallet.authenticateStart parameters


crypto_wallet_type*string

The type of wallet to authenticate. Currently ethereum and solana are supported.


crypto_wallet_address*string

The address to authenticate.

cryptoWallet.authenticate parameters


crypto_wallet_type*string

The type of wallet to authenticate. Currently ethereum and solana are supported.


crypto_wallet_address*string

The address to authenticate.


signature*string

The signature from the message.


session_duration_minutes*int

Set the session lifetime to be this many minutes from now. This will return both an opaque session_token and session_jwt for this session, which will automatically be stored in the browser cookies. The session_jwt will have a fixed lifetime of five minutes regardless of the underlying session duration, and will be automatically refreshed by the SDK in the background over time.

This value must be a minimum of 5 and may not exceed the maximum session duration minutes value set in the SDK Configuration page of the Stytch dashboard.

A successful authentication will continue to extend the session this many minutes.

Example

React
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();

  const trigger = useCallback(async () => {
    /* Request user's address */
    const [crypto_wallet_address] = await ethereum.request({ 
      method: 'eth_requestAccounts',
    });
    
    /* Ask Stytch to generate a challenge for the user */
    const { challenge } = await stytchClient.cryptoWallets.authenticateStart({
      crypto_wallet_address,
      crypto_wallet_type: 'ethereum',
    });
    
    /* Ask the user to sign the challenge */
    const signature = await ethereum.request({
      method: 'personal_sign', 
      params: [challenge, crypto_wallet_address],
    });
    
    /* Send the signature back to Stytch for validation */
    await stytchClient.cryptoWallets.authenticate({
      crypto_wallet_address,
      crypto_wallet_type: 'ethereum',
      signature,
      session_duration_minutes: 60,
    });
  }, [stytchClient]);

  return (
    <button onClick={trigger}>
      Sign in with Ethereum
    </button>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
  "user": {...},
  "session_jwt": "",
  "session_token": ""
}

UI components

The SDK also comes with a pre-built UI component for our Crypto wallets product. It wraps our authenticate_start and authenticate Crypto wallet API endpoints, which finds an existing user or creates a new user and authenticates them with their wallet.

To add Crypto wallets to the login UI, add SDKProductTypes.crypto to the products array in the configuration.

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

Example

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

const config = {
  products: [
    Products.crypto,
  ],
};

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

Passwords

Stytch supports creating, storing, and authenticating password based users, as well as support for account recovery (password reset) and account deduplication with passwordless login methods.

Methods

The SDK provides methods that can be used to create and authenticate password based users.

To call these methods, Passwords must be enabled in the SDK Configuration page of the Stytch dashboard.

Create

The send method wraps the create Password API endpoint.


email*string

The email of the new user.


password*string

The password for the new user.


session_duration_minutes*int

Set the session lifetime to be this many minutes from now. This will return both an opaque session_token and session_jwt for this session, which will automatically be stored in the browser cookies. The session_jwt will have a fixed lifetime of five minutes regardless of the underlying session duration, and will be automatically refreshed by the SDK in the background over time.

This value must be a minimum of 5 and may not exceed the maximum session duration minutes value set in the SDK Configuration page of the Stytch dashboard.

A successful authentication will continue to extend the session this many minutes.

Example

React
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();

  const createPassword = useCallback(() => {
    stytchClient.passwords.create({
      email: example@domain.com,
      password: skME)rbNQ$4@e9c&,
      session_duration_minutes: 60,
    });
  }, [stytchClient]);

  return (
    <button onClick={createPassword}>
      Create Password
    </button>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
  "email_id": "email-test-81bf03a8-86e1-4d95-bd44-bb3495224953"
}
Authenticate

The authenticate method wraps the authenticate Password API endpoint. 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.


email*string

The email of the user.


password*string

The password of the user.


session_duration_minutes*int

Set the session lifetime to be this many minutes from now. This will return both an opaque session_token and session_jwt for this session, which will automatically be stored in the browser cookies. The session_jwt will have a fixed lifetime of five minutes regardless of the underlying session duration, and will be automatically refreshed by the SDK in the background over time.

This value must be a minimum of 5 and may not exceed the maximum session duration minutes value set in the SDK Configuration page of the Stytch dashboard.

A successful authentication will continue to extend the session this many minutes.

Example

React
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();

  const authenticatePassword = useCallback(() => {
    stytchClient.passwords.authenticate({
      email: example@domain.com,
      password: skME)rbNQ$4@e9c&,
      session_duration_minutes: 60,
    });
  }, [stytchClient]);

  return (
    <button onClick={authenticatePassword}>
      Authenticate Password
    </button>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6"
}
Reset By Email Start

The resetByEmailStart method wraps the reset_by_email_start Password API endpoint. 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.


email*string

The email of the user that requested the password reset.


Configurationobject

Additional configuration.

Collapse


reset_password_redirect_urlstring

The url that the user clicks from the password reset email to finish the reset password flow. This should be a url that your app receives and parses before showing your app's reset password page. After the user submits a new password to your app, it should send an API request to complete the password reset process. If this value is not passed, the default reset password redirect URL that you set in your Dashboard is used. If you have not set a default reset password redirect URL, an error is returned.


login_redirect_urlstring

The url that the user clicks from the password reset email to skip resetting their password and directly login. This should be a url that your app receives, parses, and subsequently sends an API request to the magic link authenticate endpoint to complete the login process without reseting their password. If this value is not passed, the login redirect URL that you set in your Dashboard is used. If you have not set a default login redirect URL, an error is returned.,


reset_password_expiration_minutesint

Set the expiration for the password reset, in minutes. By default, it expires in 30 minutes. The minimum expiration is 5 minutes and the maximum is 7 days (10080 mins).

Example

React
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();

  const resetPasswordStart = useCallback(() => {
    stytchClient.passwords.resetByEmailStart({
      email: example@domain.com,
    });
  }, [stytchClient]);

  return (
    <button onClick={resetPasswordStart}>
      Reset Password Start
    </button>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
  "email_id": "email-test-81bf03a8-86e1-4d95-bd44-bb3495224953"
}
Reset By Email

The resetByEmail method wraps the reset_by_email Password API endpoint. 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.


token*string

The token to authenticate.


password*string

The new password for the user.


session_duration_minutes*int

Set the session lifetime to be this many minutes from now. This will return both an opaque session_token and session_jwt for this session, which will automatically be stored in the browser cookies. The session_jwt will have a fixed lifetime of five minutes regardless of the underlying session duration, and will be automatically refreshed by the SDK in the background over time.

This value must be a minimum of 5 and may not exceed the maximum session duration minutes value set in the SDK Configuration page of the Stytch dashboard.

A successful authentication will continue to extend the session this many minutes.

Example

React
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();

  const token = new URLSearchParams(window.location.search).get('token');

  const resetPassword = useCallback(() => {
    stytchClient.passwords.resetByEmail({
      token: token,
      password: skME)rbNQ$4@e9c&,
      session_duration_minutes: 60,
    });
  }, [stytchClient, token]);

  return (
    <button onClick={resetPassword}>
      Reset Password
    </button>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6"
}
Reset By Existing Password

The resetByExistingPassword method wraps the reset_by_existing_password Password API endpoint. 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.


session_duration_minutes*int

Set the session lifetime to be this many minutes from now. This will return both an opaque session_token and session_jwt for this session, which will automatically be stored in the browser cookies. The session_jwt will have a fixed lifetime of five minutes regardless of the underlying session duration, and will be automatically refreshed by the SDK in the background over time.

This value must be a minimum of 5 and may not exceed the maximum session duration minutes value set in the SDK Configuration page of the Stytch dashboard.

A successful authentication will continue to extend the session this many minutes.

Example

React
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();

  const resetPassword = useCallback(() => {
    await stytch.passwords.resetByExistingPassword({
      existing_password: "existing_password",
      new_password: skME)rbNQ$4@e9c&,
      session_duration_minutes: 60,
    });
  }, [stytchClient]);

  return (
    <button onClick={resetPassword}>
      Reset Password
    </button>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6"
}
Reset By Session

The resetBySession method wraps the reset_by_session Password API endpoint. 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.


password*string

The new password for the user.


session_duration_minutes*int

Set the session lifetime to be this many minutes from now. This will return both an opaque session_token and session_jwt for this session, which will automatically be stored in the browser cookies. The session_jwt will have a fixed lifetime of five minutes regardless of the underlying session duration, and will be automatically refreshed by the SDK in the background over time.

This value must be a minimum of 5 and may not exceed the maximum session duration minutes value set in the SDK Configuration page of the Stytch dashboard.

A successful authentication will continue to extend the session this many minutes.

Example

React
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();

  const resetPassword = useCallback(() => {
    stytchClient.passwords.resetBySession({
      password: skME)rbNQ$4@e9c&,
      session_duration_minutes: 60,
    });
  }, [stytchClient]);

  return (
    <button onClick={resetPassword}>
      Reset Password
    </button>
  );
};

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": null
}
Strength Check

The strengthCheck method wraps the strength_check Password API endpoint. 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.


password*string

The password to strength check.


emailstring

The email associated with the password. Provide this for a more accurate strength check.

Example

React
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();

  const createPassword = useCallback(() => {
    stytchClient.passwords.strengthCheck({
      email: example@domain.com,
      password: skME)rbNQ$4@e9c&,
    });
  }, [stytchClient]);

  return (
    <button onClick={strengthCheck}>
      Strength Check
    </button>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "valid_password": true,
  "score": 4,
  "breached_password": false,
  "feedback": {
    "suggestions": [],
    "warning": ""
  }
}

UI components

The SDK also comes with a pre-built UI component for our Passwords product.

To add passwords to the login UI, add Products.passwords to the products array in the configuration and the appropriate passwordOptions.

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

Example

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

const config = {
  passwordOptions: {
    loginExpirationMinutes: 30,
    loginRedirectURL: 'https://example.com/authenticate',
    resetPasswordExpirationMinutes: 30,
    resetPasswordRedirectURL: 'https://example.com/authenticate',
  },
  products: [
    Products.passwords,
  ],
};

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

There is a separate component for the password reset flow.

The component takes in a passwordResetToken as a prop along with all props the StytchLogin component supports.

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

Example

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

const config = {
  passwordOptions: {
    loginExpirationMinutes: 30,
    loginRedirectURL: 'https://example.com/authenticate',
    resetPasswordExpirationMinutes: 30,
    resetPasswordRedirectURL: 'https://example.com/authenticate',
  },
  products: [
    Products.passwords,
  ],
};

export const ResetPassword = () => {
  const passwordResetToken = new URLSearchParams(window.location.search).get('token');
  return (
      <StytchResetPassword config={config} passwordResetToken={passwordResetToken} />  );
};

Users

Once a user has successfully logged in, the SDK can be used to view and manage that user's information, add additional authentication factors, or delete factors that are no longer used.

Methods

To call these methods, Manage user data must be enabled in the SDK Configuration page of the Stytch dashboard.

Get user

The SDK provides two methods for getting a user. The recommended approach is to use the synchronous method, user.getSync, and listen to changes with the user.onChange method.

If logged in, the user.getSync method returns the cached user object. Otherwise it returns null. This method does not refresh the user's data. The stytch-react library provides the useStytchUser hook that implements these methods for you to easily access the user and listen for changes.

The user.onChange method takes in a callback that gets called whenever the user object changes. It returns an unsubscribe method for you to call when you no longer want to listen for such changes.

The asyncronous method, user.get, wraps the get user endpoint. It fetches the user's data and refreshes the cached object if changes are detected. The Stytch SDK will invoke this method automatically in the background, so you probably won't need to call this method directly.

Example

React
import React from 'react';
import { useStytchUser } from '@stytch/react';

export const Home = () => {
  const { user } = useStytchUser();

  return user ? (
    <p>Welcome, {user.name.first_name}</p>
  ) : (
    <p>Log in to continue!</p>
  );
};
Update user

Wraps Stytch's update user endpoint. Use this method to change the user's name, untrusted metadata, and attributes.

You can listen for successful user updates anywhere in the codebase with the stytch.user.onChange() method or useStytchUser() hook if you are using React.

Note: If a user has enrolled another MFA method, this method will require MFA. See the Multi-factor authentication section for more details.

Method parameters


nameobject

The name of the user. If at least one name field is passed, all name fields will be updated.

Collapse

first_namestring

The first name of the user. Replaces an existing first name, if it exists.

middle_namestring

The middle name(s) of the user. Replaces an existing middle name, if it exists.

last_namestring

The last name of the user. Replaces an existing last name, if it exists.


untrusted_metadataobject

The untrusted_metadata field contains an arbitrary JSON object of application-specific data. Untrusted metadata can be edited by end users directly via the SDK, and cannot be used to store critical information. See the Metadata reference for complete field behavior details.

Example

React
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();

  const updateName = useCallback(() => {
    stytchClient.user.update({
      name: {
        first_name: 'Jane',
        last_name: 'Doe',
      },
      untrusted_metadata: {
        display_theme: 'DARK_MODE',
      }
    });
  }, [stytchClient]);


  return (
    <>
      <button onClick={updateName}>
        Update name
      </button>
    </>
  );
};

RESPONSE

200
{
  "emails": [
    {
      "email_id": "email-test-81bf03a8-86e1-4d95-bd44-bb3495224953",
      "email": "",
      "verified": false
    }
  ],
  "phone_numbers": [
    {
      "phone_id": "phone-number-test-d5a3b680-e8a3-40c0-b815-ab79986666d0",
      "phone_number": "+12025550162",
      "verified": false
    }
  ],
  "crypto_wallets": [
    {
      "crypto_wallet_id": "crypto-wallet-test-dbbd372e-79f8-48ea-907c-5f0755e7d328",
      "crypto_wallet_address": "0x6df2dB4Fb3DA35d241901Bd53367770BF03123f1",
      "crypto_wallet_type": "ethereum",
      "verified": true
    }
  ],
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "status_code": 200,
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
  "user": {...}
}
Delete authentication factors

Wraps Stytch's delete authentication factors family of endpoints and can be used to remove factors from a user.

These methods cannot be used to remove all factors from a user. A user must have at least one email, phone number, or OAuth provider associated with their account at all times, otherwise they will not be able to log in again.

You can listen for successful user updates anywhere in the codebase with the stytch.user.onChange() method or useStytchUser() hook if you are using React.

Note: If a user has enrolled another MFA method, this method will require MFA. See the Multi-factor authentication section for more details.

Method parameters


method_id*string

ID of the email, phone number, or WebAuthn registeration to be deleted.

Example

React
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';

export const Login = () => {
  const stytchClient = useStytch();

  const deleteEmail = useCallback(() => {
    stytchClient.user.deleteEmail('email-test-81bf03a8-86e1-4d95-bd44-bb3495224953');
  }, [stytchClient]);

  const deletePhoneNumber = useCallback(() => {
    stytchClient.user.deletePhoneNumber('phone-number-test-d5a3b680-e8a3-40c0-b815-ab79986666d0');
  }, [stytchClient]);

  const deleteWebauthnRegistration = useCallback(() => {
    stytchClient.user.deleteWebauthnRegistration('webauthn-registration-test-5c44cc6a-8af7-48d6-8da7-ea821342f5a6');
  }, [stytchClient]);


  const deleteOAuthRegistration = useCallback(() => {
    stytchClient.user.deleteOAuthRegistration('oauth-user-test-de86770c-911d-463f-80e7-f1b089cead14');
  }, [stytchClient]);


  return (
    <>
      <button onClick={deleteEmail}>
        Delete email
      </button>
      <button onClick={deletePhoneNumber}>
        Delete phone number
      </button>
      <button onClick={deleteWebauthnRegistration}>
        Delete WebAuthn registration
      </button>
      <button onClick={deleteOAuthRegistration}>
        Delete OAuth registration
      </button>
    </>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
  "user": {...}
}

Session management

The SDK may be used to check whether a user has a cached session, view the current session, refresh the session, and revoke the session. To authenticate a session on your backend, you must use either the Stytch API or a Stytch server-side library.

Methods

Get session

The SDK provides the session.getSync method to retrieve the current session. The session.onChange method can be used to listen to session changes.

If logged in, the session.getSync method returns the cached session object. Otherwise it returns null. The stytch-react library provides the useStytchSession hook that implements these methods for you to easily access the session and listen for changes.

The session.onChange method takes in a callback that gets called whenever the user object changes. It returns an unsubscribe method for you to call when you no longer want to listen for such changes.

Example

React
import React, { useEffect } from 'react';
import { useStytchSession } from '@stytch/react';

export const withMfaRequired = (Component) => (props) => {
  const { session } = useStytchSession();

  useEffect(() => {
    if (!session || session.authentication_factors.length < 2) {
      window.location.replace('/home');
    }
  }, [session]);

  if (!session || session.authentication_factors.length) {
    return null;
  }

  return <Component {...props} />;
};
Refresh session

Wraps Stytch's authenticate Session endpoint and validates that the session issued to the user is still valid. The SDK will invoke this method automatically in the background. You probably won't need to call this method directly. It's recommended to use session.getSync and session.onChange instead.

Method parameters


Configuration*object

Additional configuration.

Collapse

session_duration_minutes*int

Set the session lifetime to be this many minutes from now. This will return both an opaque session_token and session_jwt for this session, which will automatically be stored in the browser cookies. The session_jwt will have a fixed lifetime of five minutes regardless of the underlying session duration, and will be automatically refreshed by the SDK in the background over time.

This value must be a minimum of 5 and may not exceed the maximum session duration minutes value set in the SDK Configuration page of the Stytch dashboard.

A successful authentication will continue to extend the session this many minutes.

Example

React
import React, { useEffect } from 'react';
import { useStytch } from '@stytch/stytch';

export const RefreshSession = () => {
  const stytchClient = useStytch();

  useEffect(() => {
    const refresh = () => {
      if (stytchClient.session.getSync()) {
        stytchClient.session.authenticate({
          session_duration_minutes: 60,
        });
      }
    };
    // Refresh session every 50 minutes
    let interval = setInterval(refresh, 3000000);
    return () => clearInterval(interval);
  }, [stytchClient]);

  return <></>;
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "session": {
    "attributes": {
      "ip_address": "203.0.113.1",
      "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
    },
    "authentication_factors": [
      {
        "delivery_method": "email",
        "email_factor": {
          "email_address": "sandbox@stytch.com",
          "email_id": "email-test-81bf03a8-86e1-4d95-bd44-bb3495224953"
        },
        "last_authenticated_at": "2021-08-09T07:41:52Z",
        "type": "magic_link"
      }
    ],
    "custom_claims": {
      "claim1": "value1",
      "claim2": "value2",
    },
    "expires_at": "2021-08-10T07:41:52Z",
    "last_accessed_at": "2021-08-09T07:41:52Z",
    "session_id": "session-test-fe6c042b-6286-479f-8a4f-b046a6c46509",
    "started_at": "2021-08-09T07:41:52Z",
    "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
  },
  "user": {...},
  "session_jwt": "example_jwt"
  "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q"
}
Revoke session

Wraps Stytch's revoke Session endpoint and revokes the user's current session. This method should be used to log out a user.

Example

React
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react';

export const LogOutButton = () => {
  const stytchClient = useStytch();

  const logout = useCallback(() => {
    stytchClient.session.revoke();
  }, [stytchClient]);

  return (
    <button onClick={logout}>
      Log out
    </button>
  );
};

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141"
}

UI config


config*object

The config object for login or signup functionality.

Collapse

products*array

The products array allows you to specify the authentication methods that you would like to expose to your users.

The order of the products that you include here will also be the order in which they appear in the login form, with the first product specified appearing at the top of the login form.

Currently the JavaScript SDK supports our emailMagicLinksoauth, crypto and otp products.

emailMagicLinksOptions*object

The options for email magic links. This is required if emailMagicLinksis present in the products array.

Collapse

loginRedirectURL*string

The URL that will appear in your email template and accepts a token (ex: you implement 'https://example.com/authenticate?token=123' in your app and pass 'https://example.com/authenticate' as the redirect URL). This link should route to an endpoint that authenticates your user via Stytch's authenticate magic link endpoint and redirect to your app's experience for existing users.

loginExpirationMinutesint

Number of minutes the magic link is valid for.

signupRedirectURL*string

The URL that will appear in your email template and accepts a token (ex: you implement 'https://example.com/authenticate?token=123' in your app and pass 'https://example.com/authenticate' as the redirect URL). This link should route to an endpoint that authenticates your user via Stytch's authenticate magic link endpoint and redirect to your app's experience for new users.

signupExpirationMinutesint

Number of minutes the magic link is valid for.

createUserAsPendingboolean

This flag determines whether the status of a new user will be pending. Users are created with an active status by default. If this flag true, users will be saved with a pending status in Stytch's backend. An example usage of this would be to invite users.

oauthOptions*object

The options for OAuth. This is required if oauth is present in the products array.

Collapse

providers*Array<Provider>

An array of OAuth providers you wish to use. Each Provider is an object with a type key that determines the type of provider. Each Provider accepts an optional custom_scopes array of scopes that Stytch will request for your application in addition to the base set of scopes required for login. The order of the providers in the array determines the order of the rendered buttons.

Collapse

Googleobject

Adds the Google OAuth login button and Google One Tap. If you enable one_tap you must also provide a position parameter; embedded will display Google One Tap within the existing JavaScript SDK login form alongside the other configured sign-in options, floating will display the One Tap prompt in the top right corner.

If Google OAuth is the only authentication option specified and one_tap is set to floating, the normal Google OAuth login button will not appear in the SDK login form and only the floating One Tap box will be displayed.

See Stytch's UI customization for examples.

Note: If you enable Google One Tap, ensure that you've added your app or website's URL as an authorized JavaScript origin in your Google Developer dashboard. If you're using localhost, make sure to add both http://localhost and http://localhost:port (e.g http://localhost:3000). See Step 5 in your Google OAuth setup guide here.
Note: Google One Tap cannot be used to authorize additional custom scopes.

// with One Tap
{ type: 'google', one_tap: true, position: 'embedded' | 'floating' }
// with standard OAuth
{ type: 'google', custom_scopes?: ['...'] }

Microsoftobject

Adds the Microsoft OAuth start button.

{ type: 'microsoft', custom_scopes?: ['...'] }

Appleobject

Adds the Apple OAuth start button. Apple has no additional scopes that may be requested at this time.

{ type: 'apple' }

GitHubobject

Adds the GitHub OAuth start button.

{ type: 'github', custom_scopes?: ['...'] }

Gitlabobject

Adds the Gitlab OAuth start button.

{ type: 'gitlab', custom_scopes?: ['...'] }

Facebookobject

Adds the Facebook OAuth start button.

{ type: 'facebook', custom_scopes?: ['...'] }

Slackobject

Adds the Slack OAuth start button.

{ type: 'slack', custom_scopes?: ['...'] }

Discordobject

Adds the Discord OAuth start button.

{ type: 'discord', custom_scopes?: ['...'] }

Amazonobject

Adds the Amazon OAuth start button.

{ type: 'amazon', custom_scopes?: ['...'] }

Bitbucketobject

Adds the Bitbucket OAuth start button.

{ type: 'bitbucket', custom_scopes?: ['...'] }

Coinbaseobject

Adds the Coinbase OAuth start button.

{ type: 'coinbase', custom_scopes?: ['...'] }

LinkedInobject

Adds the LinkedIn OAuth start button.

{ type: 'linkedin', custom_scopes?: ['...'] }

Twitchobject

Adds the Twitch OAuth start button.

{ type: 'twitch', custom_scopes?: ['...'] }

loginRedirectURLstring

The URL that your users will redirect to after completing the OAuth authentication flow at a given OAuth provider, i.e. after the user returns from authenticating via Google.

This URL should route to an endpoint within your app that will complete the Stytch OAuth authentication flow, by hitting our oauth/authenticate endpoint.

If not specified, the user will be redirected to the default login redirect URL that you've configured in your Dashboard.

signupRedirectURLstring

The URL that your users will redirect to after completing the OAuth authentication flow at a given OAuth provider, i.e. after the user returns from authenticating via Google.

This URL should route to an endpoint within your app that will complete the Stytch OAuth authentication flow, by hitting our oauth/authenticate endpoint.

If not specified, the user will be redirected to the default sign up redirect URL that you've configured in your Dashboard.

otpOptionsobject

The options for one time passcodes. This is required if otpis present in the products array.

Collapse

methods*array

The methods array allows you to specify the authentication methods that you would like to expose to your users. The order of the products that you include here will also be the order in which they appear in the login form, with the first product specified appearing at the top of the login form. We currently support passcodes on email, sms and whatsapp

expirationMinutesint

Number of minutes the passcode is valid for.

sessionOptionsobject

The options for session management. If you are using the otp or cryptoproduct, we also create a session for users when they log in.You can access a user or session using the User or Session SDK methods.products array.

Collapse

sessionDurationMinutesint

Set the session lifetime to be this many minutes from now; minimum of 5 and a maximum of 129600 minutes (90 days). Note that a successful authentication will continue to extend the session this many minutes.

passwordOptions*object

The options for passwords. This is required if passwordsis present in the products array.

Collapse

loginRedirectURL*string

The redirect URL used in your password reset email template for users which opt to log in with a magic link opposed to resetting their password. This link should route to an endpoint that authenticates your user via Stytch's authenticate magic link endpoint and redirect to your app's experience for existing users.

loginExpirationMinutesint

Number of minutes the magic link is valid for.

resetPasswordRedirectURL*string

The redirect URL used in your password reset email template for users who opt to reset their password. This link should route to an page that lets your user reset their password via Stytch's reset password endpoint.

resetPasswordExpirationMinutesint

Number of minutes the reset password token is valid for.


stylesobject

The style object allows you to customize the look of the SDK. You can specify some of them or none at all. We'll use our defaults for the ones you don't specify. Check out the UI customization options in the SDK here.

Collapse

fontFamilystring

The font family that will apply to all text in the SDK.

hideHeaderTextboolean

When this value is false, the title and description text will not show in the SDK.

containerobject

The configuration object for the Stytch UI container.

Collapse

widthstring

The width of the SDK container.

backgroundColorstring

The background color of the SDK container.

borderColorstring

The border color of the SDK container.

borderRadiusstring

The border radius of the SDK container.

colorsobject

The configuration object for colors used in the Stytch UI components.

Collapse

primarystring

Your primary brand color. This will be applied to most of the text in the SDK.

secondarystring

Your secondary brand color. This will be applied to text disclaimers and other visual elements.

successstring

A success color to be used in visual elements.

errorstring

An error color to be used in visual elements.

buttonsobject

The configuration object for buttons in the Stytch UI component.

Collapse

primaryobject

The configuration object for primary buttons

Collapse

textColorstring

The text color of the primary button.

backgroundColorstring

The background color of the primary button.

borderColorstring

The border color of the primary button.

borderRadiusstring

The border radius of the primary button.

secondaryobject

The configuration object for secondary buttons

Collapse

textColorstring

The text color of the secondary button.

backgroundColorstring

The background color of the secondary button.

borderColorstring

The border color of the secondary button.

borderRadiusstring

The border radius of the secondary button.

logoobject

The configuration object for your custom logo.

Collapse

logoImageUrlstring

The URL of your custom logo. The image will be resized to fit a max width of 50px, and a max width of 100px.


callbacksobject

Optional callbacks that are triggered by various events in the SDK. See more details about the callbacks here.

Collapse

onEvent(data) => void

A callback function that responds to events sent from the SDK.

onError(data) => void

A callback function that responds to errors in the SDK. It is useful for debugging during development and error handling in production.

Example

React
import React from "react";
import { StytchLogin } from "@stytch/react";

const Login = () => {
  const style = {
    fontFamily: 'Arial',
  };
  
  const callbacks = {
    onEvent: ({ type, data }) => {
      if (type === 'MAGIC_LINK_LOGIN_OR_CREATE') {
        console.log("Email magic Link sent", data);
      }
    },
    onError: (data) => {
      console.log(data);
    }
  }

  const config = {
    products: ['emailMagicLinks', 'oauth'],
    emailMagicLinksOptions: {
      loginRedirectURL: "https://example.com/authenticate",
      loginExpirationMinutes: 30,
      signupRedirectURL: "https://example.com/authenticate",
      signupExpirationMinutes: 30,
    },
    oauthOptions: {
      providers: [{type: 'google', 'one_tap': true, position: 'floating'}, {type: 'microsoft'}]
    },
  };

  return (
    <div className="sign-in-container">
      <StytchLogin
        config={config}
        styles={style}
        callbacks={callbacks}
      />
    </div>
  );
};

export default Login;

CAPTCHA

CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) is a security measure that attempts to verify that a user is human and not a malicious bot. This helps protect your application against spammy sign ups and other automated bot attacks. Set up CAPTCHA in your Dashboard via our step by step guide and the SDK will protect every login according to your configured threshold. Only Google Enterprise is currently supported, but please contact us if there is a CAPTCHA provider you would like to see supported in the future!

Hiding the reCAPTCHA Badge

When Google Enterprise reCAPTHCA is configured, Google automatically displays a badge in the lower corner of the screen. This badge may be hidden with CSS as long as you include the reCAPTCHA branding visibly in the user flow. See Google's documentation for more details.

.grecaptcha-badge { visibility: hidden; }

If you are using the React SDK with Next.js, the following utility component can be used to programmatically hide the badge on a page by page basis.

import React from 'react';

export const HideRecaptchaBadge = () => (
  <style global jsx>{`
    .grecaptcha-badge {
      visibility: hidden;
    }
  `}</style>
);

Resources

Callbacks

Callbacks are optional functions for the Javascript SDK.

onEvent

A function that is called when the stytch client makes a request. The function expects an argument of an event object. The object has type and data objects.

{
  "type": "MAGIC_LINK_LOGIN_OR_CREATE",
  "data": {
    "userId": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "status_code": 200,
  }
},

onError

A function that is called when a error occurs. The function expects an argument of an StytchError object. The object has a message property.

{
  "message": "Error sending magic link",
},

Cookies & session management

Stytch will automatically save the user's session data in two cookies:

  • stytch_session that will contain the opaque session token returned from the API
  • stytch_session_jwt that will contain the session JWT returned from the API

Both cookies will be sent on every request to your backend servers. Your servers must validate either the stytch_session or stytch_session_jwt before processing the request. The session may be validated using any of our supported client libraries.

For example, if you load the SDK on https://app.mycoolsite.com we will set

  • document.cookie = "stytch_session=secret-session; domain=app.mycoolsite.com; path=/; SameSite=Lax; Secure; max-age=whenever-it-expires"
  • document.cookie = "stytch_session_jwt=eyJhxxx.xxx.xxx; domain=app.mycoolsite.com; path=/; SameSite=Lax; Secure; max-age=whenever-it-expires"

Note: If you load the SDK on localhost, we will not mark the cookie as secure.

Here is an example of validating the opaque session in Node.js / Express.

const express = require('express');
const cookieParser = require('cookie-parser');

const app = express();
app.use(cookieParser());
app.use(authenticateStytchSession);

const client = new stytch.Client({
  project_id: process.env.STYTCH_PROJECT_ID,
  secret: process.env.STYTCH_SECRET,
  env: stytch.envs.test,
});

const authenticateStytchSession = (req, res, next) => {
  return client.sessions.authenticate({
    session_token: req.cookies['stytch_session'],
  })
    .then(session => {
      req.stytchSession = session;
      return next();
    })
    .catch(next)
} ;

Heres an example of validating the JWT in Node.js / Express.

const express = require('express');
const cookieParser = require('cookie-parser');

const app = express();
app.use(cookieParser());
app.use(authenticateStytchSession);

const client = new stytch.Client({
  project_id: process.env.STYTCH_PROJECT_ID,
  secret: process.env.STYTCH_SECRET,
  env: stytch.envs.test,
});

const authenticateStytchSession = (req, res, next) => {
  return client.sessions.authenticateJwt(req.cookies['stytch_session_jwt'])
    .then(session => {
      req.stytchSession = session;
      return next();
    })
    .catch(next)
};

Migration Guide

If you are currently using the @stytch/stytch-js or @stytch/stytch-react SDKs, please upgrade to our newest SDK using the guides below.


Migrating to v0.5

Version 0.5.0 introduces an updated styles object used to customize the appearance of the SDK UI. This change introduces many new styling options, and restructures how existing styles are defined.

  • width is now container.width
  • primaryColor is now buttons.primary.backgroundColor
  • primaryTextColor is now colors.primary
  • secondaryTextColor is now colors.secondary
  • Note: that we have also added new buttons.secondary properties which you can check out here.

Values lightGrey and darkGrey do not have direct replacements. Check out all of the new properties we've added here.

Review this pull request to see what migrating our example app from 0.4 to 0.5 looked like.

SWR & caching

On first load, many websites must make a network request to determine whether a user is logged in before the site can start rendering the user interface. This slows down users' ability to interact with the application and ultimately leaves them with a sluggish experience.

Stytch JavaScript SDK embraces stale-while-revalidate (SWR) - a caching and data fetching strategy that promises faster time-to-interactivity and snappier UX. While SWR is most closely associated with React, the principles can apply to any web application.

Here's how it works:

  • The page first loads. Stytch's SDK checks cached data to determine if a user has logged in previously on the same device, and returns that data to your app immediately.
  • Stytch's SDK refreshes the user's data in the background while your app starts.
  • Your app makes requests to your backend to pull in application-specific data. Your backend validates the session stored in the request's cookies, and then completes the request.
  • In the rare case that the user's session has been terminated from another device, your backend will fail the request and return a 401 error. The Stytch SDK will also notify your app that the session is no longer valid through the useStytchUser and useStytchSession hooks or HOCs.

If a SWR approach isn't right for you, you can explicitly call stytch.user.get() to refresh the user object with a network call, and/or stytch.session.authenticate() to make sure the user is still logged in.

User privacy measures

To guard against potential misuse of the client-side library by bad actors, the SDK has a few restrictions:

  • No user data is shared with the browser until the user has logged in
  • The client may only access data for one user at a time - endpoints like search users are not available
  • Certain endpoints, such as update user, require step-up or multi-factor authentication in order to be used
  • To prevent account enumeration, login or create endpoints for one-time passcodes and magic links do not return the user_id as they would when using the direct API

The JavaScript SDK is not a complete replacement for the Stytch API - they are designed to be used together in order to create secure and low-friction login experiences. Some processes must necessarily happen on your server rather than client (for example, validating a session_token).

Multi-factor authentication

The Stytch SDK allows users to edit the verification mechanisms associated with their account (adding an email, deleting a phone number, adding a second factor method, etc.).

In order to access these routes, we require the that the user be authenticated with a secure combination of factors.

Stytch factors are split into three general groups based on what they prove:

  • Access to another online account or email address (OAuth, email magic links, email passcodes, and embeddable magic links)
  • Access to a phone number (SMS and WhatsApp passcodes)
  • Access to a dedicated 2nd factor (WebAuthn and TOTP)

In order for a session to be considered secure, it must include factors from at least two categories. For example, if a user completes a successful Email magic link flow and a successful SMS passcode flow, they will be considered securely authenticated. A user that completes an Email magic link flow + an OAuth flow with their Google account will not. In addition, at least one factor in the session must be less than an hour old.

Important: If a user does not have enough registered factors, they will always be allowed to add one.