DOCUMENTACIÓN
API REST, Webhooks y Servidor MCP
Autenticación
Todas las peticiones llevan la cabecera Authorization: Bearer mtb_…. Las claves se crean en el Panel (solo admin), se muestran una sola vez y se guardan cifradas (hash SHA-256). Cada clave tiene permisos de lectura y/o escritura y actúa sobre el progreso de quien la creó.
URL base: https://tu-app.lovable.app/api/v1
Endpoints
| GET | /api/v1/lecciones | Lista los sistemas (lecciones). ?q=, ?page=, ?per_page= |
| GET | /api/v1/lecciones/:id | Detalle de una lección (p. ej. diamantes) |
| GET | /api/v1/diagramas | Diagramas de jugadas y de sistemas (coordenadas en diamantes 8x4) |
| GET | /api/v1/jugadores | Jugadores y maestros |
| GET | /api/v1/ejercicios | Ejercicios con nivel 1–3 |
| POST | /api/v1/{recurso} | Crea contenido propio (requiere escritura). Campo obligatorio: title |
| PATCH | /api/v1/{recurso}/:id | Edita contenido propio (el contenido base es de solo lectura) |
| GET | /api/v1/progreso | Sesiones del alumno dueño de la clave |
| GET | /api/v1/progreso/resumen | Resumen: promedios, racha, puntos, insignias |
| POST | /api/v1/progreso | Registra sesión: caroms, innings, high_run, session_date, notes |
| PATCH | /api/v1/progreso/:id | Edita una sesión |
| POST | /api/v1/webhooks/in | Webhook entrante (cabecera X-Webhook-Secret o X-Signature) |
Ejemplos curl
curl "https://tu-app.lovable.app/api/v1/lecciones?q=diamantes&page=1&per_page=5" \
-H "Authorization: Bearer $MTB_API_KEY"curl -X POST "https://tu-app.lovable.app/api/v1/progreso" \
-H "Authorization: Bearer $MTB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"caroms":18,"innings":40,"high_run":4,"notes":"Ángulos naturales"}'curl -X PATCH "https://tu-app.lovable.app/api/v1/progreso/ID_SESION" \
-H "Authorization: Bearer $MTB_API_KEY" -H "Content-Type: application/json" \
-d '{"high_run":5}'curl -X POST "https://tu-app.lovable.app/api/v1/ejercicios" \
-H "Authorization: Bearer $MTB_API_KEY" -H "Content-Type: application/json" \
-d '{"title":"20 bricoles a la esquina","level":2}'Errores y Paginación
Las listas responden { data: [...], pagination: { page, per_page, total, total_pages } }. per_page va de 1 a 100 (20 por defecto).
HTTP 401
{ "error": { "code": "clave_invalida", "message": "La clave de API no existe o fue revocada." } }Códigos: 400 json_invalido · 401 no_autorizado / clave_invalida · 403 sin_permiso · 404 no_encontrado · 405 metodo_no_permitido · 409 solo_lectura · 422 validacion · 500 error_interno.
Webhooks Salientes
Eventos: leccion.completada, alumno.nuevo, racha.lograda (3, 7, 14 y 30 días seguidos) y prueba. Hasta 3 intentos (0 s, 1 s, 3 s); cada entrega queda en el registro del Panel.
POST https://tu-servidor.com/webhook
Content-Type: application/json
X-Event: racha.lograda
X-Delivery-Id: evt_5c1e9a0b2d4f6e81
X-Signature: sha256=9f2c…
{
"id": "evt_5c1e9a0b2d4f6e81",
"event": "racha.lograda",
"created_at": "2026-10-05T04:40:00.000Z",
"data": { "user_id": "8d1f…", "streak_days": 7 }
}Cómo Verificar la Firma
Calcula HMAC-SHA256 del cuerpo exacto con el secreto del endpoint y compáralo en tiempo constante con X-Signature.
// Node.js
import crypto from "node:crypto";
export function verificar(rawBody, header, secreto) {
const esperado = "sha256=" + crypto.createHmac("sha256", secreto).update(rawBody).digest("hex");
return header && header.length === esperado.length &&
crypto.timingSafeEqual(Buffer.from(header), Buffer.from(esperado));
}# Python
import hmac, hashlib
def verificar(raw_body: bytes, header: str, secreto: str) -> bool:
esperado = "sha256=" + hmac.new(secreto.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(esperado, header or "")Webhooks Entrantes
Genera el secreto en el Panel. Envía la cabecera X-Webhook-Secret o una firma X-Signature: sha256=… del cuerpo. Usa type para el tipo de evento y ?source= para el origen.
curl -X POST "https://tu-app.lovable.app/api/v1/webhooks/in?source=pasarela-pagos" \
-H "X-Webhook-Secret: whin_tu_secreto" -H "Content-Type: application/json" \
-d '{"type":"suscripcion.pagada","email":"alumno@ejemplo.com","plan":"mensual"}'Conectar el MCP a Claude
Servidor MCP por HTTP en https://tu-app.lovable.app/mcp, con la misma clave de API. Herramientas: buscar_lecciones, ver_diagrama, registrar_progreso, sugerir_ejercicio, resumen_del_alumno.
Claude Desktop → Configuración → Desarrollador → Editar configuración (claude_desktop_config.json):
{
"mcpServers": {
"maestro-tres-bandas-10k": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://tu-app.lovable.app/mcp",
"--header",
"Authorization: Bearer ${MTB_API_KEY}"
],
"env": {
"MTB_API_KEY": "mtb_tu_clave_aqui"
}
}
}
}Claude Code (terminal):
claude mcp add --transport http maestro-tres-bandas-10k https://tu-app.lovable.app/mcp \
--header "Authorization: Bearer mtb_tu_clave_aqui"Prueba rápida:
curl -X POST "https://tu-app.lovable.app/mcp" -H "Authorization: Bearer $MTB_API_KEY" \
-H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"sugerir_ejercicio","arguments":{}}}'