> ## Documentation Index
> Fetch the complete documentation index at: https://stytch.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrate TOTPs via the API

> Implement TOTP enrollment and verification with the Consumer API.

Time-based one-time passcodes (TOTP) provide a second factor using a shared secret with an authenticator app. Users enter a time-based code (typically 30 seconds), and your backend verifies it with Stytch.

<Steps>
  <Step title="Create a Stytch User">
    If the user isn't already associated with a Stytch `user_id`, create a User with the `/users/create` endpoint. Store the returned `user_id` so you can enroll and authenticate the user with TOTP.

    ```js theme={null}
    const stytch = require("stytch")

    const client = new stytch.Client({
        project_id: "PROJECT_ID",
        secret: "SECRET",
        env: stytch.envs.test,
      }
    );

    const params = {
        email: "sandbox@stytch.com",
    };
    client.users.create(params)
        .then(resp => {
            console.log(resp)
        })
        .catch(err => {
            console.log(err)
        });
    ```
  </Step>

  <Step title="Create a TOTP for the user">
    Create a TOTP by passing the `user_id` into `/totps/create`. The `expiration_minutes` value sets how long the enrollment is valid; the user must authenticate at least once before it expires.

    The response includes `secret`, `totp_id`, `qr_code`, and `recovery_codes`. You can embed the `qr_code` to display a scannable QR code, and store recovery codes for account recovery.

    ```js theme={null}
    const stytch = require("stytch")

    const client = new stytch.Client({
        project_id: "PROJECT_ID",
        secret: "SECRET",
        env: stytch.envs.test,
      }
    );

    const params = {
        user_id: "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
        expiration_minutes: 60
    };
    client.totps.create(params)
        .then(resp => { console.log(resp) })
        .catch(err => { console.log(err) });
    ```
  </Step>

  <Step title="Authenticate a TOTP code">
    Prompt the user to enter a TOTP code, then call `/totps/authenticate` with the `user_id` and `totp_code`. This endpoint allows codes from the previous and next 30-second windows to accommodate delays.

    You can optionally pass `session_duration_minutes` (new session) or `session_token` (reuse session). See the [session management guide](/consumer-auth/manage-sessions/overview) for more details.

    ```js theme={null}
    const stytch = require("stytch")

    const client = new stytch.Client({
        project_id: "PROJECT_ID",
        secret: "SECRET",
        env: stytch.envs.test,
      }
    );

    const params = {
        user_id: "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
        totp_code: "576831"
    };
    client.totps.authenticate(params)
        .then(resp => { console.log(resp) })
        .catch(err => { console.log(err) });
    ```
  </Step>

  <Step title="You're done">
    You now have a second factor of authentication via TOTP. Have feedback after integrating? Reach out in our [forum](https://stytch.com/web/discourse), via [support@stytch.com](mailto:support@stytch.com), or in our [community Slack](https://join.slack.com/t/stytch/shared%5Finvite/zt-3aqo03e10-afWXyF%5F~zHw).
  </Step>
</Steps>
