TS
Tournament Suite
TS
Tournament Suite
Developer Documentation

OAuth 2

How to obtain and use OAuth 2 access tokens with the TournamentSuite API.

TournamentSuite uses OAuth 2 for user-scoped authentication. Access tokens are short-lived JWTs issued by the TournamentSuite identity provider. They must be included in every request that requires a specific user context.

Grant types

TournamentSuite supports two OAuth 2 grant types.

Client Credentials (machine-to-machine)

Use this when your server needs to call the API on its own behalf — not on behalf of a specific user. This is the most common pattern for backend integrations.

curl -X POST "$OIDC_ISSUER/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=$CLIENT_ID" \
  -d "client_secret=$CLIENT_SECRET" \
  -d "scope=read:tournaments manage:matches"

Response:

{
  "access_token": "eyJhbGciOiJSUzI1NiJ9...",
  "expires_in": 900,
  "token_type": "Bearer",
  "scope": "read:tournaments manage:matches"
}

Authorization Code (on behalf of a user)

Use this when a user grants your application permission to act on their account — for example, registering them in a tournament.

  1. Redirect the user to the authorization endpoint:
GET $OIDC_ISSUER/protocol/openid-connect/auth
  ?response_type=code
  &client_id=YOUR_CLIENT_ID
  &redirect_uri=https://yourapp.com/callback
  &scope=openid read:tournaments
  1. The user authenticates and is redirected back to your redirect_uri with a code parameter.

  2. Exchange the code for tokens:

const tokenResponse = await fetch(
  `${process.env.OIDC_ISSUER}/protocol/openid-connect/token`,
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      client_id: process.env.TOURNAMENTSUITE_CLIENT_ID!,
      client_secret: process.env.TOURNAMENTSUITE_CLIENT_SECRET!,
      redirect_uri: 'https://yourapp.com/callback',
      code: authorizationCode,
    }),
  }
);
const { access_token, refresh_token, expires_in } = await tokenResponse.json();

Token lifecycle

TokenLifetimePurpose
Access token15 minutesAuthenticate API requests
Refresh token7 daysObtain new access tokens

When the access token expires, use the refresh token to get a new one without requiring the user to log in again:

async function refresh(refreshToken: string) {
  const response = await fetch(
    `${process.env.OIDC_ISSUER}/protocol/openid-connect/token`,
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({
        grant_type: 'refresh_token',
        client_id: process.env.TOURNAMENTSUITE_CLIENT_ID!,
        refresh_token: refreshToken,
      }),
    }
  );
  return response.json();
}

Discovery document

Your OAuth 2 client endpoint URLs can be discovered programmatically:

GET $OIDC_ISSUER/.well-known/openid-configuration

This returns the token endpoint, authorization endpoint, and supported scopes for your TournamentSuite environment.

Security recommendations

  • Store access tokens in server-side session storage, not in localStorage or cookies accessible to JavaScript.
  • Treat refresh tokens like passwords — store them encrypted and rotate them regularly.
  • Use PKCE (Proof Key for Code Exchange) when implementing the Authorization Code flow in a browser or mobile app.
  • Always validate the token's iss, aud, and exp claims before accepting it in your own services.

On this page

Grant typesClient Credentials (machine-to-machine)Authorization Code (on behalf of a user)Token lifecycleDiscovery documentSecurity recommendations