TOURNAMENTSUITE
TOURNAMENTSUITE
Developer Documentation
AuthenticationAuthorizationScopesOAuth 2
Security

Authorization

How Tournament Suite controls access to resources through projects, scopes, and API key restrictions.

Authentication tells Tournament Suite who you are. Authorization determines what you can do.

Project-level isolation

All resources — tournaments, matches, and webhooks — belong to a project. Your API key can only access resources within the project it was created in. There is no way to read or write data across projects using a single key.

This means you can safely use separate keys for each environment (development, staging, production) without any risk of cross-contamination.

Scope-based access control

Every API key carries one or more scopes that limit the operations it can perform. A key with read:tournaments can list and retrieve tournaments but cannot access match or player data unless it also carries the matching read scope.

When you generate a key, you choose which scopes to grant. Request only the scopes your integration actually needs — this reduces the blast radius if a key is ever compromised.

See Scopes for the full list of available permissions.

What the public API surface covers

The public Data API is read-only. Every route requires an x-api-key header and a specific scope:

EndpointRequired scope
GET /tournamentsread:tournaments
GET /tournaments/:idread:tournaments
GET /tournaments/:id/bracketread:tournaments
GET /tournaments/:id/matchesread:matches
GET /matches/:idread:matches
GET /matches/:id/eventsread:matches
GET /players/:id/statsread:player_stats
GET /teams/:idread:teams

Creating or updating tournaments, registering participants, and reporting match results are organizer actions performed from the dashboard — they are not exposed to API keys.

The one part of the public API that does accept writes is the anti-cheat integration surface, which uses its own dedicated scopes:

ScopeGrants
anticheat:session.writeStart and end anti-cheat sessions
anticheat:evidence.writeUpload evidence for a session
anticheat:detections.readRead detection results

Checking permissions at runtime

If your integration receives a 403 Forbidden, inspect the response body's error.code field. The API always returns FORBIDDEN for authorization failures, regardless of the underlying cause:

{
  "success": false,
  "error": {
    "code": "FORBIDDEN",
    "message": "API key is missing required scope(s): read:matches"
  }
}

A 403 on a request made with an API key can come from any of the following. The message field tells you which one applies:

  • Missing scope — the key doesn't carry a scope the endpoint requires.
  • Plan entitlement — the project's current subscription plan doesn't include the capability the endpoint needs (for example, API access above your plan's tier), independent of the key's scopes.
  • IP not allowed — the request came from an address outside the key's configured IP allow list.

To resolve a scope or IP restriction, go to your project's developer settings in the organizer dashboard and generate a new key (or rotate the existing one) with the correct scopes or allow list. To resolve a plan-entitlement error, upgrade the project's plan.

Was this helpful?

Authentication

How to authenticate requests to the Tournament Suite public Data API using a project-scoped API key.

Scopes

The scopes you can grant an API key, and which endpoints each one unlocks.

On this page

Project-level isolationScope-based access controlWhat the public API surface coversChecking permissions at runtime