Skip to main content
Todos os exemplos assumem a chave em ENEMHUB_API_KEY e a base https://api.enemhub.com.br.

Listar os exames

É por aqui que se começa: /exams devolve o catálogo inteiro, sem paginação, e é dele que saem os examId usados como filtro.
institution e type podem vir null para exames sem essa classificação. Não assuma que estão preenchidos.

Filtrar questões

GET /v1/vestibulares/questions aceita cinco filtros, todos opcionais e combináveis:
Biológicas difíceis da FUVEST
Sem examId, a listagem cobre todos os exames do produto, ENEM incluído.

Paginar até o fim

meta.total é a contagem do conjunto filtrado inteiro, então dá para calcular o número de páginas antes de começar:
limit=100 é o teto. Espelhar um catálogo inteiro a 20 por vez custa cinco vezes mais requisições da sua cota do que a 100 por vez.

Espelhar o catálogo por exame

O caso mais comum de carga inicial: varrer exame a exame, para poder retomar de onde parou se algo falhar no meio.

Buscar uma questão específica

Diferente da listagem, esta rota devolve a questão sem envelope:
Um ID que não existe — ou que pertence a um exame fora deste produto — devolve 404:

Montar uma prova

Correta e alternativas vêm juntas na resposta, então embaralhar e esconder o gabarito é trabalho do seu lado:

Lidar com limites

Toda resposta de /v1/* traz dois headers: Ao estourar, a resposta é 429 com Retry-After: 60. São três limites independentes:
  • Por minuto — definido pelo plano.
  • Por dia — 10.000 requisições, igual para todos os planos.
  • Por mês — a cota do plano. Ao estourar, a mensagem pede upgrade.
Uma requisição recusada com 429 não consome cota mensal. Estourar o limite por minuto não queima o seu volume contratado.
Retry com backoff

Tratar erros

O corpo do erro não é uniforme em toda a API — documentamos o que existe hoje, não o que gostaríamos que existisse.As rotas de gestão devolvem { "error", "message", "statusCode" }. Os erros de autenticação e de rate limit devolvem { "error", "message" }, sem statusCode. E o 404 das rotas de questão devolve só { "error": "Questão não encontrada" }.Ou seja: trate pelo status HTTP, que é consistente, e use error / message apenas para exibir ou registrar em log.
Um wrapper que cobre o caso comum: