Skip to main content
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

The Discovery flow is designed for centralized login pages where users authenticate before selecting which Organization to access.
1

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

Authenticate the OAuth token

After the redirect, exchange the OAuth token for an intermediate session:
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:
{
  "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": {}
      }
    }
  ]
}
3

Exchange the intermediate session

After the user selects an organization, exchange the intermediate session token for a full session:
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:
{
  "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 */ }
}
The Discovery flow returns an intermediate_session_token which must be exchanged for a full session after the user selects their organization.

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:

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

Google

Microsoft

GitHub

Slack

HubSpot

Next steps