Documentación v1
Conecta tus Campeonatos con Cualquier Sistema
API REST, webhooks firmados y un servidor MCP para que Claude y otros asistentes organicen torneos de cualquier deporte. Funciona con los datos de demostración de Costa Rica (Liga Fut 5 Escazú Nocturna y Santa Ana Pádel Open).
Inicio Rápido
- Entra como administrador y en Integraciones crea una Clave de API (se muestra una sola vez).
- En tu panel pulsa Cargar Datos de Demostración para tener la liga de Fútbol 5 y el torneo de Pádel.
- Prueba la API con el primer curl de abajo o conecta el MCP a Claude.
URL base: https://tu-dominio.com/api/public/v1
Autenticación
Todas las peticiones llevan la clave en la cabecera Authorization. Las claves de solo lectura no pueden usar POST ni PATCH. Cada clave solo ve los campeonatos de su dueño.
Authorization: Bearer ct10k_tu_clave_secreta
Endpoints
| GET | /deportes | Deportes disponibles y sus sugerencias |
| GET | /formatos | Formatos de competencia |
| GET | /campeonatos | Lista tus campeonatos (paginado) |
| POST | /campeonatos | Crea un campeonato |
| GET | /campeonatos/{id|slug} | Detalle de un campeonato |
| PATCH | /campeonatos/{id} | Edita nombre, estado, sede, reglamento o visibilidad |
| GET | /campeonatos/{id}/equipos | Equipos inscritos |
| POST | /campeonatos/{id}/equipos | Inscribe un equipo |
| GET · PATCH | /campeonatos/{id}/equipos/{equipoId} | Ver o editar un equipo |
| GET · POST | /campeonatos/{id}/equipos/{equipoId}/jugadores | Jugadores de un equipo |
| GET | /campeonatos/{id}/jugadores | Todos los jugadores |
| GET | /campeonatos/{id}/calendario | Calendario ordenado por fecha |
| POST | /campeonatos/{id}/calendario | Genera y programa el calendario sin choques |
| GET | /campeonatos/{id}/partidos?estado=pendiente | Partidos (filtro: pendiente, en_vivo, final) |
| GET · PATCH | /campeonatos/{id}/partidos/{partidoId} | Ver o reprogramar (fecha, cancha, árbitro) |
| POST | /campeonatos/{id}/partidos/{partidoId}/resultado | Carga un resultado |
| GET | /campeonatos/{id}/resultados | Partidos finalizados |
| GET | /campeonatos/{id}/posiciones | Tabla de posiciones |
| POST | /webhooks/in | Webhook entrante (resultado o inscripción) |
Donde dice {id} puedes usar el id o el slug del campeonato.
Ejemplos curl
Listar campeonatos
curl "https://tu-dominio.com/api/public/v1/campeonatos?page=1&limit=10" \ -H "Authorization: Bearer $CT10K_KEY"
Crear un torneo de pádel en Santa Ana
curl -X POST "https://tu-dominio.com/api/public/v1/campeonatos" \
-H "Authorization: Bearer $CT10K_KEY" \
-H "Content-Type: application/json" \
-d '{"nombre":"Copa Pádel Escazú 2026","deporte":"padel","formato":"americano","cupos":16,"canchas":4,"fecha_inicio":"2026-11-07","sede":"Club Escazú"}'Inscribir un equipo con jugadores
curl -X POST "https://tu-dominio.com/api/public/v1/campeonatos/{id}/equipos" \
-H "Authorization: Bearer $CT10K_KEY" \
-H "Content-Type: application/json" \
-d '{"nombre":"Saprissa Barrio","capitan":"Keylor Mora","telefono":"+506 8888-1234","jugadores":["Keylor Mora","Bryan Solís","Joel Campbell"]}'Generar el calendario
curl -X POST "https://tu-dominio.com/api/public/v1/campeonatos/{id}/calendario" \
-H "Authorization: Bearer $CT10K_KEY" \
-H "Content-Type: application/json" \
-d '{"desde":"2026-11-07"}'Cargar un resultado
curl -X POST "https://tu-dominio.com/api/public/v1/campeonatos/{id}/partidos/{partidoId}/resultado" \
-H "Authorization: Bearer $CT10K_KEY" \
-H "Content-Type: application/json" \
-d '{"local":3,"visitante":1}'Tabla de posiciones
curl "https://tu-dominio.com/api/public/v1/campeonatos/{id}/posiciones" -H "Authorization: Bearer $CT10K_KEY"Errores y Paginación
Las listas aceptan page y limit (máx. 100). Los errores siempre tienen la misma forma:
// 200 — lista paginada
{ "data": [ ... ], "pagina": 1, "limite": 20, "total": 42, "paginas": 3 }
// 4xx / 5xx
{ "error": { "codigo": "clave_invalida", "mensaje": "La clave de API no existe o fue revocada." } }- 400 datos_invalidos / json_invalido
- 401 sin_autorizacion / clave_invalida
- 403 sin_permiso_escritura
- 404 no_encontrado / ruta_desconocida
- 422 equipos_insuficientes / partido_incompleto
- 500 error_interno
Webhooks Entrantes
Otros sistemas pueden enviar resultados o inscripciones a https://tu-dominio.com/api/public/v1/webhooks/in usando una clave con escritura como secreto. Cada evento queda registrado en Integraciones → Eventos Entrantes.
curl -X POST "https://tu-dominio.com/api/public/v1/webhooks/in" \
-H "Authorization: Bearer $CT10K_KEY" \
-H "Content-Type: application/json" \
-d '{"tipo":"resultado","campeonato":"{id o slug}","partido":"{partidoId}","local":2,"visitante":2}'{ "tipo": "inscripcion", "campeonato": "{id o slug}",
"equipo": { "nombre": "Heredia Pádel Club", "capitan": "Daniela Rojas", "jugadores": ["Daniela Rojas", "Sofía Vargas"] } }Webhooks Salientes
Registra destinos en Integraciones → Webhooks Salientes. Enviamos un POST JSON con hasta 3 intentos (espera creciente) y cada entrega queda en el registro, con botón para reintentar. Eventos:
- partido.programado — se asigna o cambia fecha
- resultado.cargado — un partido pasa a final
- equipo.inscrito — nuevo equipo en el torneo
- campeon.definido — se conoce el campeón
POST /tu-endpoint Content-Type: application/json X-Evento: resultado.cargado X-Signature: sha256=5f1c0e…a9
{
"id": "2b0f4c1e-7d5a-4a3e-9b1f-0c6d2e8a1f44",
"evento": "resultado.cargado",
"creado": "2026-10-05T02:14:09.512Z",
"datos": {
"campeonato": { "id": "…", "slug": "liga-fut-5-escazu-nocturna-x1y2", "nombre": "Liga Fut 5 Escazú Nocturna" },
"partido": {
"id": "k3j9a1", "ronda": 3, "fase": "liga",
"local": { "id": "a1", "nombre": "Los Ticos FC" }, "visitante": { "id": "b2", "nombre": "Real Escazú" },
"marcador_local": 4, "marcador_visitante": 2, "estado": "final",
"cancha": "Cancha 1", "fecha": "2026-10-03T19:00", "arbitro": "Marco Jiménez"
}
}
}Verificar la Firma
Calcula HMAC-SHA256 del cuerpo crudo con el secreto del destino (whsec_…) y compáralo en tiempo constante con X-Signature.
import crypto from "node:crypto";
export function verificar(cuerpoCrudo, cabecera, secreto) {
const esperado = "sha256=" + crypto.createHmac("sha256", secreto).update(cuerpoCrudo).digest("hex");
const a = Buffer.from(esperado), b = Buffer.from(cabecera ?? "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}import hmac, hashlib
def verificar(cuerpo_crudo: bytes, cabecera: str, secreto: str) -> bool:
esperado = "sha256=" + hmac.new(secreto.encode(), cuerpo_crudo, hashlib.sha256).hexdigest()
return hmac.compare_digest(esperado, cabecera or "")Servidor MCP
Endpoint MCP (HTTP): https://tu-dominio.com/api/public/mcp. Usa la misma clave de API. Herramientas: listar_campeonatos, listar_deportes, crear_campeonato, inscribir_equipo, generar_calendario, registrar_resultado, tabla_de_posiciones, proximos_partidos.
Claude Desktop — claude_desktop_config.json
{
"mcpServers": {
"campeonatos-total-10k": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://tu-dominio.com/api/public/mcp", "--header", "Authorization:${CT10K_AUTH}"],
"env": { "CT10K_AUTH": "Bearer ct10k_tu_clave_secreta" }
}
}
}Claude Code
claude mcp add --transport http campeonatos-total-10k https://tu-dominio.com/api/public/mcp \ --header "Authorization: Bearer ct10k_tu_clave_secreta"
Probar con curl
curl -X POST "https://tu-dominio.com/api/public/mcp" -H "Authorization: Bearer $CT10K_KEY" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"proximos_partidos","arguments":{"limite":5}}}'Pídele a Claude
"Crea un torneo de ajedrez suizo en Cartago con 12 jugadores, inscríbelos, genera el calendario y dime los próximos partidos."