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

# Sessions overview

> Manage Member sessions with the Stytch Sessions API

Sessions represent an authenticated user's active login to an Organization. After a user successfully authenticates, Stytch creates a Session and returns both a `session_token` and `session_jwt` that you can use to authorize requests.

Sessions have a configurable lifetime (default: 60 minutes) and can be extended by re-authenticating them before they expire. Sessions contain authentication factors and can be revoked at any time.

## Common operations

<Tabs>
  <Tab title="Authenticate Session" icon="shield-check">
    Validate a session and optionally extend its lifetime. Use this to authorize requests in your application.

    <Steps>
      <Step title="Authenticate with session token">
        ```bash theme={null}
        curl --request POST \
          --url https://test.stytch.com/v1/b2b/sessions/authenticate \
          --header 'Content-Type: application/json' \
          --user 'PROJECT_ID:SECRET' \
          --data '{
            "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
            "session_duration_minutes": 60
          }'
        ```

        **Parameters:**

        * `session_token`: The session token to validate (use either this or `session_jwt`)
        * `session_jwt`: Alternative to `session_token` - the JWT to validate
        * `session_duration_minutes`: (Optional) Extend session lifetime by this many minutes
        * `session_custom_claims`: (Optional) Custom claims to add to the session JWT
        * `authorization_check`: (Optional) Check RBAC permissions during authentication

        **Response:**

        ```json theme={null}
        {
          "status_code": 200,
          "request_id": "request-id-test-...",
          "member_session": {
            "member_session_id": "member-session-test-...",
            "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
            "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
            "started_at": "2024-01-01T00:00:00Z",
            "last_accessed_at": "2024-01-01T01:00:00Z",
            "expires_at": "2024-01-01T02:00:00Z",
            "authentication_factors": [
              {
                "type": "magic_link",
                "delivery_method": "email",
                "email_factor": {
                  "email_id": "email-test-...",
                  "email_address": "user@example.com"
                }
              }
            ]
          },
          "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
          "session_jwt": "eyJhbGc...",
          "member": { /* member object */ },
          "organization": { /* organization object */ }
        }
        ```
      </Step>

      <Step title="Use for request authorization">
        Store the `session_token` or `session_jwt` and include it in subsequent requests to verify the user is authenticated. Call the authenticate endpoint on each request or periodically to validate the session is still active.
      </Step>
    </Steps>

    <Note>
      You can pass an expired JWT (based on its `exp` claim) and receive a new JWT if the underlying Session is still valid.
    </Note>
  </Tab>

  <Tab title="Revoke Session" icon="circle-x">
    Immediately invalidate a session and all its tokens. Use this to implement logout functionality.

    <Steps>
      <Step title="Revoke a specific session">
        ```bash theme={null}
        curl --request POST \
          --url https://test.stytch.com/v1/b2b/sessions/revoke \
          --header 'Content-Type: application/json' \
          --user 'PROJECT_ID:SECRET' \
          --data '{
            "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q"
          }'
        ```

        **Parameters (one required):**

        * `session_token`: The session token to revoke
        * `session_jwt`: Alternative - the session JWT to revoke
        * `member_session_id`: Alternative - the session ID to revoke
        * `member_id`: Revoke ALL sessions for this member

        **Response:**

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

      <Step title="Revoke all member sessions">
        To log a user out of all devices, pass the `member_id`:

        ```bash theme={null}
        curl --request POST \
          --url https://test.stytch.com/v1/b2b/sessions/revoke \
          --header 'Content-Type: application/json' \
          --user 'PROJECT_ID:SECRET' \
          --data '{
            "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f"
          }'
        ```
      </Step>
    </Steps>

    <Warning>
      Revoking a session immediately invalidates all tokens. Users will need to re-authenticate.
    </Warning>
  </Tab>

  <Tab title="Get Sessions" icon="list">
    Retrieve all active sessions for a member.

    <Steps>
      <Step title="List member sessions">
        ```bash theme={null}
        curl --request GET \
          --url 'https://test.stytch.com/v1/b2b/sessions?organization_id=organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931&member_id=member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f' \
          --user 'PROJECT_ID:SECRET'
        ```

        **Query parameters:**

        * `organization_id`: The organization's ID (required)
        * `member_id`: The member's ID (required)

        **Response:**

        ```json theme={null}
        {
          "status_code": 200,
          "request_id": "request-id-test-...",
          "member_sessions": [
            {
              "member_session_id": "member-session-test-...",
              "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
              "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
              "started_at": "2024-01-01T00:00:00Z",
              "last_accessed_at": "2024-01-01T01:00:00Z",
              "expires_at": "2024-01-01T02:00:00Z",
              "authentication_factors": [
                {
                  "type": "magic_link",
                  "delivery_method": "email",
                  "email_factor": {
                    "email_id": "email-test-...",
                    "email_address": "user@example.com"
                  }
                }
              ]
            }
          ]
        }
        ```
      </Step>
    </Steps>

    <Note>
      This endpoint only returns active (non-expired, non-revoked) sessions.
    </Note>
  </Tab>

  <Tab title="Exchange Intermediate Session" icon="arrows-right-left">
    Convert an intermediate session token (from Discovery flow) into a full session for a specific organization.

    <Steps>
      <Step title="Exchange the token">
        After a user completes Discovery authentication and selects an organization, exchange their intermediate 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-07971b06-ac8b-4cdb-9c15-63b17e653931",
            "session_duration_minutes": 60
          }'
        ```

        **Parameters:**

        * `intermediate_session_token`: The intermediate token to exchange (required)
        * `organization_id`: The organization to create a session for (required)
        * `session_duration_minutes`: (Optional) Session lifetime in minutes (default: 60)
        * `session_custom_claims`: (Optional) Custom claims for the session JWT

        **Response:**

        ```json theme={null}
        {
          "status_code": 200,
          "request_id": "request-id-test-...",
          "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
          "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
          "session_jwt": "eyJhbGc...",
          "member_authenticated": true,
          "member_session": { /* session object */ },
          "member": { /* member object */ },
          "organization": { /* organization object */ }
        }
        ```
      </Step>

      <Step title="Handle incomplete authentication">
        If the user hasn't satisfied all authentication requirements, `member_authenticated` will be `false`:

        * Check `primary_required` for required primary auth methods
        * Check `mfa_required` for required MFA methods
        * Complete the required authentication with the intermediate token
      </Step>
    </Steps>

    <Note>
      Intermediate session tokens are valid for 10 minutes and are used in Discovery flows to allow users to select which organization to log into.
    </Note>
  </Tab>
</Tabs>

## Session tokens vs JWTs

Stytch provides two token formats for sessions:

<CardGroup cols={2}>
  <Card title="Session Tokens" icon="key">
    **Opaque tokens** that must be validated server-side via the authenticate endpoint.

    * More secure (can't be decoded)
    * Requires API call to validate
    * Can be revoked immediately
  </Card>

  <Card title="Session JWTs" icon="file-code">
    **JSON Web Tokens** that can be validated locally using your project's public key.

    * Can validate without API calls
    * Contains claims (member ID, org ID, etc.)
    * Slightly delayed revocation (until JWT expires)
  </Card>
</CardGroup>

## Authentication factors

Sessions track which authentication methods were used. Common factors include:

* **Magic Links** - Email-based authentication
* **OAuth** - Social login (Google, Microsoft, etc.)
* **OTP** - One-time passcodes via email or SMS
* **SSO** - SAML or OIDC connections
* **Passwords** - Traditional password authentication
* **TOTP** - Authenticator app codes
* **WebAuthn** - Biometric or security key authentication

## RBAC authorization checks

You can combine session authentication with RBAC permission checks:

```bash theme={null}
curl --request POST \
  --url https://test.stytch.com/v1/b2b/sessions/authenticate \
  --header 'Content-Type: application/json' \
  --user 'PROJECT_ID:SECRET' \
  --data '{
    "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
    "authorization_check": {
      "organization_id": "organization-test-...",
      "resource_id": "documents",
      "action": "delete"
    }
  }'
```

If the member lacks permission, the API returns a 403 error. Otherwise, the response includes which roles satisfied the authorization.

## Next steps

<CardGroup cols={2}>
  <Card title="Session management guide" icon="book" href="/docs/multi-tenant-auth/manage-sessions">
    Comprehensive session documentation
  </Card>

  <Card title="RBAC" icon="user-lock" href="/docs/multi-tenant-auth/enterprise-ready/rbac">
    Implement role-based access control with sessions
  </Card>
</CardGroup>
