Changelog
Version history of the SETTO External API — what shipped, what changed, and what counts as a breaking change.
Every change to the External API is recorded here, newest first. The API is
versioned in its path (/v1/): additive changes ship inside v1, and anything
that would break an existing integration would ship as a new path prefix.
What counts as a change
| Change | Breaking? |
|---|---|
A new endpoint, field or populate path | No — additive |
A new member in an existing enum (a new status, sport or type) | No — treat enums as open |
A new error code for a status you already handle | No |
Removing or renaming a field, endpoint or populate path | Yes |
| Changing a field's type, or a list's default ordering | Yes |
| Tightening validation on a parameter that used to be accepted | Yes |
Build for the additive cases: ignore fields you do not recognise, and fall
through on enum values you have not seen. That way a release like "pickleball
individual leagues now expose a new tournament type" never reaches your
on-call.
2026-11 — Draws and results through AI
Additive. Existing tokens, reads, setup writes and the schedule write work unchanged.
- Eleven new operations, 38 in all, on the padel, tennis and pickleball
categories of a regular tournament. With the
managepermission («Gestionar torneos»): set a category's format, a group stage, a knockout or both (previewDivisionFormat,applyDivisionFormat); add the knockout after a group stage (appendEliminationRound); set up the groups («Configurar grupos»,previewPools,applyPools) and the knockout draw («Configurar eliminatorias»,previewDraw,applyDraw; 2 to 256 teams); seat the knockout from the final group standings («Confirmar cuadro»,confirmDraw; the same body sent again answerschanged: false); and set who plays a game (setGameTeams). Withresults(«Cargar resultados»), the first routes that use it: record a game's result (recordGameResult: its sets, a W.O., a retirement or a «Doble W.O.») and clear it («Borrar resultado»,clearGameResult). The three previews need onlyread. See the API reference. - A format, groups or a draw is previewed, then confirmed, like a
withdrawal: the preview answers the plan and a
confirmationTokenvalid 15 minutes; the apply writes exactly that plan, or answers409 PREVIEW_STALEwhen the category changed in between. The groups' lot is reproducible (rngSeed), andpinsputs a team in a given group. - Played games are never rebuilt. A format, groups or a draw over results
is refused (
FORMAT_HAS_PLAYED_GAMES,ROUND_HAS_PLAYED_GAMES,KNOCKOUT_HAS_PLAYED_GAMES), and the confirmation never seats a withdrawn team:replacegives its place to another team of the category or to a BYE. - A result moves what follows it: the group standings, and in a knockout
the winner (
advancedlists the slots it filled); clearing it puts each slot back to «Ganador del juego N». A stored result is replaced only withoverwrite: true. A success can carrywarnings:SET_COUNT_UNUSUAL,BRACKET_ALREADY_CONFIRMED,STANDINGS_NOT_COUNTED. - New refusal codes (
INVALID_FORMAT,INVALID_POOL_PIN,INVALID_DRAW_SIZE,ROUND_ROBIN_INCOMPLETE,DRAW_SEATS_WITHDRAWN_TEAM,GAME_HAS_RESULT,INVALID_RESULT, …), each withdetails. Every write here takes an optionalIdempotency-Key, and every write, and every refusal, is recorded in «Actividad». See Errors. - The MCP server (1.5.0) gains the eleven tools, 38 in all, and its
instructions teach preview → the organizer's yes → apply for a format, groups
and a draw, and read the game → record → show what changed for a result. The
setto-apiAgent Skill (1.6.0, with «Armar grupos / cuadro» and «Cargar resultados» inreferences/workflows.md) and the Claude Code plugin (1.5.0) follow. See MCP server.
2026-11 — Tournament setup through AI
Additive. Existing tokens, reads and the schedule write work unchanged.
- Seventeen new operations, 27 in all. With the
managepermission («Gestionar torneos»): create a tournament on the FREE plan as a draft, with its categories (createTournament); edit, publish, take back to draft, archive or restore it (updateTournament,publishTournament,setTournamentLifecycle); add, edit and delete categories and set their seeds (createDivision,updateDivision,deleteDivision,setDivisionSeeds); register one team or up to 50 without sending an email (registerTeam,registerTeams); edit or delete a team and edit a player (updateTeam,deleteTeam,updatePlayer); replace a player («Sustitución»,substitutePlayer); and withdraw a team («Baja»,withdrawTeam). Withread: find categories, rounds, groups, teams and players by name (searchTournament) and preview a withdrawal game by game (previewTeamWithdrawal, which writes nothing). See the API reference. - A withdrawal is previewed, then confirmed. The preview answers a
confirmationTokenvalid 15 minutes for that team and that plan;withdrawTeamapplies exactly that plan, or answers409 PREVIEW_STALEwhen the tournament changed in between. - Retries never write twice. The creates and the team operations take an
optional
Idempotency-Keyheader: the same key with the same body answers the first result for 24 hours. listTournamentssearches by name withq(accents and case ignored) and answers the folded query inquery. Rounds carry alabelin Spanish and English, bracket slots a SpanishlabelEs, and a teamwithdrawn.- New refusal codes for the setup writes (
DIVISION_LIMIT_REACHED,DIVISION_FULL,TEAM_HAS_GAMES,PREVIEW_STALE,TOURNAMENT_BUSY,TOURNAMENT_CREATE_DAILY_CAP, …), each withdetails. An organizer creates at most 20 tournaments a day through the API. No price, paid mark, payment record or refund changes through a write (a withdrawal closes the team's unpaid payment links); every write, and every refusal, is recorded in «Actividad». See Errors. - The MCP server (1.4.0) gains
search_tournamentand the sixteen setup tools, words every warning and every game of a withdrawal in Spanish (mensaje), and its instructions teach preview → the organizer's yes → apply. Thesetto-apiAgent Skill (1.5.0, with a newreferences/workflows.md) and the Claude Code plugin (1.4.0) follow. See MCP server.
2026-11 — OAuth sign-in, permissions, «Actividad»
Additive. Existing tokens and integrations keep working unchanged.
- Sign in with your SETTO account. SETTO's api is now its own OAuth 2.1
authorization server, so claude.ai, ChatGPT, Codex and Claude Code connect to
the MCP server without a token: the organizer approves the app on a consent
screen at
app.setto.io. The app's access token is an API token (setto_live_…) that acts as that organizer, so this API accepts it too. It never appears under «Tokens de API»; «Conexiones» lists the app and disconnects it. See Sign in with your SETTO account. - Six permissions («Permisos»).
readandscheduleare joined bymanage,results,landingandcommunications, which can be granted now and are reserved for the writes that come next: no route needs them yet. An organization token keeps any permission beyondreadonly while theADMINwho created it still is one (until now, that rule coveredscheduleonly). See What a token can change. GET /v1/external/activity(listActivity, tagActivity, needs onlyread) — «Actividad»: the writes apps and API tokens made in the tournaments the token reaches, newest first, with who acted, through which app or token, and the outcome. Page withcursorandnextCursor(limit1-50, default 20); a cursor that does not decode is400 INVALID_CURSOR.GET /v1/external/megainsactingAs(the organizer every call acts as),app(the connected app,nullfor an API token) andtoken.origin(manualoroauth).- The MCP server (1.3.0) accepts the sign-in, states all four MCP hints on
every tool, names the missing «Permiso» for each kind of credential, and
gains
list_activity. Thesetto-apiAgent Skill (1.4.0) and the Claude Code plugin (1.3.0) follow. See MCP server.
2026-11 — Personal API tokens
Additive for existing tokens. Organization tokens work exactly as before; everything below is new.
- Personal tokens («Token personal»). Any SETTO user can hold up to 10
active personal tokens, created in
app.setto.io→ Configuración → Tokens de API with the scope on Personal. A personal token reaches every tournament its owner manages at the moment of each request — personal tournaments included — and may carryschedule, which then writes the schedule of any of those tournaments. See Two kinds of token. - Organization tokens («Token de la organización») are now created in the
same place, with the organization as the scope; the organization's page, tab
API, still lists them. Their reach, scopes and
ADMINre-check are unchanged. GET /v1/external/megainsowner(type,idx,name):typeisuserfor a personal token andorganizationfor an organization token.organizationisnullonly for a personal token.- A tournament's
organizationis unchanged for an organization token (the token's organization). For a personal token it is the tournament's home organization, ornullfor a personal tournament: handlenullbefore you point an integration at a personal token. - The MCP server (1.2.0) accepts personal tokens, names the
INSUFFICIENT_SCOPEfix for each kind of token, and gains a Claude Desktop setup throughmcp-remote. See MCP server.
2026-11 — Scheduling: the first write
Additive. Three operations under a new Scheduling tag, and a second token
scope:
GET /v1/external/tournaments/{idx}/schedule(getTournamentSchedule) — courts, categories, every game with its start, length, court andlockedflag, and the teams' approved time petitions.POST /v1/external/tournaments/{idx}/schedule/proposals(proposePoolPerCourtSchedule) — plans one day «un grupo por cancha» and returns the placements, the unplaceable games and the petition misses. Saves nothing; needs onlyread.POST /v1/external/tournaments/{idx}/schedule/placements(applySchedulePlacements) — writes the start, court and length of the named games, all or nothing. Refusals list every offending game indetails(409 SCHEDULE_CONFLICT,409 GAME_LOCKED, …).- Tokens can now carry
schedulenext toread: an organization token created by an organizationADMINwith «Permitir programar partidos» ticked (and, since personal API tokens, a personal token created with it). Existing tokens keepreadonly. Withoutschedule, the placements route answers403 INSUFFICIENT_SCOPE. - The MCP server gains
get_schedule,propose_pool_per_court_scheduleandapply_schedule_placements, and installs from a Claude Code plugin, an «Add to Cursor» link or an «Add to VS Code» link. See MCP server.
2026-10-02 — whoCanSubmit: ANYONE
Additive. tournament.whoCanSubmit gains a third member, ANYONE, next to
ADMINS_ONLY and PLAYERS: the organizer lets anyone with the tournament's
public link upload game results, signed in or not. Results still follow
resultApprovalMode (ADMIN holds each one for the organizer's review). An
integration that falls through on unseen enum members needs no change.
1.1.0 — 2026-09-19
Fútbol (soccer) joins padel, tennis and pickleball. Everything in this release is additive: no existing field changed its type or its meaning, and an integration that already ignores unknown fields and falls through on unseen enum members needs no change at all.
FUTBOLjoins thesportenum, next toPADEL,TENNISandPICKLEBALL. A fútbol tournament always registers teams (a captain signs the team up), is alwaystype: TOURNAMENT, and is never part of a circuit.tournament.sportSettings— a new object, present onFUTBOLtournaments andnullfor the racket sports:modality(F5,F7,F9,F11orFUTSAL),extraTime,matchMinutes,h2hRequiresCompleteSubset,forfeitScoreandfairPlayWeights.- Three new fields on
score, allnullfor the racket sports:extraTime({ home, away }— goals scored during extra time only, not cumulative: add them toscore.home/score.awayfor the after-extra-time total),penalties({ home, away }— shootout kicks converted; kicks are never goals and never enter the standings) anddecisionMethod(REGULATION,EXTRA_TIME,SHOOTOUTorWALKOVER, whereWALKOVERis a forfeit). On a fútbol game they readnulltoo until the game actually went to extra time, to a shootout, or reached an official result —nullis the ordinary case, not an error. - For
FUTBOL,score.setsholds exactly one element — the full-time score, whosehomeandawayequalscore.homeandscore.away, withisTieBreakalwaysfalse. That single set is what keeps a set-shaped consumer working unchanged. - A fútbol game can end in a draw. Group and league games have no winner when they finish level. A knockout tie goes to extra time (an organizer toggle per tournament) and then to a shootout; the winner is derived on the server.
GOALS_FOR,GOALS_AGAINSTandGOAL_DIFFERENCEjoin thestandingColumnsenum, for fútbol standings. Racket-sport tournaments keep exactly the columns they already had.H2HL, a new tiebreak criterion — the head-to-head mini-league: points, then goal difference, then goals for, counting only the games among the tied teams. It is skipped when the tied teams have not all met, unless the organizer turnssportSettings.h2hRequiresCompleteSubsetoff. It reaches you as anacronyminsiderankedTiebreakRules.teamStatscounts goals for fútbol.pointsFor,pointsAgainstandpointsDifferencecarry goals for, goals against and goal difference;setsPointsFor,setsPointsAgainstandsetsPointsDifferenceare not written forFUTBOLand stay0. Their racket-sport meaning is unchanged.
2026-09-17 — Canonical host api.setto.io
The External API now answers on https://api.setto.io, which is the base URL every
example in this documentation, the OpenAPI document and the agent skill (1.0.1) use.
The Railway-generated host it replaced (https://api-production-ea80.up.railway.app)
keeps answering for existing integrations, but new ones should use api.setto.io.
Paths, authentication and responses are unchanged — this is not a breaking change.
1.0.0 — 2026-09
Initial public release.
- Six read-only endpoints, all under
/v1/external/:getMe,listTournaments,getTournament,listDivisions,listTeams,getRound. - Organization API tokens. Created by the organization creator or an
ADMINmember (today inapp.setto.io→ Configuración → Tokens de API). Shown once, read-only, revocable, with an optional 30/90/365-day expiry and a maximum of 10 active tokens per organization. - Bearer authentication with
setto_live_(production) andsetto_test_(non-production) prefixes, and the error codesMISSING_API_TOKEN,INVALID_API_TOKEN,EXPIRED_API_TOKENandINSUFFICIENT_SCOPE. - Organization scoping. A token reads only the tournaments its organization
owns; anything else — including another organization's data and personal
tournaments — answers
404, never403, so ids cannot be probed. (Since 2026-11, a personal token reaches its owner's personal tournaments.) populate, an allow-listed comma-separated relation list per endpoint, with implicit parent expansion and per-endpoint defaults. Unknown values are a400.- Offset pagination on
listTournaments:limit1..100(default25),offset, and ametaenvelope withlimit,offsetandtotal. Rows are ordered bystartDatedescending. - Rate limiting at 120 requests per 60 seconds per token, with
X-RateLimit-Limit,X-RateLimit-RemainingandX-RateLimit-Reseton every response andRetry-Afteron a429. - Conditional requests. Strong
ETagplusIf-None-Matchreturns304 Not Modifiedso polling a round costs almost nothing. - A privacy-safe projection. No emails, phone numbers or social handles; no
payment or billing data. Player objects carry
idx,firstName,lastNameandavataronly. - Hidden and draft material is returned, flagged rather than filtered —
isVisible: falseon divisions and rounds, andDRAFT/ARCHIVEDtournaments inlistTournaments. - This documentation site, with a generated reference and a Try it
playground, a published
/openapi.json, a Markdown rendition of every page,/llms.txtand/llms-full.txt, a remote MCP server and an Agent Skill.