Pular para o conteúdo
Studeia

API Pública — Studeia

Integre sua instituição com a plataforma Studeia

Autenticação

Inclua a chave no header Authorization:

Como obter uma chave

Acesse o painel institucional, vá em Configurações > Chaves de API e crie uma nova chave.

Exemplo de Request

curl -X GET \
  https://seu-dominio.com/api/institution/courses \
  -H "Authorization: Bearer mia_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0"

JavaScript / TypeScript

const response = await fetch("https://seu-dominio.com/api/institution/courses", {
  headers: {
    "Authorization": "Bearer mia_a1b2c3d4...",
    "Content-Type": "application/json",
  },
});
const data = await response.json();

Prefere OAuth com a sua conta? Use o conector MCP

Além das chaves mia_, cada instituição expõe um servidor MCP em /api/mcp: o ChatGPT, o Claude e o Claude Code se conectam via OAuth 2.1 com a conta do usuário (token mcp_at_) e usam as mesmas permissões da web — sem chave compartilhada, com auditoria por chamada.

Ver o guia do conector MCP →

Rate Limits

Requisições são limitadas por chave de API:

TierLimite/horaBurst/min
standard1.000100
high5.000300
customCustomcustom/60

Headers de rate limit retornados:

HeaderDescrição
X-RateLimit-LimitRequest limit per hour
X-RateLimit-RemainingRemaining requests in window
X-RateLimit-ResetEpoch timestamp of window reset
Retry-AfterSeconds until retry (only on 429)

Códigos de Erro

CódigoStatusDescrição
400Bad RequestParâmetros inválidos ou ausentes
401UnauthorizedAPI key inválida, expirada ou revogada
403ForbiddenScope insuficiente ou acesso negado
404Not FoundRecurso não encontrado
409ConflictConflito (ex: slug duplicado)
429Too Many RequestsRate limit excedido. Ver header Retry-After
500Internal Server ErrorErro interno do servidor

Respostas de erro seguem o formato:

{
  "error": "Descriptive error message"
}

Paginação

Endpoints que retornam listas suportam paginação:

ParamTypeDefaultDescrição
pagenumber1Page number
limitnumber20Items per page (max 50)

Exemplo de Response

{
  "success": true,
  "data": [...],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 142,
    "totalPages": 8
  }
}

Scopes

Chaves de API podem ter scopes restritos:

ScopeDescrição
courses:readListar e visualizar cursos, módulos, aulas e templates
courses:writeCriar, editar, publicar, clonar e deletar cursos
users:readListar e visualizar usuários do tenant
users:writeCriar, editar e deletar usuários
enrollments:readListar matrículas
enrollments:writeCriar e gerenciar matrículas
classes:readListar turmas
classes:writeCriar e gerenciar turmas
media:readListar arquivos e pastas de mídia
media:writeRegistrar, editar e deletar mídias
grades:readVisualizar notas e gradebook
grades:writeLançar notas e gerenciar categorias
rubrics:readListar rubricas
rubrics:writeCriar e editar rubricas
question-banks:readListar bancos de questões
question-banks:writeCriar e editar questões
live-classes:readListar aulas ao vivo
live-classes:writeCriar, iniciar e encerrar aulas ao vivo
tags:readListar tags
tags:writeCriar e gerenciar tags
invites:readListar convites
invites:writeCriar e gerenciar convites
lti:readListar ferramentas LTI
lti:writeRegistrar e editar ferramentas LTI
settings:readVisualizar configurações do tenant
settings:writeEditar configurações, temas e perfil
reports:readVisualizar relatórios e exportar dados
ai:readVisualizar prompts e limites de IA
ai:writeGerar conteúdo com IA e editar configurações
automations:readListar e visualizar automações
automations:writeCriar, editar, ativar e deletar automações
gamification:readVisualizar gamificação (config, badges, leaderboard, contests, analytics)
gamification:writeCriar, editar badges, contests e configurar gamificação
drive:readListar integrações Google Drive / OneDrive e logs de sincronização
drive:writeConectar, sincronizar e remover integrações Google Drive / OneDrive

Instituição

Informações e configurações gerais do tenant

GET/api/institution

Retorna informações da instituição (nome, slug, logo, cores, config).

Scopes:settings:read

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "Escola XYZ",
    "slug": "escola-xyz",
    "logoUrl": "https://...",
    "primaryColor": "#3b82f6",
    "config": {}
  }
}

Cursos

CRUD de cursos, módulos, aulas, templates e geração automática

GET/api/institution/courses

Lista cursos do tenant com paginação e filtros.

Scopes:courses:read

Query Parameters

ParamTypeDefaultDescrição
statusstring—Filtrar por status: draft | published | archived
templatesbooleanfalseSe true, lista templates em vez de cursos
pagenumber1Página
limitnumber20Itens por página (max 50)

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "title": "Curso de Exemplo",
      "slug": "curso-exemplo",
      "status": "published"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 42,
    "totalPages": 3
  }
}
POST/api/institution/courses

Cria um novo curso. Pode criar a partir de template com fromTemplateId.

Scopes:courses:write

Body Parameters

FieldTypeObrigatórioDescrição
titlestringObrigatórioTítulo do curso
slugstringObrigatórioSlug único (URL-friendly)
descriptionstringOpcionalDescrição do curso
fromTemplateIdstringOpcionalID do template para clonar

Exemplo de Request

{
  "title": "Matemática Básica",
  "slug": "mat-basica",
  "description": "Curso introdutório"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "title": "Matemática Básica",
    "slug": "mat-basica",
    "status": "draft"
  }
}
PATCH/api/institution/courses/{id}

Atualiza um curso.

Scopes:courses:write

Body Parameters

FieldTypeObrigatórioDescrição
titlestringOpcionalNovo título
descriptionstringOpcionalNova descrição
statusstringOpcionaldraft | published | archived

Exemplo de Request

{
  "title": "Matemática Avançada"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "title": "Matemática Avançada"
  }
}
DELETE/api/institution/courses/{id}

Deleta um curso e todos os seus módulos e aulas.

Scopes:courses:write

Exemplo de Response

{
  "success": true,
  "message": "Curso deletado com sucesso"
}
POST/api/institution/courses/{id}/publish

Publica um curso (muda status para published).

Scopes:courses:write

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "status": "published"
  }
}
POST/api/institution/courses/{id}/clone

Clona um curso inteiro (deep copy incluindo módulos e aulas).

Scopes:courses:write

Body Parameters

FieldTypeObrigatórioDescrição
newTitlestringOpcionalTítulo da cópia

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "new-uuid",
    "title": "Cópia - Curso X"
  }
}
POST/api/institution/courses/{id}/export

Exporta um curso como JSON.

Scopes:courses:read

Exemplo de Response

{
  "success": true,
  "data": {
    "course": {},
    "modules": [],
    "lessons": []
  }
}
POST/api/institution/courses/import

Importa um curso via upload de pacote IMS Common Cartridge. Content-Type: multipart/form-data com o campo `file` (.imscc ou .zip, máx. 50MB). Respostas: 201 (criado), 400 (arquivo ausente/formato inválido), 413 (acima de 50MB).

Scopes:courses:write

Body Parameters

FieldTypeObrigatórioDescrição
filefile (multipart)ObrigatórioPacote .imscc ou .zip (IMS Common Cartridge), máximo 50MB

Exemplo de Response

{
  "success": true,
  "data": {
    "courseId": "uuid",
    "title": "Curso",
    "modulesCreated": 4,
    "lessonsCreated": 36,
    "warnings": [
      {
        "title": "Aula X",
        "code": "embedded_origin_not_allowed",
        "detail": "https://tool.example/…"
      }
    ]
  }
}
POST/api/institution/courses/auto-generate

Gera um curso via IA a partir de documentos enviados (PDF/DOCX/PPTX). Sem defaultLessonType, o job para em 'awaiting_review' com a estrutura proposta (multi-tipo: rich_text, slides, quiz, assignment e interativos) para revisão + confirm. Com defaultLessonType, roda one-shot no modo legado (aulas de conteúdo só nesse tipo + quiz). Retorna jobId para polling.

Scopes:ai:writecourses:write

Body Parameters

FieldTypeObrigatórioDescrição
courseTitlestringObrigatórioTítulo do curso (1-200 chars)
courseSlugstringObrigatórioSlug único do curso no tenant
mediaAssetIdsstring[]ObrigatórioIDs de MediaAsset dos documentos fonte (1-20, PDF/DOCX/PPTX)
defaultLessonTypestringOpcionalLEGADO: 'rich_text' | 'slides' — modo one-shot conservador sem etapa de revisão
contentLocalestringOpcional'auto' (default, detecta o idioma do documento) | 'pt-BR' | 'en-US' | 'es-ES' | 'fr-FR'

Exemplo de Response

{
  "success": true,
  "data": {
    "jobId": "uuid"
  }
}
GET/api/institution/courses/auto-generate/{jobId}

Progresso da geração. stage: extracting | analyzing | structuring | awaiting_review | populating | complete | error. Em 'awaiting_review', inclui data.proposal = { structure, locale, courseTitle } para revisão.

Scopes:courses:read

Exemplo de Response

{
  "success": true,
  "data": {
    "stage": "awaiting_review",
    "percent": 50,
    "message": "Estrutura pronta para revisão.",
    "proposal": {
      "structure": {
        "modules": []
      },
      "locale": "pt-BR",
      "courseTitle": "..."
    }
  }
}
POST/api/institution/courses/auto-generate/{jobId}/confirm

Confirma a estrutura revisada (fase B): cria o curso e gera o conteúdo. Body: structure com modules[].lessons[] (title 1-200, type na allowlist gerável, sourceChunkIndices, estimatedDuration 1-120; máx 12 módulos / 60 aulas). Consome a proposta — segundo confirm retorna 404; slug ocupado durante a revisão retorna 409 sem consumir.

Scopes:ai:writecourses:write

Body Parameters

FieldTypeObrigatórioDescrição
structureobjectObrigatórioEstrutura editada: { modules: [{ title, description?, lessons: [{ title, type, sourceChunkIndices, estimatedDuration }] }] }

Exemplo de Response

{
  "success": true,
  "data": {
    "jobId": "uuid"
  }
}
DELETE/api/institution/courses/auto-generate/{jobId}

Cancela um job aguardando revisão (apaga proposta e progresso). Apenas o usuário que iniciou o job.

Scopes:courses:write

Exemplo de Response

{
  "success": true
}

Módulos

Módulos dentro de um curso

GET/api/institution/courses/{id}/modules

Lista módulos de um curso.

Scopes:courses:read

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "title": "Módulo 1",
      "sortOrder": 0
    }
  ]
}
POST/api/institution/courses/{id}/modules

Cria um módulo no curso.

Scopes:courses:write

Body Parameters

FieldTypeObrigatórioDescrição
titlestringObrigatórioTítulo do módulo
descriptionstringOpcionalDescrição
sortOrdernumberOpcionalOrdem de exibição

Exemplo de Request

{
  "title": "Introdução",
  "sortOrder": 0
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "title": "Introdução"
  }
}
PATCH/api/institution/courses/{id}/modules/{mid}

Atualiza um módulo.

Scopes:courses:write

Exemplo de Request

{
  "title": "Módulo Atualizado"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid"
  }
}

Aulas

Aulas dentro de módulos (slides, video, quiz, rich_text, pdf, assignment, live_class, external_link, interactive, lti_launch, embedded_tool)

POST/api/institution/courses/{id}/modules/{mid}/lessons

Cria uma aula no módulo.

Scopes:courses:write

Body Parameters

FieldTypeObrigatórioDescrição
titlestringObrigatórioTítulo da aula
typestringObrigatórioslides | video | quiz | rich_text | pdf_viewer | assignment | live_class | external_link | interactive | lti_launch | embedded_tool
contentobjectOpcionalConteúdo no formato JSON do tipo
sortOrdernumberOpcionalOrdem de exibição
teacherGuideobjectOpcionalMaterial do professor (só docentes; NUNCA devolvido a alunos nem ao tutor de IA): summary, keyTopics[], objectives[], skillsTaught[], skillsAssessed[], competencyCodes[], medIntegration, materials[], localContext, durationPlan{theoryMin,labMin,closureMin}, script[{minute,say,show,ask}], labSpec{mechanics,validationRules[],commonErrors[],audioSupport}, assessment{criteria[],badgeName,descriptiveReportCriteria[]}

Exemplo de Request

{
  "title": "Aula 1",
  "type": "rich_text",
  "content": {
    "html": "<h1>Olá</h1>"
  },
  "teacherGuide": {
    "summary": "Primeiro contacto com o computador.",
    "objectives": [
      "Identificar 4 componentes"
    ],
    "competencyCodes": [
      "CD3.U1.1"
    ],
    "durationPlan": {
      "theoryMin": 20,
      "labMin": 35,
      "closureMin": 5
    }
  }
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "title": "Aula 1",
    "type": "rich_text"
  }
}
PATCH/api/institution/courses/{id}/modules/{mid}/lessons/{lid}

Atualiza uma aula (campos opcionais; null remove prerequisiteLessonId/dueDate/minScore/publishAt/teacherGuide).

Scopes:courses:write

Body Parameters

FieldTypeObrigatórioDescrição
titlestringOpcionalNovo título
contentobjectOpcionalConteúdo JSON completo do tipo
durationnumberOpcionalDuração em minutos
isPublishedbooleanOpcionalPublicar/despublicar
teacherGuideobject | nullOpcionalMaterial do professor completo (substitui; null remove). Só docentes — nunca devolvido a alunos.

Exemplo de Request

{
  "title": "Aula Atualizada",
  "content": {
    "html": "<p>Novo conteúdo</p>"
  }
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid"
  }
}
POST/api/institution/courses/{id}/modules/{mid}/lessons/{lid}/populate

Gera conteúdo da aula via IA a partir de documento ou descrição.

Scopes:ai:writecourses:write

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "content": {}
  }
}

Requer créditos de IA suficientes.

Usuários

Gerenciamento de usuários do tenant

GET/api/institution/users

Lista usuários do tenant com filtros.

Scopes:users:read

Query Parameters

ParamTypeDefaultDescrição
rolestring—Filtrar por role
searchstring—Buscar por nome ou email
pagenumber1Página
limitnumber20Itens por página

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "name": "João",
      "email": "joao@email.com",
      "role": "student"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 150,
    "totalPages": 8
  }
}
POST/api/institution/users

Cria um novo usuário no tenant.

Scopes:users:write

Body Parameters

FieldTypeObrigatórioDescrição
emailstringObrigatórioEmail do usuário
namestringObrigatórioNome completo
rolestringObrigatóriostudent | teacher | coordinator | pedagogue
passwordstringOpcionalSenha (se não informada, convite será enviado)

Exemplo de Request

{
  "email": "maria@escola.com",
  "name": "Maria Silva",
  "role": "student"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "email": "maria@escola.com"
  }
}
GET/api/institution/users/{id}

Detalhes de um usuário.

Scopes:users:read

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "João",
    "role": "student"
  }
}
PATCH/api/institution/users/{id}

Atualiza dados do usuário.

Scopes:users:write

Exemplo de Request

{
  "name": "João Atualizado",
  "role": "teacher"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid"
  }
}
DELETE/api/institution/users/{id}

Remove usuário do tenant.

Scopes:users:write

Exemplo de Response

{
  "success": true,
  "message": "Usuário removido"
}

Matrículas

Gerenciamento de matrículas (enrollment) de alunos em cursos

GET/api/institution/enrollments

Lista matrículas com filtros.

Scopes:enrollments:read

Query Parameters

ParamTypeDefaultDescrição
courseIdstring—Filtrar por curso
studentIdstring—Filtrar por aluno
statusstring—active | completed | paused | cancelled
pagenumber1Página
limitnumber20Itens por página

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "studentId": "uuid",
      "courseId": "uuid",
      "status": "active",
      "progressPct": 45
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 100,
    "totalPages": 5
  }
}
POST/api/institution/enrollments

Matricula um aluno em um curso.

Scopes:enrollments:write

Body Parameters

FieldTypeObrigatórioDescrição
studentIdstringObrigatórioID do aluno
courseIdstringObrigatórioID do curso
classGroupIdstringOpcionalID da turma (opcional)

Exemplo de Request

{
  "studentId": "uuid",
  "courseId": "uuid"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "status": "active",
    "progressPct": 0
  }
}
DELETE/api/institution/enrollments

Cancela matrícula.

Scopes:enrollments:write

Exemplo de Response

{
  "success": true,
  "message": "Matrícula cancelada"
}

Turmas

Gerenciamento de turmas (class groups)

GET/api/institution/classes

Lista turmas do tenant.

Scopes:classes:read

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "name": "Turma A",
      "courseId": "uuid",
      "teacherId": "uuid",
      "isActive": true
    }
  ]
}
POST/api/institution/classes

Cria uma turma.

Scopes:classes:write

Body Parameters

FieldTypeObrigatórioDescrição
namestringObrigatórioNome da turma
courseIdstringObrigatórioID do curso
teacherIdstringObrigatórioID do professor
maxStudentsnumberOpcionalLimite de alunos

Exemplo de Request

{
  "name": "Turma A - 2026",
  "courseId": "uuid",
  "teacherId": "uuid"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "Turma A - 2026"
  }
}

Mídia

Biblioteca de mídia (assets e pastas)

GET/api/institution/media

Lista assets de mídia com filtros.

Scopes:media:read

Query Parameters

ParamTypeDefaultDescrição
folderIdstring—Filtrar por pasta
fileTypestring—pdf | image | video | audio | docx | pptx | other
searchstring—Buscar por nome
pagenumber1Página
limitnumber20Itens por página

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "fileName": "aula.pdf",
      "fileType": "pdf",
      "storageUrl": "https://..."
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 35,
    "totalPages": 2
  }
}
POST/api/institution/media/upload-url

Emite uma signed upload URL para o bucket de mídia. Faça PUT do arquivo em `uploadUrl` e depois registre o asset em POST /api/institution/media com `storageUrl = publicUrl`. O path é definido pelo servidor ({tenantId}/{purpose}/…).

Scopes:media:write

Body Parameters

FieldTypeObrigatórioDescrição
fileNamestringObrigatórioNome original do arquivo (só a extensão é usada no path)
mimeTypestringObrigatórioMIME type (HTML/JS executável são rejeitados)
fileSizeBytesnumberObrigatórioTamanho em bytes (máx. 500 MB; verificado contra a quota do tenant)
purposestringObrigatóriomedia-library | documents | course-material
courseIdstringOpcionalObrigatório quando purpose = course-material (valida edição do curso)

Exemplo de Request

{
  "fileName": "apostila.pdf",
  "mimeType": "application/pdf",
  "fileSizeBytes": 1048576,
  "purpose": "media-library"
}

Exemplo de Response

{
  "uploadUrl": "https://<projeto>.supabase.co/storage/v1/object/upload/sign/...",
  "storagePath": "<tenantId>/media-library/1758000000000-abc123.pdf",
  "publicUrl": "https://<projeto>.supabase.co/storage/v1/object/public/<bucket>/<tenantId>/media-library/1758000000000-abc123.pdf"
}
POST/api/institution/media

Registra um asset de mídia (após PUT na signed URL de /media/upload-url).

Scopes:media:write

Body Parameters

FieldTypeObrigatórioDescrição
fileNamestringObrigatórioNome do arquivo
fileTypestringObrigatórioTipo do arquivo
mimeTypestringObrigatórioMIME type
fileSizeBytesnumberObrigatórioTamanho em bytes
storageUrlstringObrigatórioURL no Supabase Storage
folderIdstringOpcionalID da pasta

Exemplo de Request

{
  "fileName": "aula.pdf",
  "fileType": "pdf",
  "mimeType": "application/pdf",
  "fileSizeBytes": 1048576,
  "storageUrl": "https://..."
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "fileName": "aula.pdf"
  }
}
GET/api/institution/media/{id}/versions

Lista histórico de versões de um asset.

Scopes:media:read

Exemplo de Response

{
  "success": true,
  "data": {
    "currentVersion": 3,
    "versions": [
      {
        "versionNumber": 2,
        "fileSizeBytes": 1048576,
        "createdAt": "2026-03-23"
      }
    ]
  }
}
POST/api/institution/media/{id}/versions

Envia nova versão de um asset. O arquivo atual vira versão anterior.

Scopes:media:write

Body Parameters

FieldTypeObrigatórioDescrição
storageUrlstringObrigatórioURL do novo arquivo no Storage
fileSizeBytesnumberObrigatórioTamanho em bytes
changelogstringOpcionalDescrição das alterações

Exemplo de Response

{
  "success": true,
  "data": {
    "currentVersion": 3
  }
}
POST/api/institution/media/{id}/versions/{v}/restore

Restaura uma versão anterior. O arquivo atual vira versão.

Scopes:media:write

Exemplo de Response

{
  "success": true,
  "data": {
    "restoredVersion": 1,
    "currentVersion": 4
  }
}
GET/api/institution/media/{id}/analytics

Analíticas de acesso de um asset (views, downloads, previews).

Scopes:media:read

Query Parameters

ParamTypeDefaultDescrição
periodstring30dPeríodo: 7d | 30d | 90d

Exemplo de Response

{
  "success": true,
  "data": {
    "totalViews": 42,
    "totalDownloads": 10,
    "uniqueUsers": 8
  }
}
POST/api/institution/media/{id}/analytics

Registra evento de acesso (view, download, preview).

Scopes:media:read

Body Parameters

FieldTypeObrigatórioDescrição
actionstringObrigatórioview | download | preview
contextstringOpcionalContexto: lesson:uuid, forum:uuid, share:token

Exemplo de Response

{
  "success": true
}
GET/api/institution/media/{id}/transcription

Status e texto da transcrição de um asset de áudio/vídeo.

Scopes:media:read

Exemplo de Response

{
  "success": true,
  "data": {
    "status": "completed",
    "text": "...",
    "language": "pt-BR",
    "wordCount": 342
  }
}
POST/api/institution/media/{id}/transcription

Inicia transcrição (Whisper → Google STT fallback). Executa em background.

Scopes:media:write

Body Parameters

FieldTypeObrigatórioDescrição
languagestringOpcionalIdioma (pt-BR, en-US, auto). Default: auto

Exemplo de Response

{
  "success": true,
  "data": {
    "status": "pending"
  }
}
DELETE/api/institution/media/{id}/transcription

Remove dados de transcrição de um asset.

Scopes:media:write

Exemplo de Response

{
  "success": true
}
POST/api/institution/media/{id}/transcription/ingest

Ingere transcrição concluída no RAG do tenant (chunking + embeddings).

Scopes:media:write

Exemplo de Response

{
  "success": true,
  "data": {
    "chunksCreated": 5
  }
}

Notas (Gradebook)

Sistema de notas: categorias, itens avaliativos e lançamento de notas

GET/api/institution/gradebook/{courseId}

Retorna o gradebook completo de um curso (categorias, itens e notas).

Scopes:grades:read

Exemplo de Response

{
  "success": true,
  "data": {
    "categories": [
      {
        "id": "uuid",
        "name": "Provas",
        "weight": 60
      }
    ],
    "items": [
      {
        "id": "uuid",
        "name": "Prova 1",
        "maxScore": 100,
        "categoryId": "uuid"
      }
    ],
    "grades": [
      {
        "studentId": "uuid",
        "itemId": "uuid",
        "score": 85
      }
    ]
  }
}
POST/api/institution/gradebook/{courseId}/grades

Lança ou atualiza nota de um aluno.

Scopes:grades:write

Body Parameters

FieldTypeObrigatórioDescrição
studentIdstringObrigatórioID do aluno
gradeItemIdstringObrigatórioID do item avaliativo
scorenumberObrigatórioNota (0 a maxScore)
feedbackstringOpcionalFeedback textual

Exemplo de Request

{
  "studentId": "uuid",
  "gradeItemId": "uuid",
  "score": 85
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "score": 85
  }
}
POST/api/institution/gradebook/{courseId}/export

Exporta notas em formato CSV.

Scopes:reports:readgrades:read

Exemplo de Response

{
  "success": true,
  "data": {
    "csv": "Student,Grade\nJoão,85\nMaria,92"
  }
}
POST/api/institution/gradebook/ai-grade

Corrige atividade automaticamente com IA.

Scopes:ai:writegrades:write

Exemplo de Response

{
  "success": true,
  "data": {
    "score": 78,
    "feedback": "Boa resposta, mas..."
  }
}

Consome créditos de IA.

GET/api/institution/gradebook/{courseId}/competency-report

Domínio por competência do curso (média ponderada das notas dos itens vinculados). Filtros opcionais por aluno ou turma.

Scopes:grades:read

Query Parameters

ParamTypeDefaultDescrição
studentIdstring—Filtrar por um aluno
classGroupIdstring—Filtrar por uma turma

Exemplo de Response

{
  "success": true,
  "data": {
    "competencies": [
      {
        "code": "EF04MA01",
        "framework": "BNCC — Base Nacional Comum Curricular",
        "description": "Ler, escrever e ordenar números naturais...",
        "area": "Matemática",
        "masteryPct": 82,
        "gradedCount": 14,
        "itemCount": 3
      }
    ],
    "byArea": [
      {
        "area": "Matemática",
        "avgMasteryPct": 78,
        "competencyCount": 12
      }
    ],
    "unknownCodes": []
  }
}

Competências & Frameworks

Frameworks curriculares de avaliação (BNCC, Common Core, custom) e competências do tenant. Os códigos são vinculados aos itens do gradebook (GradeItem.competencyCodes).

GET/api/institution/competency-frameworks

Lista frameworks do catálogo global da plataforma (ativos) e frameworks custom do tenant, com contagem de competências.

Scopes:grades:read

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "slug": "bncc",
      "name": "BNCC — Base Nacional Comum Curricular",
      "country": "BR",
      "isGlobal": true,
      "catalogCount": 207,
      "tenantCount": 207
    }
  ]
}
POST/api/institution/competency-frameworks

Cria um framework custom do tenant.

Scopes:grades:write

Body Parameters

FieldTypeObrigatórioDescrição
namestringObrigatórioNome do framework
descriptionstringOpcionalDescrição
countrystringOpcionalPaís (ISO 3166-1 alpha-2, ex: BR)
localestringOpcionalLocale do conteúdo (ex: pt-BR)
versionstringOpcionalVersão do framework

Exemplo de Request

{
  "name": "Currículo Interno 2026",
  "country": "BR"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "slug": "curriculo-interno-2026"
  }
}
POST/api/institution/competency-frameworks/{id}/import

Importa (copia) as competências do catálogo global do framework para o tenant. Idempotente: códigos já existentes são pulados.

Scopes:grades:write

Exemplo de Response

{
  "success": true,
  "data": {
    "imported": 207,
    "skipped": 0
  }
}
GET/api/institution/competencies

Lista as competências do tenant. Filtros: ?frameworkId= | ?framework= (legado).

Scopes:grades:read

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "code": "EF04MA01",
      "description": "Ler, escrever e ordenar números naturais...",
      "area": "Matemática",
      "stage": "Ensino Fundamental — 4º ano",
      "frameworkRef": {
        "id": "uuid",
        "slug": "bncc",
        "name": "BNCC — Base Nacional Comum Curricular"
      }
    }
  ]
}
POST/api/institution/competencies

Cadastra uma competência do tenant.

Scopes:grades:write

Body Parameters

FieldTypeObrigatórioDescrição
frameworkIdstringOpcionalFramework (global ou do tenant)
codestringObrigatórioCódigo (ex: EF04MA01)
descriptionstringObrigatórioDescrição da competência
areastringOpcionalÁrea do conhecimento
stagestringOpcionalEtapa/segmento

Exemplo de Request

{
  "frameworkId": "uuid",
  "code": "EF04MA01",
  "description": "Ler, escrever..."
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "code": "EF04MA01"
  }
}
POST/api/institution/competencies/import

Import em lote (CSV/TSV parseado no cliente) de competências vinculadas a um framework. Máx. 2000 linhas; códigos existentes são pulados.

Scopes:grades:write

Body Parameters

FieldTypeObrigatórioDescrição
frameworkIdstringObrigatórioFramework de destino
rowsarrayObrigatório[{ code, description, area?, stage? }]

Exemplo de Response

{
  "success": true,
  "data": {
    "imported": 120,
    "skipped": 3
  }
}
PATCH/api/institution/competencies/{id}

Edita uma competência do tenant (itens do catálogo global não são editáveis).

Scopes:grades:write

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid"
  }
}
DELETE/api/institution/competencies/{id}

Remove uma competência do tenant.

Scopes:grades:write

Exemplo de Response

{
  "success": true
}

Rubricas

Rubricas de avaliação reutilizáveis

GET/api/institution/rubrics

Lista rubricas do tenant.

Scopes:rubrics:read

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "name": "Rubrica de Redação",
      "criteria": []
    }
  ]
}
POST/api/institution/rubrics

Cria uma rubrica.

Scopes:rubrics:write

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "Nova Rubrica"
  }
}

Banco de Questões

Bancos de questões para quizzes e avaliações

GET/api/institution/question-banks

Lista bancos de questões.

Scopes:question-banks:read

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "name": "Banco de Matemática",
      "questionCount": 45
    }
  ]
}
POST/api/institution/question-banks

Cria um banco de questões.

Scopes:question-banks:write

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "Novo Banco"
  }
}
POST/api/institution/question-banks/generate

Gera questões automaticamente com IA.

Scopes:ai:writequestion-banks:write

Exemplo de Response

{
  "success": true,
  "data": {
    "questions": []
  }
}

Consome créditos de IA.

Aulas ao Vivo

Aulas ao vivo com suporte multi-provider (BBB, Zoom, Teams, Google Meet)

GET/api/institution/live-classes

Lista aulas ao vivo.

Scopes:live-classes:read

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "title": "Aula ao Vivo #1",
      "scheduledStart": "2026-03-15T14:00:00Z",
      "status": "scheduled",
      "videoProvider": "zoom"
    }
  ]
}
POST/api/institution/live-classes

Agenda uma aula ao vivo. Campo videoProvider opcional (bbb, zoom, teams, google_meet).

Scopes:live-classes:write

Body Parameters

FieldTypeObrigatórioDescrição
titlestringObrigatórioTítulo da aula
videoProviderstringOpcionalProvider: bbb | zoom | teams | google_meet (default: provider padrão do tenant)

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "title": "Nova Aula",
    "videoProvider": "zoom"
  }
}
POST/api/institution/live-classes/{id}/start

Inicia a aula (cria meeting no provider configurado).

Scopes:live-classes:write

Exemplo de Response

{
  "success": true,
  "data": {
    "joinUrl": "https://zoom.us/j/...",
    "providerJoinUrl": "https://zoom.us/j/...",
    "videoProvider": "zoom"
  }
}
POST/api/institution/live-classes/{id}/join

Obtém URL de entrada. Retorna joinMethod (iframe para BBB, external para Zoom/Teams/Meet).

Scopes:live-classes:read

Exemplo de Response

{
  "success": true,
  "data": {
    "joinUrl": "https://...",
    "joinMethod": "external",
    "videoProvider": "zoom"
  }
}
POST/api/institution/live-classes/{id}/end

Encerra a aula ao vivo.

Scopes:live-classes:write

Exemplo de Response

{
  "success": true,
  "message": "Aula encerrada"
}

Provedores de Vídeo

Configuração de provedores de videoconferência (Zoom, Teams, Google Meet)

GET/api/institution/video-provider/config

Lista provedores de videoconferência configurados para o tenant.

Scopes:settings:read

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "provider": "zoom",
      "isEnabled": true,
      "isDefault": true,
      "config": {}
    }
  ]
}
POST/api/institution/video-provider/config

Cria ou atualiza configuração de provider. Credenciais são criptografadas com AES-256-GCM.

Scopes:settings:write

Body Parameters

FieldTypeObrigatórioDescrição
providerstringObrigatóriobbb | zoom | teams | google_meet
credentialsobjectObrigatórioCredenciais do provider (shape varia)
isDefaultbooleanOpcionalDefinir como provider padrão

Exemplo de Request

{
  "provider": "zoom",
  "credentials": {
    "accountId": "...",
    "clientId": "...",
    "clientSecret": "..."
  },
  "isDefault": true
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "provider": "zoom",
    "isEnabled": true,
    "isDefault": true
  }
}
DELETE/api/institution/video-provider/config?provider=zoom

Remove configuração de provider.

Scopes:settings:write

Exemplo de Response

{
  "success": true
}
GET/api/institution/video-provider/connect/google-meet

Redireciona para OAuth do Google para autenticação do Google Meet.

Scopes:settings:write

Exemplo de Response

"Redirect para accounts.google.com"

Webhooks de Vídeo

Endpoints de webhook para provedores de videoconferência (não requerem autenticação de API key)

POST/api/webhooks/video/zoom

Recebe eventos do Zoom (meeting lifecycle, recordings, attendance). Validado via x-zm-signature.

Scopes:

Exemplo de Response

{
  "status": "ok"
}
POST/api/webhooks/video/teams

Recebe notificações do Microsoft Graph para Teams. Suporta validação de subscription.

Scopes:

Exemplo de Response

{
  "status": "ok"
}

Convites

Convites para ingressar no tenant

GET/api/institution/invites

Lista convites.

Scopes:invites:read

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "email": "novo@email.com",
      "role": "student",
      "status": "pending"
    }
  ]
}
POST/api/institution/invites

Cria um convite.

Scopes:invites:write

Body Parameters

FieldTypeObrigatórioDescrição
emailstringObrigatórioEmail do convidado
rolestringObrigatórioRole do convidado

Exemplo de Request

{
  "email": "professor@escola.com",
  "role": "teacher"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "token": "invite-token"
  }
}
POST/api/institution/invites/bulk

Valida e importa convites em massa a partir de CSV (colunas email, name, role — máx. 500 linhas). mode=validate retorna preview; mode=import re-valida e cria convites só para as linhas válidas.

Scopes:invites:write

Body Parameters

FieldTypeObrigatórioDescrição
csvContentstringObrigatórioConteúdo do arquivo CSV (cabeçalho email,name,role)
modestringObrigatório"validate" (preview) ou "import" (cria convites)

Exemplo de Request

{
  "csvContent": "email,name,role\njoao@escola.com,João,teacher",
  "mode": "validate"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "mode": "validate",
    "totalRows": 1,
    "validRows": [
      {
        "line": 2,
        "email": "joao@escola.com",
        "name": "João",
        "role": "teacher"
      }
    ],
    "invalidRows": [],
    "summary": {
      "valid": 1,
      "invalid": 0
    }
  }
}

Tags

Tags para categorização de usuários

GET/api/institution/tags

Lista tags do tenant.

Scopes:tags:read

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "name": "Turma 2026",
      "color": "#3b82f6"
    }
  ]
}
POST/api/institution/tags

Cria uma tag.

Scopes:tags:write

Exemplo de Request

{
  "name": "Bolsista",
  "color": "#10b981"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "Bolsista"
  }
}

LTI

Integração LTI 1.3 (ferramentas externas)

GET/api/institution/lti-tools

Lista ferramentas LTI registradas.

Scopes:lti:read

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "name": "Ferramenta X",
      "clientId": "..."
    }
  ]
}
POST/api/institution/lti-tools

Registra uma ferramenta LTI.

Scopes:lti:write

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid"
  }
}

Ferramentas Incorporadas

Allowlist de origens externas embutíveis em aulas do tipo embedded_tool (iframe sandboxado na página do aluno)

GET/api/institution/embedded-tools

Lista as origens permitidas do tenant.

Scopes:settings:read

Exemplo de Response

{
  "tools": [
    {
      "id": "uuid",
      "origin": "https://blockly.games",
      "label": "Blockly Games",
      "isActive": true
    }
  ]
}
POST/api/institution/embedded-tools

Adiciona uma origem à allowlist. Origem https exata sem caminho; domínios da própria plataforma são rejeitados.

Scopes:settings:write

Body Parameters

FieldTypeObrigatórioDescrição
originstringObrigatórioEx.: https://blockly.games
labelstringOpcionalNome de exibição (opcional)

Exemplo de Request

{
  "origin": "https://blockly.games",
  "label": "Blockly Games"
}

Exemplo de Response

{
  "id": "uuid",
  "origin": "https://blockly.games",
  "label": "Blockly Games",
  "isActive": true
}
PATCH/api/institution/embedded-tools/{id}

Edita o label ou ativa/pausa uma origem.

Scopes:settings:write

Body Parameters

FieldTypeObrigatórioDescrição
labelstringOpcionalNovo nome de exibição
isActivebooleanOpcionalAtiva/pausa a origem

Exemplo de Response

{
  "id": "uuid",
  "origin": "https://blockly.games",
  "isActive": false
}
DELETE/api/institution/embedded-tools/{id}

Remove a origem da allowlist (aulas que a usam ficam com o iframe bloqueado).

Scopes:settings:write

Exemplo de Response

{
  "success": true
}

Configurações

White-label, temas visuais, configurações de perfil e IA

GET/api/institution/settings

Retorna configurações do tenant (white-label, BBB, etc).

Scopes:settings:read

Exemplo de Response

{
  "success": true,
  "data": {
    "name": "Escola",
    "logoUrl": "...",
    "config": {}
  }
}
PATCH/api/institution/settings

Atualiza configurações do tenant.

Scopes:settings:write

Exemplo de Request

{
  "name": "Escola Nova",
  "primaryColor": "#ff0000"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "name": "Escola Nova"
  }
}
GET/api/institution/ai-limits

Retorna limites de IA configurados.

Scopes:ai:read

Exemplo de Response

{
  "success": true,
  "data": {
    "dailyMessageLimit": 50
  }
}
POST/api/institution/ai-limits

Configura limites globais de IA para alunos.

Scopes:ai:write

Exemplo de Request

{
  "dailyMessageLimit": 100
}

Exemplo de Response

{
  "success": true,
  "data": {
    "dailyMessageLimit": 100
  }
}
GET/api/institution/task-routing

Retorna roteamento de modelos por tarefa (overrides do tenant + global + padrão).

Scopes:ai:read

Exemplo de Response

{
  "success": true,
  "data": {
    "configs": [
      {
        "taskType": "chat_tutor",
        "displayName": "Chat com Tutor",
        "primaryModel": "claude-sonnet-4-6",
        "primaryProvider": "anthropic",
        "fallback1Model": "gpt-4o",
        "fallback1Provider": "openai",
        "fallback2Model": null,
        "fallback2Provider": null,
        "temperature": 0.7,
        "maxOutputTokens": 2000,
        "isEnabled": true,
        "source": "tenant"
      }
    ],
    "availableModels": [
      {
        "modelId": "claude-sonnet-4-6",
        "displayName": "Claude Sonnet",
        "provider": "anthropic"
      }
    ]
  }
}
PUT/api/institution/task-routing

Salva overrides de roteamento de modelos por tarefa para o tenant.

Scopes:ai:write

Body Parameters

FieldTypeObrigatórioDescrição
configsarrayObrigatórioArray de configurações por tarefa
configs[].taskTypestringObrigatórioTipo da tarefa (chat_tutor, question_correction, etc)
configs[].primaryModelstringObrigatórioID do modelo principal
configs[].primaryProviderstringObrigatórioProvider do modelo principal (anthropic, openai, google)
configs[].fallback1ModelstringOpcionalID do modelo fallback 1
configs[].fallback1ProviderstringOpcionalProvider do fallback 1
configs[].fallback2ModelstringOpcionalID do modelo fallback 2
configs[].fallback2ProviderstringOpcionalProvider do fallback 2
configs[].temperaturenumberObrigatórioTemperatura (0.0 a 1.0)
configs[].maxOutputTokensnumberObrigatórioMax tokens de saída
configs[].isEnabledbooleanObrigatórioSe o override está ativo

Exemplo de Request

{
  "configs": [
    {
      "taskType": "chat_tutor",
      "primaryModel": "claude-sonnet-4-6",
      "primaryProvider": "anthropic",
      "fallback1Model": "gpt-4o",
      "fallback1Provider": "openai",
      "fallback2Model": null,
      "fallback2Provider": null,
      "temperature": 0.7,
      "maxOutputTokens": 2000,
      "isEnabled": true
    }
  ]
}

Exemplo de Response

{
  "success": true,
  "data": {
    "updated": 1
  }
}
DELETE/api/institution/task-routing

Remove overrides de roteamento (reverte para global). Use ?taskType=X para uma tarefa ou sem parâmetro para todas.

Scopes:ai:write

Query Parameters

ParamTypeDefaultDescrição
taskTypestring—Tipo da tarefa para resetar. Se omitido, reseta todas.

Exemplo de Response

{
  "success": true
}
GET/api/institution/prompts

Retorna o prompt do tenant para um tipo de tarefa (ou o padrão global).

Scopes:ai:read

Query Parameters

ParamTypeDefaultDescrição
taskTypestringchat_tutorTipo da tarefa (chat_tutor, course_editor_agent)

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "systemPrompt": "Você é...",
    "isCustom": true
  }
}
PUT/api/institution/prompts

Salva prompt customizado do tenant para um tipo de tarefa.

Scopes:ai:write

Body Parameters

FieldTypeObrigatórioDescrição
taskTypestringOpcionalTipo da tarefa
systemPromptstringObrigatórioTexto do system prompt (mínimo 10 caracteres)

Exemplo de Request

{
  "taskType": "chat_tutor",
  "systemPrompt": "Você é um professor..."
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid"
  }
}
DELETE/api/institution/prompts

Remove prompt customizado do tenant (reverte para global).

Scopes:ai:write

Query Parameters

ParamTypeDefaultDescrição
taskTypestringchat_tutorTipo da tarefa

Exemplo de Response

{
  "success": true
}

Automações

CRUD de automações (triggers, condições, ações) e histórico de execuções.

GET/api/institution/automations

Lista automações do tenant com paginação e filtros.

Scopes:automations:read

Query Parameters

ParamTypeDefaultDescrição
statusstring—Filtrar por status: active, paused, draft, archived
triggerTypestring—Filtrar por tipo: scheduled, event, webhook
searchstring—Busca por nome
pagenumber1Página
limitnumber20Itens por página

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "name": "Notificar ao completar módulo",
      "status": "active",
      "triggerType": "event"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 5,
    "totalPages": 1
  }
}
POST/api/institution/automations

Cria nova automação.

Scopes:automations:write

Body Parameters

FieldTypeObrigatórioDescrição
namestringObrigatórioNome da automação
triggerTypestringObrigatórioTipo do gatilho: scheduled, event, webhook
triggerConfigobjectObrigatórioConfiguração do gatilho
conditionsarrayOpcionalCondições para execução
actionsarrayObrigatórioAções a executar

Exemplo de Request

{
  "name": "Boas-vindas",
  "triggerType": "event",
  "triggerConfig": {
    "eventName": "enrollment_created"
  },
  "actions": [
    {
      "type": "send_notification",
      "config": {
        "title": "Bem-vindo!",
        "body": "Sua matrícula foi confirmada.",
        "target": "trigger_user"
      }
    }
  ]
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "Boas-vindas",
    "status": "draft"
  }
}
PATCH/api/institution/automations/{id}

Atualiza automação existente.

Scopes:automations:write

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid"
  }
}
DELETE/api/institution/automations/{id}

Deleta automação e todo histórico.

Scopes:automations:write

Exemplo de Response

{
  "success": true
}
POST/api/institution/automations/{id}/toggle

Alterna status entre active e paused.

Scopes:automations:write

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "status": "active"
  }
}
POST/api/institution/automations/{id}/duplicate

Clona automação como rascunho.

Scopes:automations:write

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "Boas-vindas (copia)",
    "status": "draft"
  }
}
POST/api/institution/automations/{id}/test

Dry-run: avalia condições sem executar ações.

Scopes:automations:write

Exemplo de Response

{
  "success": true,
  "data": {
    "conditionsPassed": true,
    "actionsCount": 2,
    "note": "Dry-run: nenhuma ação foi executada"
  }
}
GET/api/institution/automations/{id}/runs

Histórico de execuções da automação.

Scopes:automations:read

Query Parameters

ParamTypeDefaultDescrição
pagenumber1Página
limitnumber20Itens por página
statusstring—Filtrar por status

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "status": "success",
      "durationMs": 245
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 10,
    "totalPages": 1
  }
}

RAG de Curso

Ingestão, atualização e exclusão de conteúdo RAG por curso. Alimenta o tutor IA com material do curso.

POST/api/institution/courses/{id}/rag-ingest

Inicia ingestão do conteúdo do curso no RAG. Suporta modos full (re-processa tudo) e incremental (só aulas alteradas).

Scopes:courses:write

Body Parameters

FieldTypeObrigatórioDescrição
modestringOpcionalModo de ingestão: full | incremental

Exemplo de Request

{
  "mode": "incremental"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "courseId": "uuid",
    "status": "processing",
    "totalLessons": 12,
    "processedLessons": 0
  }
}
GET/api/institution/courses/{id}/rag-ingest

Retorna status da última ingestão RAG do curso.

Scopes:courses:read

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "status": "completed",
    "totalLessons": 12,
    "processedLessons": 12,
    "totalChunks": 87,
    "completedAt": "2026-03-14T10:00:00Z"
  }
}
DELETE/api/institution/courses/{id}/rag-ingest

Remove todo o conteúdo RAG do curso (ContentBlocks + embeddings vinculados).

Scopes:courses:write

Exemplo de Response

{
  "success": true,
  "message": "RAG do curso removido com sucesso"
}

Respostas dos Alunos (Answer Review)

O que cada aluno respondeu, questão a questão: tentativas de quiz resolvidas (opções na ordem que o aluno viu, resposta, gabarito, explicação), atividades interativas, quizzes do tutor IA e entregas de assignments. Professores só enxergam alunos das suas turmas e cursos que ministram (mesmo escopo do relatório do aluno). Leituras por sessão geram AuditEvent `student.answers.view`.

GET/api/institution/students/{studentId}/quiz-attempts

Lista as tentativas de quiz SUBMETIDAS de um aluno (resumo: nota, aprovação, tempo, integridade, aula, curso). Use o detalhe para ver as respostas. Voided fora por padrão.

Scopes:reports:read

Query Parameters

ParamTypeDefaultDescrição
courseIduuid—Filtra por curso (professor: precisa ser curso que ministra)
lessonIduuid—Filtra por aula (quiz)
pagenumber1Página
limitnumber20Itens por página (máx. 100)
includeVoidedbooleanfalseInclui tentativas expiradas/abandonadas

Exemplo de Response

{
  "success": true,
  "data": {
    "student": {
      "id": "uuid",
      "name": "João Silva",
      "email": "joao@escola.com"
    },
    "attempts": [
      {
        "id": "uuid",
        "lessonId": "uuid",
        "lessonTitle": "Quiz — Frações",
        "courseId": "uuid",
        "courseTitle": "Matemática 4º ano",
        "attemptNumber": 2,
        "rawScore": 80,
        "penaltyPct": 0,
        "finalScore": 80,
        "passed": true,
        "startedAt": "2026-10-01T13:00:00.000Z",
        "submittedAt": "2026-10-01T13:12:40.000Z",
        "timeSpentSec": 760,
        "autoSubmitted": false,
        "voided": false,
        "flagged": false,
        "flagReason": null,
        "tabSwitchCount": 0,
        "proficiencyScore": 540
      }
    ],
    "total": 1,
    "page": 1,
    "limit": 20
  }
}

Professor: 403 se não tiver turma com o aluno; aluno de outro tenant: 404.

GET/api/institution/students/{studentId}/quiz-attempts/{attemptId}

Uma tentativa com TODAS as respostas resolvidas (`answers[]`): enunciado, opções na ordem exibida ao aluno, resposta do aluno (crua e legível), gabarito, acerto, explicação e conceitos. `displayIndex + 1` é o número da questão que o aluno viu. `snapshotSource`: attempt (snapshot gravado), current_content (reconstruído do quiz atual) ou unavailable (quiz editado depois — opções indisponíveis).

Scopes:reports:read

Exemplo de Response

{
  "success": true,
  "data": {
    "attempt": {
      "id": "uuid",
      "studentId": "uuid",
      "lessonId": "uuid",
      "courseId": "uuid",
      "attemptNumber": 2,
      "rawScore": 80,
      "penaltyPct": 0,
      "finalScore": 80,
      "passed": true,
      "timeSpentSec": 760,
      "correctCount": 4,
      "gradableCount": 5,
      "totalQuestions": 5,
      "snapshotSource": "attempt",
      "answers": [
        {
          "displayIndex": 0,
          "originalIndex": 3,
          "questionId": null,
          "type": "multiple_choice",
          "questionText": "Qual fração equivale a 1/2?",
          "options": [
            "3/4",
            "2/4",
            "1/3",
            "2/3"
          ],
          "studentAnswerRaw": 1,
          "studentAnswerText": "B) 2/4",
          "correctAnswerRaw": 1,
          "correctAnswerText": "B) 2/4",
          "isCorrect": true,
          "explanation": "2/4 simplifica para 1/2.",
          "concepts": [
            "frações equivalentes"
          ],
          "snapshotSource": "attempt"
        }
      ]
    },
    "lesson": {
      "id": "uuid",
      "title": "Quiz — Frações",
      "type": "quiz",
      "moduleId": "uuid"
    },
    "course": {
      "id": "uuid",
      "title": "Matemática 4º ano"
    },
    "student": {
      "id": "uuid",
      "name": "João Silva",
      "email": "joao@escola.com"
    },
    "submittedIndex": 2
  }
}

Staff sempre vê gabarito e explicação (a política showResultsMode vale só para aluno/pais). Audita `student.answers.view` quando a chamada é por sessão.

GET/api/institution/students/{studentId}/activity-attempts

Histórico de submissões de atividades INTERATIVAS do aluno (drag_drop, fill_blanks, flashcards, trainers etc.) — uma linha por envio (InteractionAttempt). Resumo; itens no detalhe.

Scopes:reports:read

Query Parameters

ParamTypeDefaultDescrição
courseIduuid—Filtra por curso
lessonIduuid—Filtra por aula
pagenumber1Página
limitnumber20Itens por página (máx. 100)

Exemplo de Response

{
  "success": true,
  "data": {
    "student": {
      "id": "uuid",
      "name": "João Silva",
      "email": "joao@escola.com"
    },
    "attempts": [
      {
        "id": "uuid",
        "lessonId": "uuid",
        "lessonTitle": "Arrasta e solta — Animais",
        "courseId": "uuid",
        "courseTitle": "Ciências",
        "attemptNumber": 2,
        "subtype": "drag_drop",
        "totalCorrect": 4,
        "totalQuestions": 5,
        "score": 80,
        "timeSpentSec": 95,
        "source": "web",
        "submittedAt": "2026-10-02T14:03:00.000Z"
      }
    ],
    "total": 1,
    "page": 1,
    "limit": 20
  }
}
GET/api/institution/students/{studentId}/activity-attempts/{attemptId}

Uma submissão de atividade interativa com todos os itens: enunciado (quando o player envia `prompt`), resposta legível do aluno, gabarito, acerto, tempo — e `answers[]` no mesmo shape das tentativas de quiz.

Scopes:reports:read

Exemplo de Response

{
  "success": true,
  "data": {
    "attempt": {
      "id": "uuid",
      "lessonId": "uuid",
      "courseId": "uuid",
      "attemptNumber": 2,
      "subtype": "drag_drop",
      "totalCorrect": 4,
      "totalQuestions": 5,
      "score": 80,
      "timeSpentSec": 95,
      "source": "web",
      "submittedAt": "2026-10-02T14:03:00.000Z",
      "correctCount": 4,
      "gradableCount": 5,
      "snapshotSource": "attempt",
      "items": [
        {
          "id": "item-gato",
          "type": "drag_drop",
          "prompt": "Gato",
          "correct": false,
          "userAnswer": "Gato → Água",
          "userAnswerText": "Água",
          "correctAnswer": "Gato → Terra",
          "correctAnswerText": "Terra",
          "timeMs": 4200
        }
      ],
      "answers": [
        {
          "displayIndex": 0,
          "type": "drag_drop",
          "questionText": "Gato",
          "studentAnswerText": "Água",
          "correctAnswerText": "Terra",
          "isCorrect": false,
          "snapshotSource": "attempt"
        }
      ]
    },
    "lesson": {
      "id": "uuid",
      "title": "Arrasta e solta — Animais",
      "type": "interactive"
    },
    "course": {
      "id": "uuid",
      "title": "Ciências"
    },
    "student": {
      "id": "uuid",
      "name": "João Silva",
      "email": "joao@escola.com"
    }
  }
}

Itens enviados por players antigos (sem `prompt`) mostram o id do item como enunciado e `snapshotSource: unavailable`.

GET/api/institution/students/{studentId}/tutor-quizzes

Quizzes inline que o tutor IA apresentou no chat e o que o aluno marcou (pergunta, opções, escolha, gabarito, acerto, explicação). SÓ o quiz — nunca o texto do chat. Professor vê apenas os vinculados a cursos que ministra.

Scopes:reports:read

Query Parameters

ParamTypeDefaultDescrição
courseIduuid—Filtra por curso da sessão do tutor
pagenumber1Página
limitnumber20Itens por página (máx. 100)

Exemplo de Response

{
  "success": true,
  "data": {
    "student": {
      "id": "uuid",
      "name": "João Silva",
      "email": "joao@escola.com"
    },
    "attempts": [
      {
        "id": "uuid",
        "createdAt": "2026-10-03T19:20:00.000Z",
        "concept": "frações equivalentes",
        "score": 67,
        "allCorrect": false,
        "courseId": "uuid",
        "courseTitle": "Matemática 4º ano",
        "questions": [
          {
            "question": "Qual fração equivale a 1/2?",
            "options": [
              "3/4",
              "2/4",
              "1/3"
            ],
            "selectedIndex": 0,
            "selectedText": "A) 3/4",
            "correctIndex": 1,
            "correctText": "B) 2/4",
            "isCorrect": false,
            "explanation": "2/4 simplifica para 1/2."
          }
        ],
        "answers": [
          {
            "displayIndex": 0,
            "type": "multiple_choice",
            "questionText": "Qual fração equivale a 1/2?",
            "options": [
              "3/4",
              "2/4",
              "1/3"
            ],
            "studentAnswerText": "A) 3/4",
            "correctAnswerText": "B) 2/4",
            "isCorrect": false
          }
        ]
      }
    ],
    "total": 1,
    "page": 1,
    "limit": 20
  }
}
GET/api/institution/courses/{id}/lessons/{lid}/submissions

Entregas de uma aula `assignment`: aluno, status (submitted/resubmitted/graded), atraso, prévia do texto, nº de anexos e nota atual; inclui os matriculados que ainda não entregaram. Professor: escopo de visualização do curso.

Scopes:grades:read

Query Parameters

ParamTypeDefaultDescrição
statusstring—draft | submitted | resubmitted | graded
studentIduuid—Entrega de um aluno específico
pagenumber1Página
limitnumber200Itens por página (máx. 500)

Exemplo de Response

{
  "success": true,
  "data": {
    "lesson": {
      "id": "uuid",
      "title": "Redação — Minha cidade",
      "dueDate": "2026-10-10T23:59:00.000Z",
      "maxScore": 100,
      "submissionType": "both",
      "instructions": "Escreva 15 linhas…"
    },
    "gradeItem": {
      "id": "uuid",
      "title": "Redação — Minha cidade",
      "maxScore": 100,
      "rubric": {
        "id": "uuid",
        "title": "Rubrica de redação",
        "criteria": [],
        "maxScore": 100
      }
    },
    "submissions": [
      {
        "id": "uuid",
        "student": {
          "id": "uuid",
          "name": "João Silva",
          "email": "joao@escola.com"
        },
        "status": "submitted",
        "isLate": false,
        "submittedAt": "2026-10-05T12:00:00.000Z",
        "updatedAt": "2026-10-05T12:00:00.000Z",
        "textPreview": "Minha cidade é…",
        "hasText": true,
        "fileCount": 1,
        "grade": null
      }
    ],
    "notSubmitted": [
      {
        "id": "uuid",
        "name": "Maria Souza"
      }
    ],
    "total": 1,
    "page": 1,
    "limit": 200
  }
}
GET/api/institution/courses/{id}/lessons/{lid}/submissions/{submissionId}

Uma entrega completa: texto integral (texto puro), anexos com signed URL temporária (5 min), nota/feedback/rubrica atuais. Nunca expõe storagePath. Audita `assignment.submission.view` por sessão.

Scopes:grades:read

Exemplo de Response

{
  "success": true,
  "data": {
    "submission": {
      "id": "uuid",
      "status": "submitted",
      "isLate": false,
      "submittedAt": "2026-10-05T12:00:00.000Z",
      "updatedAt": "2026-10-05T12:00:00.000Z",
      "textContent": "Minha cidade é…",
      "files": [
        {
          "index": 0,
          "fileName": "redacao.pdf",
          "mimeType": "application/pdf",
          "fileSizeBytes": 182331,
          "downloadUrl": "https://…/storage/v1/object/sign/…",
          "expiresInSeconds": 300
        }
      ]
    },
    "student": {
      "id": "uuid",
      "name": "João Silva",
      "email": "joao@escola.com"
    },
    "lesson": {
      "id": "uuid",
      "title": "Redação — Minha cidade",
      "maxScore": 100,
      "submissionType": "both",
      "instructions": "…"
    },
    "gradeItem": {
      "id": "uuid",
      "title": "Redação — Minha cidade",
      "maxScore": 100,
      "rubric": null
    },
    "grade": null
  }
}
POST/api/institution/courses/{id}/lessons/{lid}/submissions/{submissionId}/grade

Corrige UMA entrega: grava a nota no gradebook (source=manual — trava a célula), reusa/cria o GradeItem da aula, marca a entrega como graded, espelha o score na LessonCompletion e notifica o aluno (grade_posted). `score: null` limpa a nota e reabre a entrega. Escopo de EDIÇÃO do curso (pedagogo: 403).

Scopes:grades:write

Body Parameters

FieldTypeObrigatórioDescrição
scorenumber | nullObrigatórioNota na escala do item (<= maxScore); null remove
feedbackstringOpcionalFeedback para o aluno (máx. 5000)
rubricBreakdownarrayOpcional[{ criterionName, level, points }] quando há rubrica

Exemplo de Response

{
  "success": true,
  "data": {
    "gradeId": "uuid",
    "score": 85,
    "status": "graded"
  }
}

422 SCORE_ABOVE_MAX quando a nota excede o maxScore do item. Audita `assignment.submission.grade` (sem o texto do feedback).

POST/api/institution/courses/{id}/lessons/{lid}/quiz-results/release

Libera os resultados de um quiz configurado com showResultsMode = manual_release: a partir daí o aluno vê gabarito, acerto e explicação (antes vê só o que respondeu). Idempotente. Grava QuizConfiguration.resultsReleasedAt — campo que SÓ muda por esta rota.

Scopes:courses:write

Exemplo de Response

{
  "success": true,
  "data": {
    "resultsReleasedAt": "2026-10-06T10:00:00.000Z",
    "showResultsMode": "manual_release",
    "changed": true
  }
}

Escopo de EDIÇÃO do curso. Audita `quiz.results.release`.

DELETE/api/institution/courses/{id}/lessons/{lid}/quiz-results/release

Revoga a liberação (volta a esconder gabarito/acerto do aluno).

Scopes:courses:write

Exemplo de Response

{
  "success": true,
  "data": {
    "resultsReleasedAt": null,
    "showResultsMode": "manual_release",
    "changed": true
  }
}

Audita `quiz.results.unrelease`.

Relatórios Avançados

Relatórios de performance de alunos, cursos, eficácia do tutor IA e panorama do tenant. Professores acessam somente dados das suas turmas.

GET/api/institution/reports/student/{studentId}

Relatório individual do aluno, agrupado POR CURSO: mastery, misconceptions (com lifecycle), quizzes (só tentativas submetidas), gradebook (média canônica), atividade, presença, gamificação e risco por curso. Professores recebem scope=teacher (blocos globais nulos).

Scopes:reports:read

Exemplo de Response

{
  "student": {
    "id": "uuid",
    "name": "João Silva",
    "email": "joao@escola.com"
  },
  "scope": "full",
  "summary": {
    "coursesCount": 2,
    "avgMasteryGlobal": 65.4,
    "totalStudyMinutes": 420,
    "chatSessionCount": 14,
    "totalActiveMisconceptions": 3
  },
  "episodicInsights": [
    {
      "episodeType": "analogy_worked",
      "count": 4,
      "avgEffectiveness": 0.8
    }
  ],
  "studyTimeBreakdown": [
    {
      "week": "2026-06-29",
      "minutes": 95,
      "sessions": 4
    }
  ],
  "supervisorAccount": {
    "activeQuarantine": null,
    "recentStrikes": 0,
    "totalIncidents": 0,
    "safetyFlag": null
  },
  "courses": [
    {
      "courseId": "uuid",
      "courseTitle": "Matemática",
      "enrolled": true,
      "progressPct": 68,
      "status": "active",
      "avgMastery": 61.2,
      "conceptMastery": [
        {
          "conceptName": "Equações",
          "masteryProbability": 0.72,
          "exposureCount": 8
        }
      ],
      "misconceptions": {
        "active": [],
        "activeCount": 1,
        "resolvingCount": 0,
        "resolvedCount": 2,
        "manuallyResolved": []
      },
      "quizPerformance": {
        "totalAttempts": 5,
        "avgScore": 74,
        "passRate": 80,
        "recentQuizzes": []
      },
      "gradebook": {
        "weightedAverage": 78,
        "gradedItems": 4,
        "pendingItems": 1,
        "items": []
      },
      "competencies": {
        "frameworks": [
          {
            "slug": "bncc",
            "name": "BNCC — Base Nacional Comum Curricular"
          }
        ],
        "items": [
          {
            "code": "EF04MA01",
            "description": "Ler, escrever e ordenar...",
            "area": "Matemática",
            "masteryPct": 82,
            "gradedCount": 3,
            "itemCount": 2
          }
        ],
        "byArea": [
          {
            "area": "Matemática",
            "avgMasteryPct": 78,
            "competencyCount": 12
          }
        ],
        "unknownCodes": []
      },
      "proficiency": {
        "scaledScore": 560,
        "theta": 0.6,
        "standardError": 0.42,
        "quizzesWithTheta": 3,
        "quizzesAttempted": 5,
        "model": "2PL"
      },
      "assignments": {
        "submitted": 3,
        "late": 0,
        "awaitingGrade": 1,
        "graded": 2
      },
      "riskAssessment": {
        "riskScore": 32,
        "riskLevel": "medium",
        "primaryFactorCode": "inactivity.days",
        "primaryFactorParams": {
          "days": 4
        },
        "dataCoverage": 0.75,
        "factors": []
      }
    }
  ],
  "unattributed": null
}
GET/api/institution/reports/course/{courseId}

Relatório de performance do curso: coortes canônicas de conclusão, conceitos fracos, misconceptions comuns, quiz analytics (resultado oficial = última tentativa submetida; passed respeita o passingScore configurado), comparativo entre turmas, cobertura RAG e gamificação.

Scopes:reports:read

Exemplo de Response

{
  "course": {
    "id": "uuid",
    "title": "Matemática Básica",
    "status": "published"
  },
  "totalEnrollments": 45,
  "activeEnrollments": 30,
  "completedEnrollments": 12,
  "avgProgress": 62,
  "avgCompletionTime": 42.5,
  "weakConcepts": [
    {
      "conceptName": "Frações",
      "avgMastery": 35,
      "studentCount": 12
    }
  ],
  "commonMisconceptions": [
    {
      "misconception": "Denominadores se somam",
      "category": "conceptual",
      "count": 8
    }
  ],
  "quizAnalytics": {
    "totalQuizLessons": 6,
    "studentsWithAttempts": 28,
    "submittedAttempts": 74,
    "avgScore": 71,
    "passRate": 68,
    "scoreDistribution": [
      {
        "range": "70-89",
        "count": 12
      }
    ]
  },
  "classGroups": [
    {
      "name": "Turma A",
      "teacherName": "Prof. Ana",
      "enrollmentCount": 15,
      "avgProgress": 70,
      "avgQuizScore": 72,
      "quizPassRate": 67,
      "avgMastery": 58
    }
  ],
  "ragCoverage": {
    "totalLessons": 20,
    "ingestedLessons": 18,
    "totalChunks": 240
  },
  "gamification": {
    "enabled": true,
    "totalXpAwarded": 12400,
    "avgLevel": 3.2,
    "badgesEarned": 18,
    "activeContests": 1
  },
  "competencyAverages": {
    "frameworks": [
      {
        "slug": "bncc",
        "name": "BNCC — Base Nacional Comum Curricular"
      }
    ],
    "items": [
      {
        "code": "EF04MA01",
        "description": "Ler, escrever e ordenar...",
        "area": "Matemática",
        "masteryPct": 74,
        "gradedCount": 42,
        "itemCount": 2
      }
    ],
    "byArea": [
      {
        "area": "Matemática",
        "avgMasteryPct": 71,
        "competencyCount": 12
      }
    ],
    "unknownCodes": []
  },
  "proficiencyDistribution": {
    "avgScaled": 520,
    "minScaled": 310,
    "maxScaled": 780,
    "histogram": [
      {
        "range": "500-599",
        "count": 18
      }
    ],
    "attemptsWithTheta": 60,
    "totalSubmittedAttempts": 74,
    "model": "2PL"
  }
}
GET/api/institution/report-templates

Templates do report builder: seções habilitadas + ordem por tipo de relatório (student | course | parent), branding e título custom. Sem ?type retorna os 3.

Scopes:reports:read

Query Parameters

ParamTypeDefaultDescrição
typestring—student | course | parent

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "reportType": "student",
      "sections": [
        {
          "id": "summary",
          "enabled": true
        },
        {
          "id": "competencies",
          "enabled": true
        }
      ],
      "brandingEnabled": true,
      "customTitle": null,
      "isCustomized": false
    }
  ]
}
PUT/api/institution/report-templates

Salva o template de um tipo de relatório (seções + ordem + branding). Ids inválidos são descartados; seções ausentes são apendadas habilitadas.

Scopes:settings:write

Body Parameters

FieldTypeObrigatórioDescrição
reportTypestringObrigatóriostudent | course | parent
sectionsarrayObrigatório[{ id, enabled }] na ordem desejada
brandingEnabledbooleanOpcionalHeader com logo/cores da instituição
customTitlestringOpcionalTítulo custom exibido no header

Exemplo de Response

{
  "success": true,
  "data": {
    "reportType": "student",
    "isCustomized": true
  }
}
GET/api/institution/reports/tutor-efficacy

Uso e resultados do tutor IA: sessões (SOMENTE kind=tutor de alunos), satisfação com taxa de resposta, resolução de misconceptions em coorte fechada (nunca >100%) e custo apenas dos taskTypes do tutor. Somente admin.

Scopes:reports:read

Query Parameters

ParamTypeDefaultDescrição
startstring—Data início (YYYY-MM-DD)
endstring—Data fim (YYYY-MM-DD, dia INCLUSIVO)

Exemplo de Response

{
  "period": {
    "start": "2026-06-03T00:00:00.000Z",
    "end": "2026-07-03T23:59:59.999Z"
  },
  "totalSessions": 320,
  "uniqueStudents": 45,
  "avgSatisfaction": 4.2,
  "ratedSessions": 120,
  "totalTokens": 1200000,
  "totalCostUsd": 12.5,
  "misconceptionsDetected": 85,
  "misconceptionsResolved": 62,
  "resolutionRate": 73,
  "costPerSession": 0.0391
}

Restrito a institution_admin e admin. Custo cobre chat_tutor + session_summary + evaluation (custo total de IA é métrica separada).

GET/api/institution/reports/overview

Panorama consolidado do tenant: KPIs (aluno ativo = qualquer atividade de aprendizagem), top cursos ranqueados por matrículas, alunos em risco do cache por matrícula. Somente admin.

Scopes:reports:read

Exemplo de Response

{
  "kpis": {
    "totalStudents": 120,
    "activeStudentsLast7d": 95,
    "totalCourses": 8,
    "publishedCourses": 6,
    "totalEnrollments": 260,
    "completionRate": 41,
    "avgMastery": 58,
    "tutorSessionsLast30d": 1200,
    "aiCostLast30d": 45.8,
    "liveClassesLast30d": 9,
    "liveClassAttendanceRate": 74,
    "liveClassTotalMinutes": 5400
  },
  "topCourses": [
    {
      "title": "Física",
      "enrollments": 40,
      "avgProgress": 65,
      "completionRate": 38
    }
  ],
  "atRiskStudents": [
    {
      "id": "uuid",
      "name": "Maria",
      "riskScore": 78,
      "riskLevel": "critical",
      "riskUpdatedAt": "2026-07-03T10:00:00.000Z",
      "lastActive": "2026-06-25T14:00:00.000Z"
    }
  ]
}

Restrito a institution_admin e admin. avgMastery é null quando não há dados (nunca 50% fabricado).

Análise IA de Curso

Análise automatizada de cursos usando dados reais de performance dos alunos. Gera sugestões de melhoria (add_lesson, edit_lesson, add_exercise, reorder, add_reinforcement).

POST/api/institution/courses/{id}/ai-review

Aciona análise IA do curso. Usa dados de ConceptMastery, misconceptions e cobertura RAG para gerar até 8 sugestões priorizadas.

Scopes:courses:write

Exemplo de Response

{
  "courseId": "uuid",
  "courseTitle": "Matemática Básica",
  "suggestions": [
    {
      "id": "uuid",
      "type": "add_lesson",
      "targetModuleTitle": "Módulo 2 — Frações",
      "title": "Aula de Reforço: Soma de Frações",
      "justification": "35% dos alunos têm mastery < 30% em frações",
      "preview": "Aula focada em operações com frações, usando visualização com pizza e barra.",
      "priority": "high",
      "dataSource": "weak_concept"
    }
  ],
  "analysisContext": {
    "totalStudents": 45,
    "weakConceptsCount": 5,
    "misconceptionsCount": 12,
    "ragCoveragePercent": 90
  }
}

Chamada LLM (Sonnet). Resultado cacheado por 24h no Redis. maxDuration=120s.

GET/api/institution/courses/{id}/ai-review

Retorna sugestões de melhoria previamente geradas (do cache Redis).

Scopes:courses:read

Exemplo de Response

{
  "courseId": "uuid",
  "courseTitle": "Matemática Básica",
  "suggestions": [],
  "analysisContext": {
    "totalStudents": 45,
    "weakConceptsCount": 5,
    "misconceptionsCount": 12,
    "ragCoveragePercent": 90
  },
  "cached": true
}

Gamificação — Config

Configuração de gamificação (defaults do tenant e por curso)

GET/api/institution/gamification/config

Retorna defaults de gamificação do tenant e estatísticas (cursos habilitados/total).

Scopes:gamification:read

Exemplo de Response

{
  "success": true,
  "data": {
    "config": {
      "id": "uuid",
      "defaultEnabled": true,
      "defaultXpRules": {},
      "defaultLevelThresholds": []
    },
    "stats": {
      "enabledCourses": 5,
      "totalCourses": 12
    }
  }
}
PATCH/api/institution/gamification/config

Atualiza defaults de gamificação do tenant.

Scopes:gamification:write

Body Parameters

FieldTypeObrigatórioDescrição
defaultEnabledbooleanOpcionalSe novos cursos terão gamificação habilitada por padrão
defaultXpRulesobjectOpcionalRegras de XP padrão (lesson_completed: 50, etc)
defaultLevelThresholdsnumber[]OpcionalThresholds de nível padrão
defaultFeaturesobjectOpcionalFeatures habilitadas (badges, leaderboard, contests, streaks)

Exemplo de Request

{
  "defaultEnabled": true,
  "defaultXpRules": {
    "lesson_completed": 50,
    "quiz_submitted": 30
  }
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "defaultEnabled": true
  }
}
GET/api/institution/courses/{id}/gamification/config

Retorna config de gamificação do curso + config efetiva (com fallback do tenant).

Scopes:gamification:read

Exemplo de Response

{
  "success": true,
  "data": {
    "config": {
      "courseId": "uuid",
      "enabled": true,
      "xpRules": null
    },
    "effectiveConfig": {}
  }
}
PATCH/api/institution/courses/{id}/gamification/config

Habilita/desabilita gamificação no curso e sobrescreve configurações.

Scopes:gamification:write

Body Parameters

FieldTypeObrigatórioDescrição
enabledbooleanOpcionalHabilitar gamificação no curso
xpRulesobject|nullOpcionalRegras de XP (null = herda tenant)
levelThresholdsnumber[]|nullOpcionalThresholds (null = herda tenant)
featuresobject|nullOpcionalFeatures (null = herda tenant)

Exemplo de Request

{
  "enabled": true,
  "xpRules": {
    "lesson_completed": 75
  }
}

Exemplo de Response

{
  "success": true,
  "data": {
    "courseId": "uuid",
    "enabled": true
  }
}

Gamificação — Badges

Gerenciamento de badges (tenant-wide e por curso)

GET/api/institution/gamification/badges

Lista badges do tenant (tenant-wide + course-specific).

Scopes:gamification:read

Query Parameters

ParamTypeDefaultDescrição
courseIdstring—Filtrar por curso
categorystring—Filtrar por categoria (academic, social, milestone, skill, special, custom)

Exemplo de Response

{
  "success": true,
  "data": []
}
POST/api/institution/gamification/badges

Cria badge tenant-wide.

Scopes:gamification:write

Body Parameters

FieldTypeObrigatórioDescrição
namestringObrigatórioNome do badge
categorystringObrigatórioCategoria
criteriaTypestringObrigatórioauto ou manual
criteriaobjectObrigatórioCritérios de avaliação

Exemplo de Request

{
  "name": "Mestre Quiz",
  "category": "academic",
  "criteriaType": "auto",
  "criteria": {
    "type": "quiz_perfect_count",
    "threshold": 5
  }
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "Mestre Quiz"
  }
}
GET/api/institution/gamification/badges/{id}

Detalhe de um badge com últimos 20 earners.

Scopes:gamification:read

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "name": "Badge",
    "userBadges": []
  }
}
PATCH/api/institution/gamification/badges/{id}

Atualiza um badge.

Scopes:gamification:write

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid"
  }
}
DELETE/api/institution/gamification/badges/{id}

Deleta um badge.

Scopes:gamification:write

Exemplo de Response

{
  "success": true
}
POST/api/institution/gamification/badges/{id}/award

Concede badge manualmente a um usuário.

Scopes:gamification:write

Body Parameters

FieldTypeObrigatórioDescrição
userIdstringObrigatórioID do usuário
courseIdstringOpcionalID do curso (opcional)
notestringOpcionalNota opcional (max 500 chars)

Exemplo de Request

{
  "userId": "uuid",
  "note": "Excelente participação"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "badgeId": "uuid",
    "userId": "uuid"
  }
}
GET/api/institution/courses/{id}/gamification/badges

Lista badges específicos de um curso.

Scopes:gamification:read

Exemplo de Response

{
  "success": true,
  "data": []
}
POST/api/institution/courses/{id}/gamification/badges

Cria badge específico do curso.

Scopes:gamification:write

Exemplo de Request

{
  "name": "Expert em Módulo 1",
  "category": "academic",
  "criteriaType": "auto",
  "criteria": {
    "type": "module_count",
    "threshold": 1
  }
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid"
  }
}

Gamificação — Contests

Competições temporais por curso

GET/api/institution/gamification/contests

Lista contests do tenant.

Scopes:gamification:read

Query Parameters

ParamTypeDefaultDescrição
statusstring—Filtrar por status (draft, active, ended)
courseIdstring—Filtrar por curso

Exemplo de Response

{
  "success": true,
  "data": []
}
POST/api/institution/gamification/contests

Cria novo contest (sempre vinculado a um curso).

Scopes:gamification:write

Body Parameters

FieldTypeObrigatórioDescrição
courseIdstringObrigatórioCurso do contest
namestringObrigatórioNome
metricstringObrigatórioMétrica (xp_earned, badges_earned, courses_completed, quiz_avg_score, streak_days, lessons_completed, study_minutes)
startsAtstringObrigatórioInício (ISO 8601)
endsAtstringObrigatórioFim (ISO 8601)

Exemplo de Request

{
  "courseId": "uuid",
  "name": "Sprint de XP",
  "metric": "xp_earned",
  "startsAt": "2026-04-01T00:00:00Z",
  "endsAt": "2026-04-07T23:59:59Z"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "status": "draft"
  }
}
GET/api/institution/gamification/contests/{id}

Detalhe do contest com participantes e leaderboard live.

Scopes:gamification:read

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "participants": [],
    "liveLeaderboard": []
  }
}
POST/api/institution/gamification/contests/{id}/start

Inicia um contest (draft → active).

Scopes:gamification:write

Exemplo de Response

{
  "success": true
}
POST/api/institution/gamification/contests/{id}/end

Encerra um contest e finaliza scores.

Scopes:gamification:write

Exemplo de Response

{
  "success": true
}

Gamificação — Analytics

Métricas de engajamento e analytics de gamificação

GET/api/institution/gamification/analytics

Métricas de engajamento, funnel de badges e distribuição de XP.

Scopes:gamification:read

Query Parameters

ParamTypeDefaultDescrição
courseIdstring—Curso para distribuição de XP (opcional)

Exemplo de Response

{
  "success": true,
  "data": {
    "engagement": {
      "totalEnrolledStudents": 120,
      "studentsWithGamification": 85,
      "participationRate": 0.71,
      "totalXpAwarded": 45000,
      "totalBadgesEarned": 230,
      "avgXpPerStudent": 529,
      "avgLevel": 3,
      "activeContests": 2
    },
    "badgeFunnel": [],
    "xpDistribution": null
  }
}

Gamificação — Agente IA

Chat com agente IA para criar e gerenciar estratégias de gamificação por curso

POST/api/institution/courses/{id}/gamification-agent

Envia mensagem ao agente de gamificação. O agente usa tool_use para criar badges, contests, rewards e configurar XP automaticamente.

Scopes:gamification:writeai:write

Body Parameters

FieldTypeObrigatórioDescrição
messagestringOpcionalMensagem do admin para o agente
historyarrayOpcionalHistórico de mensagens anteriores [{role, content}]
sessionIdstringOpcionalID da sessão para continuidade (opcional)

Exemplo de Request

{
  "message": "Crie uma estratégia completa de gamificação para este curso",
  "history": [],
  "sessionId": null
}

Exemplo de Response

{
  "success": true,
  "data": {
    "response": "Criei uma estratégia completa com 5 badges de progressão, configuração de XP e um concurso semanal.",
    "sessionId": "uuid",
    "toolsExecuted": [
      "get_course_context",
      "update_gamification_config",
      "create_badge",
      "create_contest"
    ],
    "usage": {
      "inputTokens": 2500,
      "outputTokens": 800
    }
  }
}
GET/api/institution/courses/{id}/gamification-agent/sessions

Lista sessões do agente de gamificação. Use ?latest=true para restaurar a sessão mais recente com mensagens.

Scopes:gamification:read

Query Parameters

ParamTypeDefaultDescrição
latestboolean—Se true, retorna a sessão mais recente com mensagens completas
limitnumber—Máximo de sessões (default 20, max 50)
offsetnumber—Offset para paginação

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "messages": [
      {
        "role": "user",
        "content": "Crie badges"
      },
      {
        "role": "assistant",
        "content": "Criei 3 badges..."
      }
    ],
    "createdAt": "2026-03-20T10:00:00Z"
  }
}

Recompensas & Loja

Catálogo de recompensas, resgates e inventário de itens virtuais

GET/api/institution/gamification/rewards

Listar catálogo de recompensas do tenant.

Scopes:gamification:read

Query Parameters

ParamTypeDefaultDescrição
courseIdstring—Filtrar por curso (opcional)
isActiveboolean—Filtrar por status (opcional)

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "name": "Certificado Premium",
      "type": "certificate_template",
      "coinCost": 500,
      "isActive": true
    }
  ]
}
POST/api/institution/gamification/rewards

Criar nova recompensa no catálogo.

Scopes:gamification:write

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid"
  }
}
GET/api/institution/gamification/redemptions

Listar resgates pendentes e históricos.

Scopes:gamification:read

Query Parameters

ParamTypeDefaultDescrição
statusstring—pending | fulfilled | cancelled

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "userId": "uuid",
      "rewardName": "Certificado Premium",
      "status": "pending",
      "coinsSpent": 500
    }
  ]
}
POST/api/institution/gamification/redemptions/{id}/fulfill

Entregar (fulfill) um resgate pendente.

Scopes:gamification:write

Exemplo de Response

{
  "success": true
}
POST/api/institution/gamification/redemptions/{id}/cancel

Cancelar resgate e devolver moedas.

Scopes:gamification:write

Exemplo de Response

{
  "success": true,
  "data": {
    "refunded": 500
  }
}

Inventário & Customizações (Aluno)

Endpoints do aluno para inventário de itens, customizações de perfil e certificados

GET/api/student/gamification/inventory

Listar itens virtuais do aluno.

Scopes:

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "itemType": "avatar_frame",
      "name": "Moldura Diamante",
      "previewUrl": null,
      "isActive": true
    }
  ]
}
POST/api/student/gamification/inventory/{itemId}/equip

Equipar ou desequipar item (toggle). Apenas itens com equipSlot.

Scopes:

Exemplo de Response

{
  "success": true,
  "data": {
    "customizationId": "uuid",
    "equipSlot": "avatar_frame",
    "value": "diamond"
  }
}
GET/api/student/gamification/customizations

Listar customizações de perfil (ativas ou todas com ?all=true).

Scopes:

Query Parameters

ParamTypeDefaultDescrição
allboolean—Incluir inativas (default: false)

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "type": "avatar_frame",
      "value": "diamond",
      "label": "Moldura Diamante",
      "isActive": true
    }
  ]
}
PATCH/api/student/gamification/customizations/{id}/toggle

Ativar/desativar customização. Ao ativar, desativa outras do mesmo tipo.

Scopes:

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "isActive": true
  }
}
GET/api/student/gamification/user-customizations

Buscar customizações (frame + título) de outros usuários (batch).

Scopes:

Query Parameters

ParamTypeDefaultDescrição
userIdsstring—IDs separados por vírgula (max 50)

Exemplo de Response

{
  "success": true,
  "data": {
    "user-uuid": {
      "avatarFrame": "diamond",
      "customTitle": "Mestre"
    }
  }
}

Quiz Engine

Configuração de quiz, tentativas, analytics e banco de questões.

GET/api/institution/courses/{id}/lessons/{lid}/quiz-config

Retorna configuração do quiz (tentativas, tempo, segurança, pool, disponibilidade).

Scopes:courses:read

Exemplo de Response

{
  "success": true,
  "data": {
    "maxAttempts": 3,
    "timeLimitMinutes": 30,
    "shuffleQuestions": true,
    "hasLessonConfig": true
  }
}
PATCH/api/institution/courses/{id}/lessons/{lid}/quiz-config

Cria ou atualiza configuração do quiz.

Scopes:courses:write

Exemplo de Response

{
  "success": true,
  "data": {
    "maxAttempts": 3,
    "penaltyPerAttempt": 10
  }
}
POST/api/courses/{courseId}/lessons/{lessonId}/quiz/start

Inicia tentativa de quiz. Valida maxAttempts, cooldown, access code, IP whitelist.

Scopes:

Exemplo de Response

{
  "success": true,
  "data": {
    "attemptId": "uuid",
    "attemptNumber": 1,
    "questions": [],
    "config": {}
  }
}
GET/api/courses/{courseId}/lessons/{lessonId}/quiz/attempts

Histórico de tentativas do aluno.

Scopes:

Exemplo de Response

{
  "success": true,
  "data": {
    "attempts": [],
    "config": {}
  }
}
GET/api/institution/courses/{id}/quiz-analytics/{lessonId}

Análise estatística de itens do quiz (dificuldade, discriminação, distratores, Cronbach alpha).

Scopes:courses:read

Exemplo de Response

{
  "success": true,
  "data": {
    "totalAttempts": 50,
    "avgScore": 72,
    "cronbachAlpha": 0.82,
    "items": []
  }
}
GET/api/institution/question-banks/search

Busca questões nos bancos do tenant com filtros.

Scopes:question-banks:read

Query Parameters

ParamTypeDefaultDescrição
bankIdstring—Filtrar por banco específico
typestring—Tipo de questão (multiple_choice, etc)
difficultystring—Dificuldades separadas por vírgula
searchstring—Busca por texto no enunciado

Exemplo de Response

{
  "success": true,
  "data": [],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 0,
    "totalPages": 0
  }
}
POST/api/institution/question-banks/save-from-quiz

Salva questões do quiz em um banco de questões (existente ou novo).

Scopes:question-banks:write

Exemplo de Response

{
  "success": true,
  "data": {
    "bankId": "uuid",
    "saved": 5,
    "skipped": 0
  }
}
GET/api/institution/question-banks/{id}/export

Exporta questões do banco em formato GIFT ou CSV.

Scopes:question-banks:read

Query Parameters

ParamTypeDefaultDescrição
formatstring—Formato: gift ou csv

Exemplo de Response

"Arquivo para download"
POST/api/institution/question-banks/{id}/rag-ingest

Inicia ingestão do banco no RAG para o tutor IA.

Scopes:question-banks:write

Exemplo de Response

{
  "success": true,
  "data": {
    "message": "Ingestion started",
    "bankId": "uuid"
  }
}
GET/api/institution/question-banks/{id}/rag-ingest

Status da ingestão RAG do banco.

Scopes:question-banks:read

Exemplo de Response

{
  "success": true,
  "data": {
    "ragIngested": true,
    "ragIngestedAt": "2026-03-22",
    "ragChunkCount": 42
  }
}
DELETE/api/institution/question-banks/{id}/rag-ingest

Remove dados RAG do banco de questões.

Scopes:question-banks:write

Exemplo de Response

{
  "success": true,
  "data": {
    "message": "RAG removal started"
  }
}

Email

Configuração de email institucional, templates e logs de envio.

GET/api/institution/email-config

Retorna configuração de email do tenant (secret mascarado).

Scopes:settings:read

Exemplo de Response

{
  "success": true,
  "data": {
    "provider": "smtp",
    "smtpHost": "smtp.gmail.com",
    "verified": true
  }
}
PATCH/api/institution/email-config

Cria ou atualiza configuração de email (session-only).

Scopes:settings:write

Body Parameters

FieldTypeObrigatórioDescrição
providerstringOpcionalsmtp | resend | sendgrid
smtpHoststringOpcionalServidor SMTP
smtpPortnumberOpcionalPorta SMTP
secretstringOpcionalSenha SMTP ou API key (criptografada)
fromNamestringObrigatórioNome do remetente
fromEmailstringObrigatórioEmail do remetente

Exemplo de Request

{
  "provider": "smtp",
  "smtpHost": "smtp.gmail.com",
  "smtpPort": 587,
  "fromName": "Minha Escola",
  "fromEmail": "noreply@escola.com",
  "secret": "app-password"
}

Exemplo de Response

{
  "success": true
}

Aceita apenas autenticação por sessão (não API key). Altera verified para false ao trocar credenciais.

POST/api/institution/email-config/test

Testa conexão e envia email de teste ao admin logado.

Scopes:settings:write

Exemplo de Response

{
  "success": true,
  "messageId": "abc123"
}

Session-only. Marca config como verified se bem-sucedido.

GET/api/institution/email-config/native-events

Retorna configuração de eventos nativos que enviam email.

Scopes:settings:read

Exemplo de Response

{
  "success": true,
  "data": {
    "enrollment_created": {
      "enabled": true,
      "templateSlug": "welcome"
    }
  }
}
PATCH/api/institution/email-config/native-events

Atualiza configuração de eventos nativos de email.

Scopes:settings:write

Exemplo de Request

{
  "enrollment_created": {
    "enabled": true,
    "templateSlug": "welcome"
  },
  "grade_posted": {
    "enabled": false
  }
}

Exemplo de Response

{
  "success": true
}
GET/api/institution/email-templates

Lista templates de email do tenant.

Scopes:settings:read

Query Parameters

ParamTypeDefaultDescrição
slugstring—Filtrar por slug
localestring—Filtrar por locale
searchstring—Buscar por nome/slug/subject
pagenumber1Página
limitnumber50Itens por página

Exemplo de Response

{
  "success": true,
  "data": [],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 0,
    "pages": 0
  }
}
POST/api/institution/email-templates

Cria novo template de email.

Scopes:settings:write

Body Parameters

FieldTypeObrigatórioDescrição
slugstringObrigatórioIdentificador único (lowercase, underscore)
namestringObrigatórioNome do template
subjectstringObrigatórioAssunto (suporta {{vars}})
bodyHtmlstringObrigatórioCorpo HTML (Handlebars)
localestringOpcionalLocale

Exemplo de Request

{
  "slug": "custom_welcome",
  "name": "Boas-vindas Custom",
  "subject": "Olá {{user.name}}",
  "bodyHtml": "<h1>Bem-vindo!</h1>",
  "locale": "pt-BR"
}

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid",
    "slug": "custom_welcome"
  }
}
PATCH/api/institution/email-templates/{id}

Atualiza template de email.

Scopes:settings:write

Exemplo de Response

{
  "success": true,
  "data": {
    "id": "uuid"
  }
}
DELETE/api/institution/email-templates/{id}

Exclui template (não permite excluir defaults).

Scopes:settings:write

Exemplo de Response

{
  "success": true
}

Templates com isDefault=true não podem ser excluídos.

POST/api/institution/email-templates/preview

Renderiza preview de template com dados de exemplo.

Scopes:settings:read

Body Parameters

FieldTypeObrigatórioDescrição
templateIdstringOpcionalID do template (ou forneça bodyHtml)
bodyHtmlstringOpcionalHTML inline para preview
sampleDataobjectOpcionalDados de exemplo para variáveis

Exemplo de Response

{
  "success": true,
  "data": {
    "subject": "Olá João",
    "html": "<html>...</html>"
  }
}
POST/api/institution/email-templates/seed

Carrega templates padrão do sistema (idempotente).

Scopes:settings:write

Exemplo de Response

{
  "success": true,
  "data": {
    "created": 40,
    "skipped": 0
  }
}
GET/api/institution/email-logs

Lista logs de email com filtros e estatísticas agregadas.

Scopes:reports:read

Query Parameters

ParamTypeDefaultDescrição
statusstring—Filtrar por status (queued/sending/delivered/failed/bounced)
sourcestring—Filtrar por origem (automation/system/manual/digest)
recipientEmailstring—Buscar por email
dateFromstring—Data início (ISO)
dateTostring—Data fim (ISO)
pagenumber1Página

Exemplo de Response

{
  "success": true,
  "data": [],
  "stats": {
    "total": 0,
    "delivered": 0,
    "failed": 0,
    "deliveryRate": 0
  }
}

SSO & SCIM 2.0

Single Sign-On (SAML 2.0 / OIDC) e provisionamento automático de usuários e grupos via SCIM 2.0.

GET/api/institution/sso/config

Retorna a configuração SSO do tenant com secrets mascarados.

Scopes:settings:read

Exemplo de Response

{
  "config": {
    "protocol": "saml",
    "samlEnabled": true,
    "samlEntityId": "...",
    "scimEnabled": false
  }
}
PUT/api/institution/sso/config

Cria ou atualiza a configuração SSO do tenant. Criptografa secrets automaticamente. Requer plano Enterprise.

Scopes:settings:write

Body Parameters

FieldTypeObrigatórioDescrição
protocol"saml" | "oidc"ObrigatórioProtocolo SSO
samlEnabledbooleanOpcionalAtivar SAML 2.0
samlIdpSsoUrlstringOpcionalIdP SSO URL
samlIdpCertstringOpcionalCertificado IdP (PEM)
oidcEnabledbooleanOpcionalAtivar OIDC
oidcDiscoveryUrlstringOpcionalDiscovery URL OIDC
oidcClientIdstringOpcionalClient ID
oidcClientSecretstringOpcionalClient Secret (criptografado)
jitEnabledbooleanOpcionalHabilitar JIT provisioning
allowedDomainsstring[]OpcionalDomínios permitidos para JIT
scimEnabledbooleanOpcionalHabilitar SCIM 2.0

Exemplo de Response

{
  "config": {
    "id": "uuid",
    "protocol": "saml",
    "samlEnabled": true
  }
}
GET/api/institution/sso/metadata

Retorna o SP SAML Metadata XML para configurar no IdP (Okta, Azure AD, Google Workspace).

Scopes:settings:read

Exemplo de Response

"<?xml version=\"1.0\"?>..."
POST/api/institution/sso/test

Testa a configuração SSO: verifica certificado SAML, tenta fetch da Metadata URL e testa OIDC discovery.

Scopes:settings:write

Exemplo de Response

{
  "success": true,
  "results": {
    "saml": {
      "ok": true
    },
    "oidc": {
      "ok": true,
      "issuer": "https://..."
    }
  }
}
POST/api/institution/sso/scim-token

Gera ou rotaciona o token SCIM do tenant. Retorna o token plain-text uma única vez.

Scopes:settings:write

Exemplo de Response

{
  "token": "sk_scim_...",
  "scimBaseUrl": "https://app.mentoria.app/api/scim/v2"
}
GET/api/institution/sso/groups

Lista grupos SSO sincronizados do IdP com seus mapeamentos de curso.

Scopes:settings:read

Exemplo de Response

{
  "groups": [
    {
      "id": "uuid",
      "name": "Finance Team",
      "memberCount": 12,
      "courseMappings": []
    }
  ]
}
POST/api/institution/sso/groups/{id}/mappings

Adiciona um mapeamento grupo SSO → curso. Membros do grupo serão matriculados automaticamente.

Scopes:settings:write

Body Parameters

FieldTypeObrigatórioDescrição
courseIdstring (UUID)ObrigatórioID do curso
role"student" | "teacher"OpcionalPapel no curso (default: student)

Exemplo de Response

{
  "mapping": {
    "id": "uuid",
    "courseId": "uuid",
    "role": "student"
  }
}
DELETE/api/institution/sso/groups/{id}/mappings

Remove um mapeamento grupo → curso. Use query param ?mappingId=.

Scopes:settings:write

Query Parameters

ParamTypeDefaultDescrição
mappingIdstring (UUID)—ID do mapping a remover

Exemplo de Response

null
GET/api/institution/sso/audit

Lista o log de auditoria de eventos SCIM paginado.

Scopes:settings:read

Query Parameters

ParamTypeDefaultDescrição
pagenumber—Página (default: 1)
pageSizenumber—Tamanho da página (max 50, default 20)
eventTypestring—Filtrar por tipo (user.create, group.member.add, etc)
statusstring—Filtrar por status (success/error/skipped)

Exemplo de Response

{
  "logs": [],
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "total": 0,
    "totalPages": 0
  }
}
GET/api/scim/v2/Users

Lista usuários no formato SCIM 2.0. Suporta filtro ?filter=userName eq "email".

Scopes:

Exemplo de Response

{
  "schemas": [
    "urn:ietf:params:scim:api:messages:2.0:ListResponse"
  ],
  "totalResults": 0,
  "Resources": []
}
POST/api/scim/v2/Users

Cria ou atualiza usuário via SCIM 2.0. Idempotente por externalId.

Scopes:

Body Parameters

FieldTypeObrigatórioDescrição
userNamestringObrigatórioEmail do usuário
name.formattedstringOpcionalNome completo
externalIdstringOpcionalID externo do IdP
activebooleanOpcionalStatus ativo/suspenso

Exemplo de Response

{
  "id": "uuid",
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "userName": "user@empresa.com"
}
PATCH/api/scim/v2/Users/{id}

Atualiza usuário via SCIM PatchOp (Operations array). Suporta replace, add, remove.

Scopes:

Body Parameters

FieldTypeObrigatórioDescrição
OperationsScimOperation[]ObrigatórioArray de operações SCIM (op, path, value)

Exemplo de Response

{
  "id": "uuid",
  "active": false
}
DELETE/api/scim/v2/Users/{id}

Desativa usuário (soft delete — status = suspended). Retorna 204. NUNCA apaga o registro.

Scopes:

Exemplo de Response

null
GET/api/scim/v2/Groups

Lista grupos no formato SCIM 2.0.

Scopes:

Exemplo de Response

{
  "schemas": [
    "urn:ietf:params:scim:api:messages:2.0:ListResponse"
  ],
  "totalResults": 0,
  "Resources": []
}
POST/api/scim/v2/Groups

Cria ou atualiza grupo via SCIM 2.0. Dispara syncGroupCourses para matrículas automáticas.

Scopes:

Exemplo de Response

{
  "id": "uuid",
  "displayName": "Finance Team",
  "members": []
}
PATCH/api/scim/v2/Groups/{id}

Atualiza grupo/membros via SCIM PatchOp. Adição/remoção de membros dispara auto-matrícula.

Scopes:

Exemplo de Response

{
  "id": "uuid",
  "displayName": "Finance Team",
  "members": [
    {
      "value": "uuid"
    }
  ]
}
DELETE/api/scim/v2/Groups/{id}

Remove grupo SSO e cancela matrículas dos membros nos cursos mapeados.

Scopes:

Exemplo de Response

null

Chat IA — Quiz Inline

Quizzes inline gerados pelo tutor IA para verificar resolução de misconceptions

POST/api/ai/chat/inline-quiz/submit

Submete respostas do quiz inline. Avalia, atualiza ConceptMastery e verifica resolução de misconceptions.

Scopes:

Body Parameters

FieldTypeObrigatórioDescrição
quizIdstring (UUID)ObrigatórioID do quiz (retornado pelo prepare)
answersnumber[]ObrigatórioÍndices das respostas selecionadas

Exemplo de Response

{
  "results": [
    {
      "questionIndex": 0,
      "isCorrect": true,
      "explanation": "..."
    }
  ],
  "score": 100,
  "allCorrect": true,
  "misconceptionsResolved": [
    "fórmula quadrática"
  ]
}

MCP (ChatGPT / Claude)

Conector MCP: admins e professores ligam a própria conta do ChatGPT/Claude ao tenant via OAuth 2.1 (endpoint MCP em /api/mcp — protocolo JSON-RPC, não REST). Rotas de gestão abaixo são sessionOnly (nunca API key nem token MCP).

GET/api/institution/mcp/settings

Estado do conector (enabled, allowTeachers, URLs do servidor MCP, ligações ativas).

Scopes:

Exemplo de Response

{
  "success": true,
  "data": {
    "enabled": true,
    "allowTeachers": true,
    "serverUrls": [
      {
        "kind": "subdomain",
        "url": "https://escola.studeia.com/api/mcp"
      }
    ],
    "activeConnections": 2
  }
}

sessionOnly — institution_admin.

PATCH/api/institution/mcp/settings

Liga/desliga o conector e o acesso de professores. Desligar revoga todas as ligações.

Scopes:

Body Parameters

FieldTypeObrigatórioDescrição
enabledbooleanOpcionalPermitir ligações MCP
allowTeachersbooleanOpcionalProfessores podem conectar

Exemplo de Response

{
  "success": true,
  "data": {
    "enabled": false,
    "allowTeachers": true
  },
  "revoked": 2
}

sessionOnly — institution_admin.

GET/api/institution/mcp/connections

Lista ligações MCP do tenant (usuário, papel, cliente, escopos, uso).

Scopes:

Query Parameters

ParamTypeDefaultDescrição
includeRevokedbooleanfalseInclui revogadas

Exemplo de Response

{
  "success": true,
  "data": [
    {
      "id": "uuid",
      "status": "active",
      "scopes": [
        "read",
        "write",
        "offline_access"
      ],
      "user": {
        "email": "prof@escola.com",
        "role": "teacher"
      },
      "client": {
        "clientName": "Claude"
      }
    }
  ]
}

sessionOnly.

DELETE/api/institution/mcp/connections/{grantId}

Revoga uma ligação (o assistente perde o acesso imediatamente).

Scopes:

Exemplo de Response

{
  "success": true,
  "revoked": true
}

sessionOnly — institution_admin/coordinator.

Webhooks

Webhooks para notificações em tempo real estão em desenvolvimento.

Studeia API v1 — Documentação gerada automaticamente

API Documentation — Studeia | Studeia