SETTO API

Quickstart

Create a SETTO API token in the dashboard and make your first three requests to the External API with curl, JavaScript or Python.

This page takes you from nothing to a tournament payload in five minutes: create a token in the SETTO organizer dashboard, confirm it with GET /v1/external/me, list your tournaments, then fetch one tournament with its categories embedded. Every request is a plain GET with an Authorization: Bearer header — no SDK, no OAuth dance, no client secret.

Before you start

You need a SETTO account. A personal token reaches every tournament you manage; to give a system only one organization's tournaments, create an organization token — see Two kinds of token. Connecting an AI assistant instead? claude.ai, ChatGPT, Codex and Claude Code can sign in with your SETTO account, no token needed.

Create an API token

In app.setto.io, open Configuración → Tokens de API, keep the scope on Personal (or pick an organization), and choose Crear token. Give it a name you will recognise later (Website widget, Season export, …), optionally pick an expiry of 30, 90 or 365 days, and confirm.

The secret is shown exactly once

SETTO stores only a hash of the token. The full setto_live_… value appears in the dialog immediately after creation and never again — copy it into your secret manager before closing. If you lose it, revoke the token and create a new one.

You can hold up to 10 active personal tokens, and an organization up to 10 active organization tokens. A token reads (scopes: ["read"]) unless you tick more under Permisos: «Gestionar torneos» adds the tournament setup writes — creating tournaments and categories, registering teams, «Sustitución», «Baja», the format, the groups and the knockout draw — as manage, «Cargar resultados» adds recording and clearing results as results, «Programar partidos» adds setting game times and courts as schedule (scopes: ["read", "schedule"]), and the other permissions are listed in What a token can change. Any token can be revoked at any time from the same list.

Confirm the token

GET /v1/external/me is the cheapest way to prove a token works. It tells you who the token belongs to (owner), when it was created, when it expires, and what your rate limit is.

export SETTO_API_TOKEN="setto_live_YOUR_TOKEN_HERE"

curl -s https://api.setto.io/v1/external/me \
  -H "Authorization: Bearer $SETTO_API_TOKEN"
200 OK
{
  "owner": {
    "type": "user",
    "idx": "2a7e4c91-0b3d-4f58-9e16-c5d8a2f4b073",
    "name": "Ana López"
  },
  "organization": null,
  "token": {
    "idx": "b8e3f107-5c92-4d6a-8e71-0a4c9d2b3f65",
    "name": "Website widget",
    "prefix": "setto_live_9f2ca",
    "scopes": ["read"],
    "createdAt": "2026-09-01T16:04:22.113Z",
    "expiresAt": null,
    "lastUsedAt": "2026-09-17T09:12:44.005Z"
  },
  "rateLimit": { "limit": 120, "windowSeconds": 60 }
}

That is a personal token: owner.type is "user" and organization is null. An organization token answers owner.type: "organization" and fills organization with the organization's idx, name, slug, avatar and website.

A 401 here means the header is missing or the token is wrong — see Errors.

List your tournaments

GET /v1/external/tournaments returns a page of tournaments ordered by startDate descending, newest first.

curl -s -G https://api.setto.io/v1/external/tournaments \
  -H "Authorization: Bearer $SETTO_API_TOKEN" \
  -d status=IN_PROGRESS \
  -d sport=PADEL \
  -d limit=5
200 OK (trimmed)
{
  "data": [
    {
      "idx": "3c9b7f52-6d41-4a8e-b1f0-2e7d5c9a4b18",
      "slug": "torneo-apertura-2026",
      "name": "Torneo Apertura 2026",
      "type": "TOURNAMENT",
      "sport": "PADEL",
      "status": "IN_PROGRESS",
      "startDate": "2026-09-18T00:00:00.000Z",
      "endDate": "2026-09-20T00:00:00.000Z",
      "timezone": "America/Monterrey",
      "publicUrl": "https://www.setto.io/t/torneo-apertura-2026",
      "organization": {
        "idx": "6f1d9c2e-4a7b-4f3d-9d2c-8b5e1a0f7c43",
        "name": "Club Padel Monterrey",
        "slug": "club-padel-monterrey"
      }
    }
  ],
  "meta": { "limit": 5, "offset": 0, "total": 1 }
}

Keep the idx — it is the identifier every other endpoint takes.

Fetch one tournament with its categories

Relations are opt-in. Ask for them with populate, a comma-separated list. GET /v1/external/tournaments/{idx} defaults to club,divisions; asking for divisions alone keeps the payload small.

curl -s -G \
  https://api.setto.io/v1/external/tournaments/3c9b7f52-6d41-4a8e-b1f0-2e7d5c9a4b18 \
  -H "Authorization: Bearer $SETTO_API_TOKEN" \
  -d populate=divisions
200 OK (trimmed)
{
  "idx": "3c9b7f52-6d41-4a8e-b1f0-2e7d5c9a4b18",
  "slug": "torneo-apertura-2026",
  "name": "Torneo Apertura 2026",
  "type": "TOURNAMENT",
  "sport": "PADEL",
  "status": "IN_PROGRESS",
  "publicUrl": "https://www.setto.io/t/torneo-apertura-2026",
  "divisions": [
    {
      "idx": "7b2f4d16-9c83-4e50-a7d1-3f6c8b204e59",
      "name": "Cuarta Fuerza Varonil",
      "number": 1,
      "color": "#2563eb",
      "isDoubles": true,
      "isVisible": true,
      "price": 900,
      "tournament": { "idx": "3c9b7f52-6d41-4a8e-b1f0-2e7d5c9a4b18" }
    }
  ]
}

Next steps

  • Populate — the exact relation list per endpoint, and why a nested path needs its parents.
  • Get a round — groups, standings, games and brackets in a single request. This is the endpoint most integrations spend their time in.
  • Rate limits — 120 requests per minute per token, and a second per-IP ceiling of 300 requests per minute.
  • API reference — every parameter, with a Try it panel you can paste a token into.

On this page