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

# OAuth overview

> Authenticate users with OAuth providers using the Stytch API

OAuth (also known as Social Login) allows users to authenticate using their existing accounts with providers like Google, Microsoft, GitHub, and more. The OAuth flow involves redirecting users to the provider, who then redirects back to your application with a token that confirms their identity.

## Implement OAuth

<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="Start the OAuth flow">
        Redirect the user to start the OAuth flow. This must be done in the browser:

        **Example URL (Google):**

        ```
        https://test.stytch.com/v1/b2b/public/oauth/google/discovery/start?public_token=YOUR_PUBLIC_TOKEN&discovery_redirect_url=https://yourapp.com/authenticate
        ```

        **Query parameters:**

        * `public_token`: Your Stytch public token
        * `discovery_redirect_url`: Where to redirect after OAuth completes

        **Supported providers:**

        * Google: `/oauth/google/discovery/start`
        * Microsoft: `/oauth/microsoft/discovery/start`
        * GitHub: `/oauth/github/discovery/start`
        * Slack: `/oauth/slack/discovery/start`
        * HubSpot: `/oauth/hubspot/discovery/start`

        The user will authenticate with the provider and be redirected back to your `discovery_redirect_url` with a `token` query parameter.
      </Step>

      <Step title="Authenticate the OAuth token">
        After the redirect, exchange the OAuth token for an intermediate session:

        ```bash theme={null}
        curl --request POST \
          --url https://test.stytch.com/v1/b2b/oauth/discovery/authenticate \
          --header 'Content-Type: application/json' \
          --user 'PROJECT_ID:SECRET' \
          --data '{
            "discovery_oauth_token": "hdPVZHHX0UoRa7hJTuuPHi1vlddffSnoweRbVFf5-H8g"
          }'
        ```

        **Parameters:**

        * `discovery_oauth_token`: The token from the redirect URL query parameter

        **Response:**

        ```json theme={null}
        {
          "status_code": 200,
          "request_id": "request-id-test-...",
          "intermediate_session_token": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
          "email_address": "user@example.com",
          "full_name": "Jane Doe",
          "provider_type": "Google",
          "provider_tenant_id": "1234567",
          "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="Start the OAuth flow">
        Redirect the user to start the OAuth flow for a specific organization. This must be done in the browser:

        **Example URL (Google):**

        ```
        https://test.stytch.com/v1/b2b/public/oauth/google/start?public_token=YOUR_PUBLIC_TOKEN&organization_id=organization-test-...&login_redirect_url=https://acme.yourapp.com/authenticate&signup_redirect_url=https://acme.yourapp.com/authenticate
        ```

        **Query parameters:**

        * `public_token`: Your Stytch public token
        * `organization_id`: The organization's ID (either this or `slug` required)
        * `slug`: The organization's slug (alternative to `organization_id`)
        * `login_redirect_url`: Where to redirect existing members
        * `signup_redirect_url`: Where to redirect new members

        **Supported providers:**

        * Google: `/oauth/google/start`
        * Microsoft: `/oauth/microsoft/start`
        * GitHub: `/oauth/github/start`
        * Slack: `/oauth/slack/start`
        * HubSpot: `/oauth/hubspot/start`

        The user will authenticate with the provider and be redirected back with a `token` query parameter.
      </Step>

      <Step title="Authenticate the OAuth token">
        After the redirect, exchange the OAuth token for a session:

        ```bash theme={null}
        curl --request POST \
          --url https://test.stytch.com/v1/b2b/oauth/authenticate \
          --header 'Content-Type: application/json' \
          --user 'PROJECT_ID:SECRET' \
          --data '{
            "oauth_token": "hdPVZHHX0UoRa7hJTuuPHi1vlddffSnoweRbVFf5-H8g",
            "session_duration_minutes": 60
          }'
        ```

        **Parameters:**

        * `oauth_token`: The token from the redirect URL query parameter
        * `session_duration_minutes`: (Optional) Session lifetime in minutes (default: 60)

        **Response:**

        ```json theme={null}
        {
          "status_code": 200,
          "request_id": "request-id-test-...",
          "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,
          "provider_type": "Google",
          "provider_subject": "10769150350006150715113082367",
          "provider_values": {
            "access_token": "example-access-token",
            "refresh_token": "example-refresh-token",
            "id_token": "example-id-token",
            "scopes": ["openid", "email", "profile"]
          },
          "member": { /* member object */ },
          "organization": { /* organization object */ },
          "member_session": { /* session object */ }
        }
        ```
      </Step>

      <Step title="Use the session">
        Store the `session_token` or `session_jwt` to authenticate future API requests. The `provider_values` object includes OAuth tokens you can use to call the provider's APIs on behalf of the user.
      </Step>
    </Steps>

    <Note>
      If MFA is required or the OAuth provider doesn't verify email, `member_authenticated` will be `false` and an `intermediate_session_token` will be returned. Complete the required authentication step to get a full session.
    </Note>
  </Tab>
</Tabs>

## OAuth scopes

By default, Stytch requests basic scopes (email, profile) from OAuth providers. You can request additional scopes using the `custom_scopes` parameter:

**Example with custom scopes:**

```
...&custom_scopes=https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/drive.readonly
```

Refer to each provider's documentation for available scopes:

* [Google OAuth scopes](https://developers.google.com/identity/protocols/oauth2/scopes)
* [Microsoft Graph permissions](https://learn.microsoft.com/en-us/graph/permissions-reference)
* [GitHub OAuth scopes](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps)

## Provider parameters

You can pass provider-specific parameters by prefixing them with `provider_`:

**Example:**

```
...&provider_login_hint=user@example.com&provider_prompt=consent
```

## Supported providers

<CardGroup cols={3}>
  <Card title="Google" icon="google" />

  <Card title="Microsoft" icon="microsoft" />

  <Card title="GitHub" icon="github" />

  <Card title="Slack" icon="slack" />

  <Card title="HubSpot" icon="shield" />
</CardGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="OAuth guide" icon="book" href="/docs/multi-tenant-auth/authentication/oauth/overview">
    Read the OAuth integration guide
  </Card>

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