DocumentaçãoPara quem contribui
Referência da API
Todas as rotas da API do OpENEM, geradas do código: método, caminho, parâmetros, corpo e se a rota exige login.
A API tem 118 rotas. As de domínio ficam em /api/v1; a raiz e o /health ficam fora do prefixo. Esta página é gerada do próprio código do backend, a partir dos decorators do Swagger: rota nova aparece aqui no próximo build. Numa instância de desenvolvimento, o Swagger interativo fica em /api.
Para usar a API, crie uma conta em POST /api/v1/auth/register ou entre em POST /api/v1/auth/login, e mande o accessToken da resposta no cabeçalho Authorization: Bearer <token>. As rotas têm limite de requisições; os números estão em Produção.
answers
POST /api/v1/answers
Registra uma tentativa e retorna a correção comentada
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): CreateAnswerDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
questionId | string | sim | |
chosenId | string | não | Alternativa escolhida (ausente = em branco) |
timeSpentSec | number | não | Tempo gasto na questão, em segundos |
simulationId | string | não | Vincula a tentativa a um simulado |
Respostas: 201.
App
GET /
Sem login.
Respostas: 200.
auth
POST /api/v1/auth/register
Cria uma conta e retorna um token de acesso
Sem login.
Corpo (JSON): RegisterDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
email | string | sim | |
password | string | sim | |
displayName | string | não | |
acceptTerms | boolean | sim | Aceite dos Termos de Uso e da Política de Privacidade (menores de 18 anos usam com ciência do responsável). Tem de ser true. |
Respostas: 201.
POST /api/v1/auth/login
Autentica e retorna um token de acesso
Sem login.
Corpo (JSON): LoginDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
email | string | sim | |
password | string | sim |
Respostas: 200.
GET /api/v1/auth/options
Formas de entrar ligadas neste servidor (recuperação de senha por e-mail, Google)
Sem login.
Respostas: 200.
POST /api/v1/auth/forgot-password
Manda um link de redefinição de senha, se o e-mail tiver conta (a resposta é sempre a mesma)
Sem login.
Corpo (JSON): ForgotPasswordDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
email | string | sim |
Respostas: 202, 503.
POST /api/v1/auth/reset-password
Cria a senha nova com o token do e-mail, encerra as outras sessões e retorna um token de acesso
Sem login.
Corpo (JSON): ResetPasswordDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
token | string | sim | Token do link enviado por e-mail |
password | string | sim |
Respostas: 200.
POST /api/v1/auth/logout-all
Sai de todos os dispositivos: nenhum token emitido até agora vale mais
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 204.
GET /api/v1/auth/google
Começa o login com Google (redireciona para o Google)
Sem login.
Respostas: 302, 404.
GET /api/v1/auth/google/callback
Volta do Google: redireciona ao app com um código de uso único (#code=) ou o motivo da recusa (#erro=)
Sem login.
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
error | query | objeto | não | Ex.: access_denied |
state | query | objeto | não | Deve bater com o cookie da ida |
code | query | objeto | não | Código do Google |
Respostas: 302.
POST /api/v1/auth/google/exchange
Troca o código de uso único da volta do Google por um token de acesso
Sem login.
Corpo (JSON): GoogleExchangeDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
code | string | sim | Código de uso único da volta do Google |
Respostas: 200.
community
GET /api/v1/community/threads
Lista os tópicos do fórum (mais recentes primeiro)
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
POST /api/v1/community/threads
Cria um tópico no fórum
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): CreateThreadDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
title | string, até 140 caracteres | sim | |
body | string, até 5000 caracteres | sim | |
questionId | string | não | Questão relacionada (opcional) |
Respostas: 201.
GET /api/v1/community/threads/{id}
Detalha um tópico com a primeira página de respostas
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
DELETE /api/v1/community/threads/{id}
Apaga um tópico próprio, com as respostas (o de outro aluno é 404)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
GET /api/v1/community/threads/{id}/posts
Próxima página de respostas de um tópico (cursor)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | |
cursor | query | string | não | Valor de nextCursor da página anterior |
limit | query | number, de 1 a 50 | não |
Respostas: 200.
POST /api/v1/community/threads/{id}/posts
Responde a um tópico
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Corpo (JSON): CreatePostDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
body | string, até 5000 caracteres | sim |
Respostas: 201.
POST /api/v1/community/threads/{id}/posts/{postId}/like
Curtir/descurtir uma resposta do fórum (toggle)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | |
postId | caminho | string | sim |
Respostas: 201.
DELETE /api/v1/community/threads/{id}/posts/{postId}
Apaga uma resposta própria (a de outro aluno é 404)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | |
postId | caminho | string | sim |
Respostas: 200.
POST /api/v1/community/threads/{id}/report
Denuncia um tópico do fórum
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Corpo (JSON): ReportDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
reason | string, até 500 caracteres | sim | Motivo da denúncia, lido por quem modera a instalação |
Respostas: 201.
POST /api/v1/community/threads/{id}/posts/{postId}/report
Denuncia uma resposta do fórum
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim | |
postId | caminho | string | sim |
Corpo (JSON): ReportDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
reason | string, até 500 caracteres | sim | Motivo da denúncia, lido por quem modera a instalação |
Respostas: 201.
essays
GET /api/v1/essays/prompts
Lista os temas de redação disponíveis
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
GET /api/v1/essays/prompts/{id}
Detalha um tema de redação
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
GET /api/v1/essays/submissions
Lista as redações enviadas pelo usuário
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
POST /api/v1/essays/submissions
Envia uma redação para um tema
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): CreateSubmissionDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
promptId | string | sim | Tema (EssayPrompt) escolhido |
content | string, até 8000 caracteres | sim | Texto da redação |
Respostas: 201.
GET /api/v1/essays/submissions/{id}
Detalha uma redação (com a avaliação, se houver)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
POST /api/v1/essays/submissions/{id}/evaluation
Corrige a redação por competência (rubrica manual)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Corpo (JSON): EvaluateEssayDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
c1 | 0 \ | 40 \ | 80 \ |
c2 | 0 \ | 40 \ | 80 \ |
c3 | 0 \ | 40 \ | 80 \ |
c4 | 0 \ | 40 \ | 80 \ |
c5 | 0 \ | 40 \ | 80 \ |
feedback | string | não | Comentário geral do corretor |
Respostas: 201.
favorites
GET /api/v1/favorites
Lista as questões favoritadas do usuário
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
POST /api/v1/favorites
Favorita uma questão
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): CreateFavoriteDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
questionId | string | sim | Questão a favoritar |
Respostas: 201.
DELETE /api/v1/favorites/{questionId}
Remove uma questão dos favoritos
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
questionId | caminho | string | sim |
Respostas: 200.
flashcards
POST /api/v1/flashcards/decks
Cria um deck de flashcards
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): CreateDeckDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
title | string | sim | Título do deck |
description | string | sim | Descrição do deck |
subject | string | sim | Matéria/área do knowledge (ex: "Matemática e suas Tecnologias") |
topic | string | não | Tópico dentro da matéria (opcional) |
subtheme | string | não | Subtema dentro do tópico (opcional) |
icon | string | não | Nome do ícone do deck (chave semântica, não emoji) |
isPublic | boolean | sim | Deck público (visível para todos) |
Respostas: 201.
GET /api/v1/flashcards/decks/mine
Decks do usuário logado
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
GET /api/v1/flashcards/decks/public
Decks públicos votados (opcionalmente por matéria)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
subject | query | string | sim |
Respostas: 200.
GET /api/v1/flashcards/decks/progress
Progresso por deck para a árvore (novos, vistos, revistos)
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
GET /api/v1/flashcards/decks/{deckId}
Detalhe de um deck (com flashcards)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
deckId | caminho | string | sim |
Respostas: 200.
PATCH /api/v1/flashcards/decks/{deckId}
Atualiza um deck (apenas o dono)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
deckId | caminho | string | sim |
Corpo (JSON): UpdateDeckDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
title | string | não | Título do deck |
description | string | não | Descrição do deck |
subject | string | não | Matéria/área do knowledge |
topic | string | não | Tópico dentro da matéria |
subtheme | string | não | Subtema dentro do tópico |
icon | string | não | Ícone do deck (emoji) |
isPublic | boolean | não | Deck público |
Respostas: 200.
DELETE /api/v1/flashcards/decks/{deckId}
Remove um deck com seus cards (apenas o dono)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
deckId | caminho | string | sim |
Respostas: 200.
POST /api/v1/flashcards/decks/{deckId}/vote
Vota (up/down) em um deck público: um voto por aluno
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
deckId | caminho | string | sim |
Corpo (JSON): VoteDeckDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
vote | "up" \ | "down" | sim |
Respostas: 201.
POST /api/v1/flashcards/decks/{deckId}/flashcards
Adiciona um flashcard ao deck
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
deckId | caminho | string | sim |
Corpo (JSON): CreateFlashcardDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
front | string | sim | Frente do card (Markdown: pergunta) |
back | string | sim | Verso do card (Markdown: resposta) |
Respostas: 201.
DELETE /api/v1/flashcards/flashcards/{flashcardId}
Remove um flashcard
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
flashcardId | caminho | string | sim |
Respostas: 200.
GET /api/v1/flashcards/study/queue
Fila otimizada de estudo (SM-2 + Pareto): filtros por escopo
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
limit | query | string | sim | |
subject | query | string | sim | |
topic | query | string | sim | |
subtheme | query | string | sim | |
deckId | query | string | sim |
Respostas: 200.
POST /api/v1/flashcards/flashcards/{flashcardId}/review
Registra uma revisão SM-2 (qualidade 0-5)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
flashcardId | caminho | string | sim |
Corpo (JSON): ReviewFlashcardDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
quality | number, de 0 a 5 | sim | Qualidade da lembrança (0-5) |
Respostas: 201.
GET /api/v1/flashcards/stats
Dashboard de revisão espaçada do usuário
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
GET /api/v1/flashcards/flashcards/{flashcardId}/preview
Preview do próximo agendamento SM-2 sem salvar (antes de avaliar)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
flashcardId | caminho | string | sim |
Respostas: 200.
GET /api/v1/flashcards/forecast
Previsão de carga de revisão dos próximos dias
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
days | query | string | sim |
Respostas: 200.
formulas
GET /api/v1/formulas
Cheat sheet de fórmulas com busca por texto, filtro por matéria/assunto e favoritas (issue #38)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
q | query | string | não | Busca por texto (título/descrição/LaTeX) |
subjectId | query | string | não | Filtra por matéria |
topicId | query | string | não | Filtra por assunto (tópico) |
onlyFavorites | query | boolean | não | Apenas favoritas do usuário |
Respostas: 200.
POST /api/v1/formulas
Cria uma fórmula personalizada
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): CreateFormulaDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
title | string | sim | Nome da fórmula |
latex | string | sim | Expressão em LaTeX |
description | string | não | Contexto/observação |
subjectId | string | sim | Matéria da fórmula |
topicId | string | não | Assunto (tópico) relacionado |
Respostas: 201.
POST /api/v1/formulas/pdf
Caderno de fórmulas em PDF: capa, sumário, fórmulas desenhadas do LaTeX e legenda
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): FormulasPdfDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
formulaIds | string[] | não | Fórmulas escolhidas |
subjectIds | string[] | não | Matérias |
topicIds | string[] | não | Assuntos |
onlyFavorites | boolean | não | Só as fórmulas favoritas do aluno |
title | string | não | Título na capa e no cabeçalho |
studentName | string | não | Nome do aluno na capa |
theme | string | não | Tema de cor (mesmos temas do app) |
brandColor | string | não | |
cover | boolean | não | |
toc | boolean | não | Sumário por assunto |
legend | boolean | não | Legenda dos símbolos |
descriptions | boolean | não | Explicação curta |
twoColumns | boolean | não |
Respostas: 200.
GET /api/v1/formulas/{id}
Detalhe de uma fórmula com estado de favorito
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
POST /api/v1/formulas/{id}/favorite
Favorita/desfavorita uma fórmula (toggle)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 201.
gamification
GET /api/v1/gamification/me
Resumo de gamificação (pontos, sequência, conquistas)
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
GET /api/v1/gamification/achievements
Catálogo de conquistas com status de desbloqueio
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
GET /api/v1/gamification/leaderboard
Ranking de XP (global ou por liga do solicitante)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
scope | query | string | sim | |
limit | query | string | sim |
Respostas: 200.
GET /api/v1/gamification/history
Histórico de XP ganho (logs + agregado por dia)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
days | query | string | sim |
Respostas: 200.
GET /api/v1/gamification/daily-challenge
Desafio diário do dia (meta, progresso, recompensa)
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
POST /api/v1/gamification/daily-challenge/claim
Resgata a recompensa do desafio diário concluído
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 201.
health
GET /health
Verificação de saúde da API, do banco e do cache
Sem login.
Respostas: 200.
performance
GET /api/v1/performance
Desempenho do usuário por área, por assunto e tendência recente (filtro 7d/30d/all)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
period | query | "7d" \ | "30d" \ | "all" |
Respostas: 200.
GET /api/v1/performance/weeks
Semana a semana: a semana atual e as anteriores (acerto, minutos de foco, dias estudados, áreas) e as prioridades do último mês
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
weeks | query | number, de 1 a 12 | não | Quantas semanas devolver, contando a atual (segunda a domingo, horário de Brasília) |
Respostas: 200.
GET /api/v1/performance/heatmap
Mapa de calor da taxonomia canônica: todos os tópicos por área → matéria com o desempenho do usuário (issue #43)
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
pomodoro
POST /api/v1/pomodoro/sessions
Registra uma sessão de foco concluída com XP proporcional (issue #41)
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): CompleteFocusSessionDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
durationSec | number, de 30 a 14400 | sim | Duração da sessão em segundos (30s a 4h) |
startedAt | string | sim | Momento em que a sessão começou (ISO 8601) |
subjectId | string | não | Matéria estudada na sessão |
Respostas: 201.
GET /api/v1/pomodoro/history
Histórico de sessões dos últimos N dias
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
days | query | string | sim |
Respostas: 200.
GET /api/v1/pomodoro/by-subject
Minutos de foco por matéria nos últimos N dias
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
days | query | string | sim |
Respostas: 200.
GET /api/v1/pomodoro/today
Minutos de foco de hoje (widget do Pomodoro)
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
question-notes
GET /api/v1/question-notes
Lista as anotações do usuário (todas, ou filtradas por questionIds)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
questionIds | query | string | sim |
Respostas: 200.
PUT /api/v1/question-notes
Cria ou atualiza uma anotação pessoal em uma questão
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): UpsertQuestionNoteDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
questionId | string | sim | Questão associada à nota |
content | string | sim | Conteúdo da nota (Markdown) |
Respostas: 200.
GET /api/v1/question-notes/{questionId}
Retorna a anotação do usuário para uma questão
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
questionId | caminho | string | sim |
Respostas: 200.
DELETE /api/v1/question-notes/{questionId}
Remove a anotação do usuário de uma questão
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
questionId | caminho | string | sim |
Respostas: 200.
questions
GET /api/v1/questions
Busca questões por área, assunto, nível e ano (paginado)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
subjectAreaId | query | string | não | Filtra pela área do conhecimento (SubjectArea) |
subjectId | query | string | não | Filtra pela matéria (Subject) |
topicId | query | string | não | Filtra pelo assunto (Topic) |
difficulty | query | number, de 1 a 5 | não | Nível 1..5 |
year | query | number | não | Ano da prova oficial |
examSlug | query | string | não | Prova específica: "2023", "2023-reaplicacao" |
language | query | "ingles" \ | "espanhol" | não |
code | query | string | não | Busca pelo código da questão, por prefixo: "ENEM-2023-136", "2023 136", "2023". |
page | query | objeto, mínimo 1 | não | |
limit | query | objeto, de 1 a 50 | não |
Respostas: 200.
GET /api/v1/questions/facets
Contagem de questões por área, assunto e prova (para o painel de filtros)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
language | query | string | sim |
Respostas: 200.
GET /api/v1/questions/exams
Lista as provas disponíveis, da mais recente para a mais antiga
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
GET /api/v1/questions/{id}
Detalha uma questão comentada (com gabarito)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
POST /api/v1/questions/{id}/explanation
Devolve o comentário da questão, gerando-o por IA na primeira vez (se houver provedor)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
recommendation
GET /api/v1/recommendation/next
Questões recomendadas a partir dos assuntos com mais erros
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
limit | query | number | sim |
Respostas: 200.
review
GET /api/v1/review/queue
Fila de revisão (assuntos com revisão vencida)
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
GET /api/v1/review/next
Próxima revisão agendada (dueAt > agora)
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
POST /api/v1/review/{id}
Reagenda um item de revisão pela lembrança (0..5)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Corpo (JSON): GradeReviewDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
quality | number, de 0 a 5 | sim | Qualidade da lembrança (0 = esqueceu, 5 = perfeito) |
Respostas: 201.
simulations
GET /api/v1/simulations/templates
Lista os simulados disponíveis e os que o aluno salvou
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
POST /api/v1/simulations/templates
Salva um simulado personalizado (por tema)
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): CreateTemplateDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
subjectAreaIds | string[] | não | Áreas do conhecimento. É o filtro que alcança as questões oficiais ainda não classificadas em matéria. |
subjectIds | string[] | não | Matérias |
topicIds | string[] | não | Assuntos (temas) |
examSlugs | string[] | não | Provas: "2023", "2023-reaplicacao" |
subjectAreaId | string | não | |
subjectId | string | não | |
topicId | string | não | |
yearFrom | number | não | Ano mínimo da prova |
yearTo | number | não | Ano máximo da prova |
difficulty | number, de 1 a 5 | não | |
language | "ingles" \ | "espanhol" | não |
questionCount | number, de 3 a 180 | não | |
timeLimitMin | number | não | Tempo do simulado, em minutos |
pareto | boolean | não | Sorteio ponderado pela incidência no ENEM (Pareto) |
unseenOnly | boolean | não | Só questões nunca respondidas |
onlyFavorites | boolean | não | Só questões favoritadas |
wrongOnly | boolean | não | Só questões que o aluno errou antes |
name | string, até 60 caracteres | sim |
Respostas: 201.
DELETE /api/v1/simulations/templates/{id}
Remove um simulado personalizado do aluno
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
POST /api/v1/simulations/preview
Quantas questões existem para um recorte, antes de iniciar
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): SimulationFiltersDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
subjectAreaIds | string[] | não | Áreas do conhecimento. É o filtro que alcança as questões oficiais ainda não classificadas em matéria. |
subjectIds | string[] | não | Matérias |
topicIds | string[] | não | Assuntos (temas) |
examSlugs | string[] | não | Provas: "2023", "2023-reaplicacao" |
subjectAreaId | string | não | |
subjectId | string | não | |
topicId | string | não | |
yearFrom | number | não | Ano mínimo da prova |
yearTo | number | não | Ano máximo da prova |
difficulty | number, de 1 a 5 | não | |
language | "ingles" \ | "espanhol" | não |
questionCount | number, de 3 a 180 | não | |
timeLimitMin | number | não | Tempo do simulado, em minutos |
pareto | boolean | não | Sorteio ponderado pela incidência no ENEM (Pareto) |
unseenOnly | boolean | não | Só questões nunca respondidas |
onlyFavorites | boolean | não | Só questões favoritadas |
wrongOnly | boolean | não | Só questões que o aluno errou antes |
Respostas: 201.
GET /api/v1/simulations/pdf-themes
Temas de cor disponíveis para o caderno em PDF
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
POST /api/v1/simulations
Inicia um simulado (de um template ou por filtros)
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): StartSimulationDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
subjectAreaIds | string[] | não | Áreas do conhecimento. É o filtro que alcança as questões oficiais ainda não classificadas em matéria. |
subjectIds | string[] | não | Matérias |
topicIds | string[] | não | Assuntos (temas) |
examSlugs | string[] | não | Provas: "2023", "2023-reaplicacao" |
subjectAreaId | string | não | |
subjectId | string | não | |
topicId | string | não | |
yearFrom | number | não | Ano mínimo da prova |
yearTo | number | não | Ano máximo da prova |
difficulty | number, de 1 a 5 | não | |
language | "ingles" \ | "espanhol" | não |
questionCount | number, de 3 a 180 | não | |
timeLimitMin | number | não | Tempo do simulado, em minutos |
pareto | boolean | não | Sorteio ponderado pela incidência no ENEM (Pareto) |
unseenOnly | boolean | não | Só questões nunca respondidas |
onlyFavorites | boolean | não | Só questões favoritadas |
wrongOnly | boolean | não | Só questões que o aluno errou antes |
templateId | string | não | Template do simulado (prova oficial, por área ou personalizado salvo). Sem ele, o simulado é montado só com os filtros. |
saveAs | string | não | Salva este recorte como um simulado personalizado com o nome dado |
Respostas: 201.
POST /api/v1/simulations/pdf
Gera o caderno de prova em PDF no padrão ENEM, com a capa do OpENEM
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): SimulationPdfDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
subjectAreaIds | string[] | não | Áreas do conhecimento. É o filtro que alcança as questões oficiais ainda não classificadas em matéria. |
subjectIds | string[] | não | Matérias |
topicIds | string[] | não | Assuntos (temas) |
examSlugs | string[] | não | Provas: "2023", "2023-reaplicacao" |
subjectAreaId | string | não | |
subjectId | string | não | |
topicId | string | não | |
yearFrom | number | não | Ano mínimo da prova |
yearTo | number | não | Ano máximo da prova |
difficulty | number, de 1 a 5 | não | |
language | "ingles" \ | "espanhol" | não |
questionCount | number, de 3 a 180 | não | |
timeLimitMin | number | não | Tempo do simulado, em minutos |
pareto | boolean | não | Sorteio ponderado pela incidência no ENEM (Pareto) |
unseenOnly | boolean | não | Só questões nunca respondidas |
onlyFavorites | boolean | não | Só questões favoritadas |
wrongOnly | boolean | não | Só questões que o aluno errou antes |
templateId | string | não | Gera o PDF de um template (prova oficial ou salvo) |
title | string | não | Título impresso na capa |
studentName | string | não | Nome do aluno na capa |
theme | string | não | Tema de cor do caderno (mesmos temas do app) |
brandColor | string | não | Cor da marca em hexadecimal, para o tema personalizado |
cover | boolean | não | |
answerSheet | boolean | não | |
answerKey | boolean | não | |
explanations | boolean | não | Inclui os comentários das questões que têm resolução |
twoColumns | boolean | não | Duas colunas, como o caderno oficial |
Respostas: 201.
GET /api/v1/simulations/{id}
Estado de um simulado
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
POST /api/v1/simulations/{id}/pdf
Gera o PDF de um simulado que o aluno já fez
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Corpo (JSON): SimulationPdfDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
subjectAreaIds | string[] | não | Áreas do conhecimento. É o filtro que alcança as questões oficiais ainda não classificadas em matéria. |
subjectIds | string[] | não | Matérias |
topicIds | string[] | não | Assuntos (temas) |
examSlugs | string[] | não | Provas: "2023", "2023-reaplicacao" |
subjectAreaId | string | não | |
subjectId | string | não | |
topicId | string | não | |
yearFrom | number | não | Ano mínimo da prova |
yearTo | number | não | Ano máximo da prova |
difficulty | number, de 1 a 5 | não | |
language | "ingles" \ | "espanhol" | não |
questionCount | number, de 3 a 180 | não | |
timeLimitMin | number | não | Tempo do simulado, em minutos |
pareto | boolean | não | Sorteio ponderado pela incidência no ENEM (Pareto) |
unseenOnly | boolean | não | Só questões nunca respondidas |
onlyFavorites | boolean | não | Só questões favoritadas |
wrongOnly | boolean | não | Só questões que o aluno errou antes |
templateId | string | não | Gera o PDF de um template (prova oficial ou salvo) |
title | string | não | Título impresso na capa |
studentName | string | não | Nome do aluno na capa |
theme | string | não | Tema de cor do caderno (mesmos temas do app) |
brandColor | string | não | Cor da marca em hexadecimal, para o tema personalizado |
cover | boolean | não | |
answerSheet | boolean | não | |
answerKey | boolean | não | |
explanations | boolean | não | Inclui os comentários das questões que têm resolução |
twoColumns | boolean | não | Duas colunas, como o caderno oficial |
Respostas: 201.
POST /api/v1/simulations/{id}/finish
Finaliza e corrige um simulado
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Corpo (JSON): FinishSimulationDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
answers | SimulationAnswerDto[] | sim |
Respostas: 201.
study-plan
GET /api/v1/study-plan
Retorna o cronograma atual com as sessões por dia
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
DELETE /api/v1/study-plan
Recomeça o cronograma vazio, com a semana a partir de hoje
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
POST /api/v1/study-plan/sessions
Adiciona um bloco livre em um dia do calendário (issue #46)
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): CreateSessionDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
label | string | sim | Nome do bloco: "Matemática", "Inglês", "Revisar simulado" |
dayIndex | number | sim | Dia do plano (0 = primeiro dia) |
minutes | number | não | Duração em minutos (padrão 45) |
Respostas: 201.
PATCH /api/v1/study-plan/sessions/{id}
Edita nome, duração, dia ou conclusão de um bloco
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Corpo (JSON): UpdateSessionDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
label | string | não | Nome livre do bloco |
minutes | number | não | Duração do bloco em minutos |
dayIndex | number | não | Dia do plano (0 = primeiro dia) |
done | boolean | não | Marca a sessão como concluída ou não |
Respostas: 200.
DELETE /api/v1/study-plan/sessions/{id}
Remove um bloco do calendário
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
subjects
GET /api/v1/subjects
Lista as áreas do conhecimento e seus assuntos
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
themes
GET /api/v1/themes/mine
Temas de cores criados pelo aluno
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
GET /api/v1/themes/community
Temas publicados pela comunidade (populares ou recentes)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
sort | query | "popular" \ | "recent" | não |
take | query | number, de 1 a 50 | não | |
skip | query | number, mínimo 0 | não |
Respostas: 200.
POST /api/v1/themes
Cria um tema (nasce privado se isPublic não vier)
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): CreateThemeDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | sim | Nome do tema (único por aluno) |
light | object | sim | Lado claro: as 10 cores em #rrggbb |
dark | object | sim | Lado escuro: as 10 cores em #rrggbb |
isPublic | boolean | não | Publica na aba Comunidade (nasce privado) |
Respostas: 201.
PATCH /api/v1/themes/{id}
Edita, publica ou despublica um tema próprio
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Corpo (JSON): UpdateThemeDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | não | Nome do tema (único por aluno) |
light | object | não | Lado claro: as 10 cores em #rrggbb |
dark | object | não | Lado escuro: as 10 cores em #rrggbb |
isPublic | boolean | não | Publica na aba Comunidade (nasce privado) |
Respostas: 200.
DELETE /api/v1/themes/{id}
Apaga um tema próprio
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
POST /api/v1/themes/{id}/like
Curtir/descurtir um tema publicado (toggle)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 201.
tools
GET /api/v1/tools
Ferramentas abertas no GitHub, com a contagem de estrelas (cache de 1 hora)
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
users
GET /api/v1/users/me
Retorna o usuário autenticado e seu perfil
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
DELETE /api/v1/users/me
Exclui a conta e todos os dados do aluno, confirmando a senha atual (LGPD, art. 18)
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): DeleteAccountDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
password | string | sim | Senha atual, para confirmar a exclusão |
Respostas: 204.
GET /api/v1/users/me/export
Baixa todos os dados do aluno em JSON (LGPD, art. 18)
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
GET /api/v1/users/{id}/profile
Perfil público de um usuário (sem PII)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
PUT /api/v1/users/me/profile
Atualiza o perfil de estudo do usuário
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): UpdateProfileDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
goal | "SISU" \ | "PROUNI" \ | "TREINEIRO" |
minutesPerDay | number, de 5 a 1440 | não | Minutos disponíveis para estudo por dia |
displayName | string, até 80 caracteres | não | |
focusMode | boolean | não | Modo sem distrações (interface minimalista) |
gamificationEnabled | boolean | não | Ativa pontos, sequência e conquistas (Fase 3) |
onboarded | boolean | não | Marcado como true ao concluir o onboarding inicial |
foreignLanguage | "ingles" \ | "espanhol" | não |
Respostas: 200.
PUT /api/v1/users/me/password
Troca a senha (pede a atual), encerra as outras sessões e retorna um token novo para este aparelho
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): ChangePasswordDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
currentPassword | string | sim | |
newPassword | string | sim |
Respostas: 200.
videos
GET /api/v1/videos
Biblioteca de vídeos do usuário (issue #37)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
subjectId | query | string | sim |
Respostas: 200.
POST /api/v1/videos
Salva um vídeo por link do YouTube (metadados via oEmbed)
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): CreateVideoDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
url | string | sim | Link do YouTube (ou ID do vídeo) |
subjectId | string | não | Matéria do vídeo |
Respostas: 201.
PATCH /api/v1/videos/{id}
Re-classifica a matéria (ou limpa com null)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Corpo (JSON): UpdateVideoDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
subjectId | object | não | Nova matéria (null para limpar) |
Respostas: 200.
DELETE /api/v1/videos/{id}
Remove o vídeo e suas notas
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
POST /api/v1/videos/{id}/watched
Marca/desmarca como assistido (toggle)
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 201.
GET /api/v1/videos/{id}/notes
Notas do vídeo com timestamp
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.
POST /api/v1/videos/{id}/notes
Adiciona uma nota com timestamp
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Corpo (JSON): AddVideoNoteDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
timestampSec | number, mínimo 0 | sim | Instante da nota, em segundos |
content | string | sim | Conteúdo da nota |
Respostas: 201.
DELETE /api/v1/videos/notes/{noteId}
Remove uma nota própria
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
noteId | caminho | string | sim |
Respostas: 200.
weekly-goals
GET /api/v1/weekly-goals
Metas da semana corrente com o progresso calculado (issue #44)
Exige login (token no cabeçalho Authorization: Bearer).
Respostas: 200.
POST /api/v1/weekly-goals
Cria uma meta para a semana corrente
Exige login (token no cabeçalho Authorization: Bearer).
Corpo (JSON): CreateWeeklyGoalDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
subjectAreaId | string | não | Escopo: área do conhecimento |
subjectId | string | não | Escopo: matéria |
topicId | string | não | Escopo: assunto (tópico) |
targetMinutes | number, mínimo 0 | não | Meta de tempo na semana, em minutos (0 = sem meta de tempo) |
targetQuestions | number, mínimo 0 | não | Meta de questões na semana (0 = sem meta de questões) |
Respostas: 201.
PATCH /api/v1/weekly-goals/{id}
Atualiza os alvos de uma meta própria
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Corpo (JSON): UpdateWeeklyGoalDto
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
targetMinutes | number, mínimo 0 | não | Nova meta de tempo na semana, em minutos |
targetQuestions | number, mínimo 0 | não | Nova meta de questões na semana |
Respostas: 200.
DELETE /api/v1/weekly-goals/{id}
Remove uma meta própria
Exige login (token no cabeçalho Authorization: Bearer).
| Parâmetro | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
id | caminho | string | sim |
Respostas: 200.