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

  1. Entra como administrador y en Integraciones crea una Clave de API (se muestra una sola vez).
  2. En tu panel pulsa Cargar Datos de Demostración para tener la liga de Fútbol 5 y el torneo de Pádel.
  3. 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
http

Endpoints

GET/deportesDeportes disponibles y sus sugerencias
GET/formatosFormatos de competencia
GET/campeonatosLista tus campeonatos (paginado)
POST/campeonatosCrea un campeonato
GET/campeonatos/{id|slug}Detalle de un campeonato
PATCH/campeonatos/{id}Edita nombre, estado, sede, reglamento o visibilidad
GET/campeonatos/{id}/equiposEquipos inscritos
POST/campeonatos/{id}/equiposInscribe un equipo
GET · PATCH/campeonatos/{id}/equipos/{equipoId}Ver o editar un equipo
GET · POST/campeonatos/{id}/equipos/{equipoId}/jugadoresJugadores de un equipo
GET/campeonatos/{id}/jugadoresTodos los jugadores
GET/campeonatos/{id}/calendarioCalendario ordenado por fecha
POST/campeonatos/{id}/calendarioGenera y programa el calendario sin choques
GET/campeonatos/{id}/partidos?estado=pendientePartidos (filtro: pendiente, en_vivo, final)
GET · PATCH/campeonatos/{id}/partidos/{partidoId}Ver o reprogramar (fecha, cancha, árbitro)
POST/campeonatos/{id}/partidos/{partidoId}/resultadoCarga un resultado
GET/campeonatos/{id}/resultadosPartidos finalizados
GET/campeonatos/{id}/posicionesTabla de posiciones
POST/webhooks/inWebhook 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"
bash

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ú"}'
bash

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"]}'
bash

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"}'
bash

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}'
bash

Tabla de posiciones

curl "https://tu-dominio.com/api/public/v1/campeonatos/{id}/posiciones" -H "Authorization: Bearer $CT10K_KEY"
bash

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." } }
json
  • 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}'
bash
{ "tipo": "inscripcion", "campeonato": "{id o slug}",
  "equipo": { "nombre": "Heredia Pádel Club", "capitan": "Daniela Rojas", "jugadores": ["Daniela Rojas", "Sofía Vargas"] } }
json

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
http
{
  "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"
    }
  }
}
json

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);
}
node
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 "")
python

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" }
    }
  }
}
json

Claude Code

claude mcp add --transport http campeonatos-total-10k https://tu-dominio.com/api/public/mcp \
  --header "Authorization: Bearer ct10k_tu_clave_secreta"
bash

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}}}'
bash

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."