Registro de cambios
Historial de versiones de la API externa de SETTO — qué salió, qué cambió y qué cuenta como un cambio rompedor.
Cada cambio de la API externa queda registrado aquí, del más reciente al más
antiguo. La API se versiona en su ruta (/v1/): los cambios aditivos salen
dentro de v1, y cualquier cosa que rompiera una integración existente saldría
con un nuevo prefijo de ruta.
Qué cuenta como un cambio
| Cambio | ¿Rompe? |
|---|---|
Un endpoint, campo o ruta de populate nuevo | No — es aditivo |
Un miembro nuevo en un enum existente (un status, sport o type nuevo) | No — trata los enums como abiertos |
Un code de error nuevo para un estado que ya manejas | No |
Eliminar o renombrar un campo, endpoint o ruta de populate | Sí |
| Cambiar el tipo de un campo, o el orden por defecto de una lista | Sí |
| Endurecer la validación de un parámetro que antes se aceptaba | Sí |
Construye para los casos aditivos: ignora los campos que no reconozcas y deja
pasar los valores de enum que no hayas visto. Así una versión del tipo "las
ligas individuales de pickleball ahora exponen un type de torneo nuevo" nunca
llega a tu guardia.
2026-11 — Cuadros y resultados con IA
Aditivo. Los tokens, las lecturas, las escrituras de configuración y la de programación existentes siguen funcionando igual.
- Once operaciones nuevas, 38 en total, en las categorías de pádel, tenis y
pickleball de un torneo regular. Con el permiso
manage(«Gestionar torneos»): fijar el formato de una categoría, fase de grupos, eliminatorias o ambas (previewDivisionFormat,applyDivisionFormat); agregar las eliminatorias después de la fase de grupos (appendEliminationRound); armar los grupos («Configurar grupos»,previewPools,applyPools) y el cuadro («Configurar eliminatorias»,previewDraw,applyDraw; de 2 a 256 equipos); acomodar el cuadro con la clasificación final de los grupos («Confirmar cuadro»,confirmDraw; el mismo cuerpo enviado otra vez contestachanged: false); y fijar quién juega un partido (setGameTeams). Conresults(«Cargar resultados»), las primeras rutas que lo usan: cargar el resultado de un partido (recordGameResult: sus sets, un W.O., un retiro o un «Doble W.O.») y borrarlo («Borrar resultado»,clearGameResult). Las tres vistas previas solo requierenread. Consulta la referencia de la API. - Un formato, unos grupos o un cuadro se previsualizan y luego se
confirman, como una baja: la vista previa contesta el plan y un
confirmationTokenválido 15 minutos; la aplicación escribe exactamente ese plan, o contesta409 PREVIEW_STALEsi la categoría cambió en medio. El sorteo de los grupos se puede repetir (rngSeed), ypinspone a un equipo en un grupo dado. - Lo jugado nunca se reconstruye. Un formato, unos grupos o un cuadro
sobre resultados se rechazan (
FORMAT_HAS_PLAYED_GAMES,ROUND_HAS_PLAYED_GAMES,KNOCKOUT_HAS_PLAYED_GAMES), y la confirmación nunca acomoda a un equipo dado de baja:replacele da su lugar a otro equipo de la categoría o a un BYE. - Un resultado mueve lo que sigue: la clasificación de los grupos y, en
eliminatorias, al ganador (
advancedlista los lugares que llenó); borrarlo regresa cada lugar a «Ganador del juego N». Un resultado guardado solo se reemplaza conoverwrite: true. Una respuesta exitosa puede traerwarnings:SET_COUNT_UNUSUAL,BRACKET_ALREADY_CONFIRMED,STANDINGS_NOT_COUNTED. - Códigos de rechazo nuevos (
INVALID_FORMAT,INVALID_POOL_PIN,INVALID_DRAW_SIZE,ROUND_ROBIN_INCOMPLETE,DRAW_SEATS_WITHDRAWN_TEAM,GAME_HAS_RESULT,INVALID_RESULT, …), cada uno condetails. Cada escritura de aquí acepta un encabezado opcionalIdempotency-Key, y cada escritura, y cada rechazo, queda en la «Actividad». Consulta Errores. - El servidor MCP (1.5.0) suma las once herramientas, 38 en total, y sus
instrucciones enseñan vista previa → el sí del organizador → aplicar para un
formato, unos grupos o un cuadro, y leer el partido → cargar → mostrar qué
cambió para un resultado. El Agent Skill
setto-api(1.6.0, con «Armar grupos / cuadro» y «Cargar resultados» enreferences/workflows.md) y el plugin de Claude Code (1.5.0) lo acompañan. Consulta Servidor MCP.
2026-11 — Configura torneos con IA
Aditivo. Los tokens, las lecturas y la escritura de programación existentes siguen funcionando igual.
- Diecisiete operaciones nuevas, 27 en total. Con el permiso
manage(«Gestionar torneos»): crear un torneo en borrador con el plan gratis, con sus categorías (createTournament); editarlo, publicarlo, regresarlo a borrador, archivarlo o restaurarlo (updateTournament,publishTournament,setTournamentLifecycle); agregar, editar y borrar categorías y fijar sus cabezas de serie (createDivision,updateDivision,deleteDivision,setDivisionSeeds); inscribir un equipo o hasta 50 sin enviar correos (registerTeam,registerTeams); editar o borrar un equipo y editar un jugador (updateTeam,deleteTeam,updatePlayer); sustituir a un jugador («Sustitución»,substitutePlayer); y dar de baja a un equipo («Baja»,withdrawTeam). Conread: encontrar categorías, rondas, grupos, equipos y jugadores por nombre (searchTournament) y ver la vista previa de una baja partido por partido (previewTeamWithdrawal, que no escribe nada). Consulta la referencia de la API. - Una baja se previsualiza y luego se confirma. La vista previa contesta un
confirmationTokenválido 15 minutos para ese equipo y ese plan;withdrawTeamaplica exactamente ese plan, o contesta409 PREVIEW_STALEsi el torneo cambió en medio. - Un reintento nunca escribe dos veces. Las creaciones y las operaciones de
equipo aceptan un encabezado opcional
Idempotency-Key: la misma llave con el mismo cuerpo contesta el primer resultado durante 24 horas. listTournamentsbusca por nombre conq(sin importar acentos ni mayúsculas) y contesta la consulta normalizada enquery. Las rondas llevan unlabelen español e inglés, los lugares del cuadro unlabelEsen español, y un equipowithdrawn.- Códigos de rechazo nuevos para las escrituras de configuración
(
DIVISION_LIMIT_REACHED,DIVISION_FULL,TEAM_HAS_GAMES,PREVIEW_STALE,TOURNAMENT_BUSY,TOURNAMENT_CREATE_DAILY_CAP, …), cada uno condetails. Un organizador crea a lo mucho 20 torneos al día por la API. Ninguna escritura cambia ningún precio, marca de pago, registro de pago ni reembolso (una baja cierra los enlaces de pago sin pagar del equipo); cada escritura, y cada rechazo, queda en la «Actividad». Consulta Errores. - El servidor MCP (1.4.0) suma
search_tournamenty las dieciséis herramientas de configuración, explica en español cada advertencia y cada partido de una baja (mensaje), y sus instrucciones enseñan vista previa → el sí del organizador → aplicar. El Agent Skillsetto-api(1.5.0, con unreferences/workflows.mdnuevo) y el plugin de Claude Code (1.4.0) lo acompañan. Consulta Servidor MCP.
2026-11 — Inicio de sesión con OAuth, permisos y «Actividad»
Aditivo. Los tokens y las integraciones existentes siguen funcionando igual.
- Entrar con tu cuenta de SETTO. La api de SETTO ahora es su propio
servidor de autorización OAuth 2.1, así que claude.ai, ChatGPT, Codex y
Claude Code se conectan al servidor MCP sin token: el organizador aprueba la
aplicación en una pantalla de consentimiento en
app.setto.io. El token de acceso de la aplicación es un token de API (setto_live_…) que actúa como ese organizador, así que esta API también lo acepta. Nunca aparece en «Tokens de API»; «Conexiones» muestra la aplicación y la desconecta. Consulta Entrar con tu cuenta de SETTO. - Seis permisos («Permisos»). A
readyschedulese sumanmanage,results,landingycommunications, que ya se pueden dar y quedan reservados para las próximas escrituras: ninguna ruta los usa todavía. Un token de organización conserva cualquier permiso además dereadsolo mientras elADMINque lo creó siga siéndolo (hasta ahora esa regla solo cubríaschedule). Consulta Qué puede cambiar un token. GET /v1/external/activity(listActivity, etiquetaActivity, basta conread) — la «Actividad»: las escrituras que las aplicaciones y los tokens hicieron en los torneos que alcanza el token, de la más reciente a la más antigua, con quién actuó, con qué aplicación o token, y el resultado. Se pagina concursorynextCursor(limitde 1 a 50, 20 por defecto); un cursor que no se puede decodificar es400 INVALID_CURSOR.GET /v1/external/mesumaactingAs(el organizador como el que actúa cada llamada),app(la aplicación conectada,nullpara un token de API) ytoken.origin(manualuoauth).- El servidor MCP (1.3.0) acepta el inicio de sesión, declara las cuatro
pistas en cada herramienta, nombra el «Permiso» que falta para cada tipo de
credencial y suma
list_activity. El Agent Skillsetto-api(1.4.0) y el plugin de Claude Code (1.3.0) lo acompañan. Consulta Servidor MCP.
2026-11 — Tokens de API personales
Aditivo para los tokens existentes. Los tokens de organización funcionan exactamente igual que antes; todo lo de abajo es nuevo.
- Tokens personales («Token personal»). Cualquier usuario de SETTO puede
tener hasta 10 tokens personales activos, creados en
app.setto.io→ Configuración → Tokens de API con el alcance en Personal. Un token personal alcanza todos los torneos que su dueño administra en el momento de cada petición — incluidos los personales — y puede llevarschedule, que entonces escribe la programación de cualquiera de esos torneos. Consulta Dos tipos de token. - Los tokens de organización («Token de la organización») ahora se crean en
el mismo lugar, con la organización como alcance; la página de la
organización, pestaña API, los sigue mostrando. Su alcance, sus scopes y
la revisión de
ADMINno cambian. GET /v1/external/mesumaowner(type,idx,name):typeesuserpara un token personal yorganizationpara uno de organización.organizationesnullsolo para un token personal.- La
organizationde un torneo no cambia con un token de organización (la organización del token). Con un token personal es la organización principal del torneo, onullpara un torneo personal: manejanullantes de apuntar una integración a un token personal. - El servidor MCP (1.2.0) acepta tokens personales, indica la solución de
INSUFFICIENT_SCOPEpara cada tipo de token y suma una configuración para Claude Desktop conmcp-remote. Consulta Servidor MCP.
2026-11 — Programación: la primera escritura
Aditivo. Tres operaciones bajo una etiqueta nueva, Scheduling, y un
segundo scope de token:
GET /v1/external/tournaments/{idx}/schedule(getTournamentSchedule) — canchas, categorías, todos los partidos con su inicio, duración, cancha y la marcalocked, y las peticiones de horario aprobadas de los equipos.POST /v1/external/tournaments/{idx}/schedule/proposals(proposePoolPerCourtSchedule) — planea un día «un grupo por cancha» y devuelve los partidos colocados, los que no se pudieron colocar y las peticiones no cumplidas. No guarda nada; basta conread.POST /v1/external/tournaments/{idx}/schedule/placements(applySchedulePlacements) — escribe el inicio, la cancha y la duración de los partidos indicados, todo o nada. Un rechazo lista cada partido en conflicto endetails(409 SCHEDULE_CONFLICT,409 GAME_LOCKED, …).- Los tokens ahora pueden llevar
scheduleademás deread: un token de organización que crea unADMINde la organización marcando «Permitir programar partidos» (y, desde los tokens personales, un token personal creado con ese permiso). Los tokens existentes conservan soloread. Sinschedule, la ruta de placements responde403 INSUFFICIENT_SCOPE. - El servidor MCP suma
get_schedule,propose_pool_per_court_scheduleyapply_schedule_placements, y se instala desde un plugin de Claude Code, un enlace «Agregar a Cursor» o uno «Agregar a VS Code». Consulta Servidor MCP.
2026-10-02 — whoCanSubmit: ANYONE
Aditivo. tournament.whoCanSubmit suma un tercer miembro, ANYONE, junto a
ADMINS_ONLY y PLAYERS: el organizador permite que cualquier persona con el
link público del torneo cargue resultados, haya iniciado sesión o no. Los
resultados siguen resultApprovalMode (ADMIN retiene cada uno para que el
organizador lo revise). Una integración que deja pasar los valores de enum que
no ha visto no necesita cambios.
1.1.0 — 2026-09-19
El fútbol se suma al pádel, el tenis y el pickleball. Todo lo de esta versión es aditivo: ningún campo existente cambió de tipo ni de significado, y una integración que ya ignora los campos que no reconoce y deja pasar los valores de enum que no ha visto no necesita ningún cambio.
FUTBOLse suma al enumsport, junto aPADEL,TENNISyPICKLEBALL. Un torneo de fútbol siempre inscribe equipos (un capitán registra al equipo), siempre estype: TOURNAMENTy nunca forma parte de un circuito.tournament.sportSettings— un objeto nuevo, presente en los torneosFUTBOLynullen los deportes de raqueta:modality(F5,F7,F9,F11oFUTSAL),extraTime,matchMinutes,h2hRequiresCompleteSubset,forfeitScoreyfairPlayWeights.- Tres campos nuevos en
score, todosnullen los deportes de raqueta:extraTime({ home, away }— goles marcados durante el tiempo extra, no acumulados: súmalos ascore.home/score.awaypara el total tras el tiempo extra),penalties({ home, away }— penales convertidos en la tanda; los penales nunca son goles ni entran en la tabla de posiciones) ydecisionMethod(REGULATION,EXTRA_TIME,SHOOTOUToWALKOVER, dondeWALKOVERes una incomparecencia). En un juego de fútbol también se leennullhasta que el juego se haya ido a tiempo extra, a penales o tenga un resultado oficial —nulles el caso normal, no un error. - En
FUTBOL,score.setslleva exactamente un elemento — el marcador al tiempo reglamentario, cuyoshomeyawayson iguales ascore.homeyscore.away, conisTieBreaksiempre enfalse. Ese único set es lo que mantiene funcionando sin cambios a quien ya consume sets. - Un juego de fútbol puede terminar en empate. Los juegos de grupo y de liga se quedan sin ganador cuando terminan igualados. Un empate en eliminatorias se va a tiempo extra (una opción que el organizador activa por torneo) y luego a penales; el ganador se deriva en el servidor.
GOALS_FOR,GOALS_AGAINSTyGOAL_DIFFERENCEse suman al enumstandingColumns, para las tablas de fútbol. Los torneos de raqueta conservan exactamente las columnas que ya tenían.H2HL, un criterio de desempate nuevo — la mini-liga entre empatados: puntos, luego diferencia de goles y luego goles a favor, contando solo los juegos entre los equipos empatados. Se omite cuando los equipos empatados no se han enfrentado todos entre sí, a menos que el organizador desactivesportSettings.h2hRequiresCompleteSubset. Te llega como unacronymdentro derankedTiebreakRules.- En fútbol,
teamStatscuenta goles.pointsFor,pointsAgainstypointsDifferencellevan goles a favor, goles en contra y diferencia de goles;setsPointsFor,setsPointsAgainstysetsPointsDifferenceno se escriben paraFUTBOLy se quedan en0. Su significado en los deportes de raqueta no cambia.
2026-09-17 — Host canónico api.setto.io
La API externa ahora responde en https://api.setto.io, que es la URL base que
usan todos los ejemplos de esta documentación, el documento OpenAPI y el Agent
Skill (1.0.1). El host generado por Railway al que reemplazó
(https://api-production-ea80.up.railway.app) sigue respondiendo para las
integraciones existentes, pero las nuevas deben usar api.setto.io. Las rutas,
la autenticación y las respuestas no cambian — no es un cambio rompedor.
1.0.0 — 2026-09
Primera versión pública.
- Seis endpoints de solo lectura, todos bajo
/v1/external/:getMe,listTournaments,getTournament,listDivisions,listTeams,getRound. - Tokens de API de organización. Los crea el creador de la organización o
un miembro
ADMIN(hoy enapp.setto.io→ Configuración → Tokens de API). Se muestran una vez, son de solo lectura, revocables, con expiración opcional de 30/90/365 días y un máximo de 10 tokens activos por organización. - Autenticación bearer con los prefijos
setto_live_(producción) ysetto_test_(no productivo), y los códigos de errorMISSING_API_TOKEN,INVALID_API_TOKEN,EXPIRED_API_TOKENeINSUFFICIENT_SCOPE. - Alcance por organización. Un token lee únicamente los torneos que su
organización posee; todo lo demás — incluidos los datos de otra organización y
los torneos personales — responde
404, nunca403, para que los ids no se puedan sondear. (Desde 2026-11, un token personal alcanza los torneos personales de su dueño.) populate, una lista de relaciones separada por comas y con lista blanca por endpoint, con expansión implícita de los padres y valores por defecto por endpoint. Los valores desconocidos son un400.- Paginación por offset en
listTournaments:limitde1..100(por defecto25),offset, y un sobremetaconlimit,offsetytotal. Las filas se ordenan porstartDatedescendente. - Límite de uso de 120 peticiones por 60 segundos por token, con
X-RateLimit-Limit,X-RateLimit-RemainingyX-RateLimit-Reseten cada respuesta yRetry-Afteren un429. - Peticiones condicionales.
ETagfuerte másIf-None-Matchdevuelve304 Not Modified, así que sondear una ronda cuesta casi nada. - Una proyección segura para la privacidad. Sin correos, teléfonos ni redes
sociales; sin datos de pago ni facturación. Los objetos de jugador llevan solo
idx,firstName,lastNameyavatar. - El material oculto y en borrador se devuelve marcado, no filtrado —
isVisible: falseen categorías y rondas, y torneosDRAFT/ARCHIVEDenlistTournaments. - Este sitio de documentación, con una referencia generada y un playground
Try it, un
/openapi.jsonpublicado, una versión Markdown de cada página,/llms.txty/llms-full.txt, un servidor MCP remoto y un Agent Skill.