OAuth 2
How Tournament Suite uses OAuth 2 for organization single sign-on, and why the Data API and other developer integrations authenticate with an API key instead.
API access uses API keys, not OAuth 2
If you're integrating with the public Data API or any other developer endpoint, authenticate with a project-scoped API key sent in the x-api-key header — Tournament Suite does not issue OAuth 2 access tokens to third-party developers, and there is no client registration or token-issuance flow for the API. See Authentication for how to generate a key and which header to use, and Scopes for how API key scopes (for example read:tournaments, manage:matches) gate individual endpoints.
The rest of this page describes the one OAuth 2 flow Tournament Suite does support: signing organization members into Tournament Suite through an external identity provider.
Organization SSO with OAuth 2
An organization can configure one or more OAuth 2 identity providers — Google, GitHub, Discord, Twitch, YouTube, or a custom OAuth 2 provider — so its members can sign in without a Tournament Suite password. This is an authentication flow for logging a person into Tournament Suite; it does not produce a token you use to call the API on that person's behalf.
1. List available providers
GET https://api.tournamentsuite.com/api/v1/auth/sso/providers
Returns the SSO providers your organization has enabled.
2. Start the authorization flow
curl -X POST "https://api.tournamentsuite.com/api/v1/auth/sso/oauth2/authorize" \
-H "Content-Type: application/json" \
-d '{
"providerId": "YOUR_PROVIDER_ID",
"redirectUri": "https://yourapp.com/callback",
"state": "random-state-token",
"codeChallenge": "PKCE_CODE_CHALLENGE",
"codeChallengeMethod": "S256"
}'
Response:
{
"authorizationUrl": "https://accounts.google.com/oauth/authorize?client_id=...",
"state": "random-state-token",
"codeVerifier": "code-verifier-12345",
"expiresAt": "2026-07-23T12:10:00.000Z"
}
Redirect the user's browser to authorizationUrl. (There is also a GET /auth/sso/oauth2/authorize/:providerId convenience endpoint that issues the redirect for you.)
3. Handle the callback
After the user authenticates with the provider, they are redirected back with a code and state. Exchange them by calling:
curl -X POST "https://api.tournamentsuite.com/api/v1/auth/sso/oauth2/callback/YOUR_PROVIDER_ID" \
-H "Content-Type: application/json" \
-d '{
"code": "AUTHORIZATION_CODE",
"state": "random-state-token"
}'
On success, the response includes the authenticated user's Tournament Suite session tokens (accessToken and refreshToken) along with userId and profile information. These are end-user session tokens for that person's Tournament Suite session — not credentials for calling the Data API. Use an API key for that instead.
Security recommendations
- Always send
statewhen starting the flow, and verify the value returned in the callback matches it, to prevent CSRF. - Use PKCE (
codeChallenge/codeChallengeMethod) when initiating the flow from a browser or mobile app, and keep the returnedcodeVerifieron the client that started the flow. - Perform the callback exchange from your server, not directly from browser or mobile code, whenever your integration architecture allows it.
- Store session tokens the same way you would any other authentication credential — never in
localStorageor another location JavaScript on your page can read.
Was this helpful?
