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 (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
Discovery flow
Organization flow
The Discovery flow is designed for centralized login pages where users authenticate before selecting which Organization to access.
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.
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" : {}
}
}
]
}
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.
The Organization flow is for organization-specific login pages where the organization context is already known (e.g., acme.yourapp.com).
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.
Authenticate the OAuth token
After the redirect, exchange the OAuth token for a session: 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: {
"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 */ }
}
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.
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.
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
Next steps
OAuth guide Read the OAuth integration guide
Sessions Learn about session management