Conecta tus clases con hojas de cálculo, plataformas escolares o tus propias apps. Por privacidad infantil, la API solo entrega apodos e IDs internos, nunca nombres reales.
Entra como profe → Panel → 🔌 Integraciones → Crear llave. Cópiala en ese momento (empieza con nsk_); puedes revocarla cuando quieras. Cada llave solo ve tus propias clases.
Authorization: Bearer nsk_tu_llave
URL base: https://tu-app.lovable.app/api/public/v1
/clasesLista tus clases con su código de acceso.
/clasesCrea una clase. Cuerpo: { "nombre": "6°A" }
/clases/{id}/alumnosAlumnos de una clase: apodo, XP, nivel, coins.
/alumnos/{id}/progresoXP reciente, logros y misiones completadas.
/alumnos/{id}/premiarDa premio. Cuerpo: { "xp": 50, "coins": 10, "motivo": "Gran idea", "insignia": "" } (xp ≤ 1000, coins ≤ 500).
/misionesMisiones activas del juego.
curl https://tu-app.lovable.app/api/public/v1/clases \
-H "Authorization: Bearer nsk_tu_llave"
curl -X POST https://tu-app.lovable.app/api/public/v1/alumnos/ID_ALUMNO/premiar \
-H "Authorization: Bearer nsk_tu_llave" \
-H "Content-Type: application/json" \
-d '{"xp":50,"coins":10,"motivo":"Mejor prompt"}'Errores: 401 llave inválida o revocada · 400 datos inválidos · 404 no existe o no es de tus clases. Siempre responden { "error": "mensaje" }.
En 🔌 Integraciones registra una URL https:// y elige eventos. Te enviaremos un POST JSON cuando ocurran en tus clases:
mision.completada — un alumno completó una misión (lección).logro.obtenido — un alumno ganó una insignia.progreso.actualizado — un alumno ganó XP.POST https://tu-servidor.com/webhook
X-Nova-Evento: logro.obtenido
X-Nova-Entrega: 7b1c… (único por entrega, úsalo para no duplicar)
X-Nova-Firma: t=1759600000,v1=5f2a…
{ "id": "7b1c…", "evento": "logro.obtenido", "fecha": "2026-10-04T15:00:00Z",
"alumno": { "id": "…", "apodo": "LavaFox", "clase_id": "…", "xp": 340, "nivel": 2, "coins": 80 },
"datos": { "insignia": "FIRST_PROMPT", "nombre": "Primer prompt" } }Firma: calcula HMAC-SHA256 con el secreto del webhook sobre `${t}.${cuerpo}` y compáralo con v1. Rechaza si t tiene más de 5 minutos.
// Node.js
import crypto from "node:crypto";
const [t, v1] = req.headers["x-nova-firma"].split(",").map(p => p.split("=")[1]);
const esperado = crypto.createHmac("sha256", SECRETO).update(`${t}.${cuerpoCrudo}`).digest("hex");
const valido = crypto.timingSafeEqual(Buffer.from(esperado), Buffer.from(v1));Reintentos: responde con un código 2xx en menos de 10 s. Si falla, reintentamos a los 1, 5, 15, 60 y 240 minutos (6 intentos en total) y luego la marcamos como fallida. Ves cada entrega, su estado y la respuesta en Integraciones → Entregas.