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

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.


Method parameters


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


Method parameters


totp_code*string

session_duration_minutes*int
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",
    "totp_id": "totp-test-41920359-8bbb-4fe8-8fa3-aaa83f35f02c",
    "session": null,
    "session_jwt": "",
    "session_token": "",
    "user": {...},
    "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6"
  }

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.

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


Method parameters


recovery_code*string

session_duration_minutes*int
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": null,
    "session_jwt": "",
    "session_token": "",
    "totp_id": "totp-test-41920359-8bbb-4fe8-8fa3-aaa83f35f02c"
    "user": {...},
    "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
  }