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

# Email OTP overview

> Authenticate users with Email One-Time Passcodes using the Stytch API

Email OTP (One-Time Passcode) provides a passwordless authentication method where users receive a 6-digit code via email. OTPs are valid for 10 minutes and can only be used once.

## Implement Email OTP

<Tabs>
  <Tab title="Discovery flow" icon="compass">
    The Discovery flow is designed for centralized login pages where users authenticate before selecting which Organization to access.

    <Steps>
      <Step title="Send the OTP">
        Send a one-time passcode to the user's email address:

        ```bash theme={null}
        curl --request POST \
          --url https://test.stytch.com/v1/b2b/otps/email/discovery/send \
          --header 'Content-Type: application/json' \
          --user 'PROJECT_ID:SECRET' \
          --data '{
            "email_address": "user@example.com"
          }'
        ```

        **Parameters:**

        * `email_address`: The user's email address
        * `discovery_expiration_minutes`: (Optional) Expiration time in minutes (default: 10)
        * `login_template_id`: (Optional) Custom email template ID
        * `locale`: (Optional) Language for the email (e.g., "en", "es")

        **Response:**

        ```json theme={null}
        {
          "status_code": 200,
          "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141"
        }
        ```
      </Step>

      <Step title="Authenticate the OTP">
        After the user receives and enters the code, authenticate it:

        ```bash theme={null}
        curl --request POST \
          --url https://test.stytch.com/v1/b2b/otps/email/discovery/authenticate \
          --header 'Content-Type: application/json' \
          --user 'PROJECT_ID:SECRET' \
          --data '{
            "email_address": "user@example.com",
            "code": "123456"
          }'
        ```

        **Parameters:**

        * `email_address`: The user's email address
        * `code`: The 6-digit OTP code

        **Response:**

        ```json theme={null}
        {
          "status_code": 200,
          "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
          "intermediate_session_token": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
          "email_address": "user@example.com",
          "discovered_organizations": [
            {
              "organization": {
                "organization_id": "organization-test-...",
                "organization_name": "Acme Corp",
                "organization_slug": "acme-corp"
              },
              "membership": {
                "type": "eligible_to_join_by_email_domain",
                "details": {}
              }
            }
          ]
        }
        ```
      </Step>

      <Step title="Exchange the intermediate session">
        After the user selects an organization, exchange the intermediate session token for a full session:

        ```bash theme={null}
        curl --request POST \
          --url https://test.stytch.com/v1/b2b/discovery/intermediate_sessions/exchange \
          --header 'Content-Type: application/json' \
          --user 'PROJECT_ID:SECRET' \
          --data '{
            "intermediate_session_token": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
            "organization_id": "organization-test-...",
            "session_duration_minutes": 60
          }'
        ```

        **Response:**

        ```json theme={null}
        {
          "status_code": 200,
          "request_id": "request-id-test-...",
          "member_id": "member-test-...",
          "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
          "session_jwt": "eyJhbGc...",
          "member": { /* member object */ },
          "organization": { /* organization object */ },
          "session": { /* session object */ }
        }
        ```
      </Step>
    </Steps>

    <Note>
      The Discovery flow returns an `intermediate_session_token` which must be exchanged for a full session after the user selects their organization.
    </Note>
  </Tab>

  <Tab title="Organization flow" icon="building">
    The Organization flow is for organization-specific login pages where the organization context is already known (e.g., `acme.yourapp.com`).

    <Steps>
      <Step title="Send the OTP">
        Send a one-time passcode for a specific organization:

        ```bash theme={null}
        curl --request POST \
          --url https://test.stytch.com/v1/b2b/otps/email/login_or_signup \
          --header 'Content-Type: application/json' \
          --user 'PROJECT_ID:SECRET' \
          --data '{
            "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
            "email_address": "user@example.com"
          }'
        ```

        **Parameters:**

        * `organization_id`: The organization's ID
        * `email_address`: The user's email address
        * `login_expiration_minutes`: (Optional) Expiration for existing members (default: 10)
        * `signup_expiration_minutes`: (Optional) Expiration for new members (default: 10)
        * `login_template_id`: (Optional) Custom email template for login
        * `signup_template_id`: (Optional) Custom email template for signup
        * `locale`: (Optional) Language for the email

        **Response:**

        ```json theme={null}
        {
          "status_code": 200,
          "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
          "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
          "member_created": false,
          "member": { /* member object */ },
          "organization": { /* organization object */ }
        }
        ```
      </Step>

      <Step title="Authenticate the OTP">
        After the user receives and enters the code, authenticate it:

        ```bash theme={null}
        curl --request POST \
          --url https://test.stytch.com/v1/b2b/otps/email/authenticate \
          --header 'Content-Type: application/json' \
          --user 'PROJECT_ID:SECRET' \
          --data '{
            "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
            "email_address": "user@example.com",
            "code": "123456",
            "session_duration_minutes": 60
          }'
        ```

        **Parameters:**

        * `organization_id`: The organization's ID
        * `email_address`: The user's email address
        * `code`: The 6-digit OTP code
        * `session_duration_minutes`: (Optional) Session lifetime in minutes (default: 60)
        * `session_custom_claims`: (Optional) Custom claims to add to the session JWT

        **Response:**

        ```json theme={null}
        {
          "status_code": 200,
          "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
          "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
          "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
          "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
          "session_jwt": "eyJhbGc...",
          "member_authenticated": true,
          "method_id": "member-email-test-...",
          "member": { /* member object */ },
          "organization": { /* organization object */ },
          "session": { /* session object */ }
        }
        ```
      </Step>

      <Step title="Use the session">
        Store the `session_token` or `session_jwt` to authenticate future API requests. You can validate sessions using the [session authenticate endpoint](/api-reference/b2b/api/sessions/authenticate-session).
      </Step>
    </Steps>

    <Note>
      If MFA is required for the Member, `member_authenticated` will be `false` and an `intermediate_session_token` will be returned instead. This token must be used to complete the MFA step.
    </Note>
  </Tab>
</Tabs>

## Next steps

<CardGroup cols={2}>
  <Card title="Sessions" icon="clock" href="/multi-tenant-auth/manage-sessions">
    Learn about session management
  </Card>

  <Card title="Organizations" icon="building" href="/multi-tenant-auth/data-model">
    Understand the B2B data model
  </Card>
</CardGroup>
