ACERVO TEACHY + SAE · API v1

Todas as questões
da habilidade informada.

A API consulta o banco unificado Teachy + SAE e lista todos os IDs vinculados ao código BNCC completo e permite consultar cada questão pelo ID. Também oferece sorteio de uma questão. Ela inclui os dados pedagógicos disponíveis, a resposta original e informações de origem.

Servidor: 0.0.0.0:5000. Neste computador, use http://127.0.0.1:5000. Em outro computador, use http://IP-DO-SERVIDOR:5000. O endereço 0.0.0.0 indica a escuta em todas as interfaces; não é o endereço do cliente. A API não exige token.

← Abrir painel de questões

Painel de consulta

O painel está em /, na mesma porta 5000. Ele consulta o acervo com paginação, busca por palavras do enunciado e filtros combinados. As rotas v1 abaixo preservam o contrato de listagem completa por BNCC.

GET /api/painel/questions?page=1&size=12&origem=teachy&bncc=EF06MA16
GET /api/painel/questions/1
GET /api/painel/stats
GET /api/painel/facets
GET /api/painel/tags?kind=bncc&term=EF06

A listagem paginada retorna items, total, page, pages e size (máximo 50). Filtros: origem (teachy/sae), disciplina, segmento, ano_serie, formato, dificuldade, bncc (código completo), assunto, banca, ano, imagem=sim, q (palavras do enunciado) e sort=antigas (IDs crescentes; padrão decrescente). Valores repetidos do mesmo filtro são combinados com OU; filtros diferentes, com E. As sugestões retornam até 40 valores que começam pelo termo, sem distinção de acentos ou caixa. Menus de filtros são globais, limitados a 250 opções por campo; assuntos, bancas e BNCC usam sugestões. A busca por enunciado usa palavras e prefixos, combina até 12 palavras com E e não interpreta operadores SQL ou FTS enviados pelo cliente.

Listar todas as questões por BNCC

GET /api/v1/questoes?bncc=EF05LP01
{
  "bncc_solicitada": "EF05LP01",
  "total_elegiveis": 2,
  "questoes": [{"id": 123}, {"id": 1000000004013}]
}

O array questoes contém todos os IDs distintos das duas plataformas, em ordem crescente, sem paginação, limite ou sorteio. Tags repetidas não duplicam questões. Um código válido sem resultados retorna HTTP 200, total_elegiveis: 0 e questoes: []. A validação de BNCC é a mesma do sorteio.

Consultar uma questão completa pelo ID

GET /api/v1/questoes/123

Retorna HTTP 200 com {"questao": {...}}. O objeto questao tem todos os campos descritos abaixo, iguais aos do sorteio: enunciado, alternativas, gabarito, resolução, BNCC, classificações, origem, mídias e pendências. Não é necessário informar BNCC; questões sem BNCC também podem ser consultadas pelo ID. ID inexistente retorna 404; ID inválido ou parâmetros adicionais retornam 400 (ID_INVALIDO).

Para percorrer todas as questões, obtenha a lista e guarde os IDs já utilizados no seu sistema. Consulte o conteúdo completo de cada ID e marque como utilizado após processá-lo com sucesso. Em caso de falha, tente novamente o mesmo ID. O sorteio pode repetir questões e não registra quais já foram utilizadas.

A lista representa a base consultada e pode ficar em cache por até 15 segundos. Após uma atualização da base, obtenha uma nova lista. Não há exclusão automática de questões com pendências.

import json
from urllib.request import urlopen

base = "http://127.0.0.1:5000"
with urlopen(base + "/api/v1/questoes?bncc=EF05LP01") as response:
    lista = json.load(response)
for item in lista["questoes"]:
    with urlopen(base + "/api/v1/questoes/" + str(item["id"])) as response:
        questao = json.load(response)["questao"]
    print(questao["id"], questao["enunciado"]["texto"])

Sorteio (rota existente)

GET /api/v1/questoes/aleatoria?bncc=EF05LP01
Accept: application/json
ParâmetroRegra
bnccObrigatório, texto, exatamente um código completo. Ex.: EF05LP01, EF15LP01, EM13MAT101 ou EM13LP01. Letras minúsculas e espaços nas extremidades são normalizados. Não aceita lista, código parcial, repetição do parâmetro ou parâmetros adicionais.

Não envie corpo no GET. O vínculo deve existir nas tags BNCC da questão. Um código válido sem questões cadastradas retorna 404.

Teste nesta página

O resultado completo aparecerá aqui.

Exemplos de cliente

Terminal (no Windows, use curl.exe):

curl "http://127.0.0.1:5000/api/v1/questoes/aleatoria?bncc=EF05LP01"

Python:

import json
from urllib.request import urlopen
from urllib.parse import urlencode

query = urlencode({"bncc": "EF05LP01"})
with urlopen("http://127.0.0.1:5000/api/v1/questoes/aleatoria?" + query) as response:
    dados = json.load(response)
    print(dados["questao"]["enunciado"]["texto"])
    print(dados["questao"]["gabarito"])

Estrutura da resposta — HTTP 200

O exemplo abaixo é ilustrativo e abreviado. O teste acima devolve todos os campos de uma questão real.

{
  "bncc_solicitada": "EF05LP01",
  "total_elegiveis": 42,
  "questao": {
    "id": 123,
    "tipo": "multipla_escolha",
    "tipo_descricao": "Múltipla escolha",
    "enunciado": {"texto": "Enunciado original…", "html": "<p>Enunciado original…</p>"},
    "alternativas": [
      {"posicao": 0, "rotulo": "A", "texto": "Opção A", "html": "Opção A", "correta": true, "comentario_html": ""},
      {"posicao": 1, "rotulo": "B", "texto": "Opção B", "html": "Opção B", "correta": false, "comentario_html": ""}
    ],
    "gabarito": {
      "alternativas_corretas": [{"posicao": 0, "rotulo": "A"}],
      "itens": [{"posicao": 0, "rotulo": "A", "correta": true}, {"posicao": 1, "rotulo": "B", "correta": false}],
      "resposta_discursiva": null,
      "original": {}
    },
    "resolucao": {"texto": "Justificativa original…", "html": "Justificativa original…"},
    "bncc": ["EF05LP01"],
    "classificacoes": [],
    "origem": {
      "plataforma": "sae", "id_externo": "identificador-na-origem",
      "url_portal": "https://app.sae.digital/atividades/avaliacoes/banco-de-questoes",
      "criacao": null, "acervo": null, "banca": null, "ano": null,
      "coletada_em": "2026-10-13T17:00:00+00:00", "atualizada_em": "2026-10-13T17:00:00+00:00"
    },
    "midias": [], "pendencias": [], "midias_pendentes": 0
  }
}
CampoSignificado
bncc_solicitada / total_elegiveisCódigo normalizado e quantidade de questões distintas no conjunto usado pelo sorteio.
questao.idIdentificador inteiro no banco local.
tipo / tipo_descricaoEnum técnico e nome legível. Tipos: discursiva (dissertativa), multipla_escolha, certo_errado, somatoria, desconhecido.
enunciado / resolucaoObjetos com texto e html. O HTML é sanitizado e referencia as mídias locais. Texto ou resolução ausentes permanecem vazios.
alternativas[]posicao começa em zero; rotulo preserva a identificação; texto, html e comentario_html trazem o conteúdo. correta pode ser true, false ou null (não informada). Dissertativas normalmente têm lista vazia.
gabaritoalternativas_corretas contém todas as opções explicitamente corretas; itens preserva as respostas individuais, inclusive false em certo/errado; resposta_discursiva contém a resolução textual original para discursivas, ou null. original preserva o objeto de gabarito salvo pelo coletor: pode conter tipo, alternativas_corretas, itens e opcoes_originais. Não é calculada uma soma para somatória nem inventado um gabarito ausente.
bncc[]Todos os códigos BNCC vinculados à questão, inclusive outros além do solicitado.
classificacoes[]Todas as tags disponíveis. Cada entrada tem kind (tipo), label (nome do tipo), value (valor), description e descriptions (lista de descrições). Inclui segmento, série, disciplina, assunto, dificuldade, banca e demais classificações existentes.
origemplataforma, id_externo, url_portal, criacao, acervo, banca, ano e datas ISO 8601. Banca e demais metadados preservam o formato original, podendo ser objeto, lista, texto ou null. A URL é a do portal, não um link individual inventado.
midias[]id, local (enunciado, alternativa, resolução ou comentário), alternativa_posicao (-1 quando não se aplica), posicao, texto_alternativo, status e url. A URL só é preenchida para arquivos baixados.
pendencias / midias_pendentesLista de pendências de conteúdo e quantidade de mídias ainda não baixadas. Uma questão pode retornar 200 mesmo incompleta; o cliente deve conferir estes campos. Não há filtro oculto excluindo esses registros.

Sorteio e atualização

Cada questão distinta associada ao código tem a mesma chance no sorteio. Chamadas consecutivas são independentes e podem repetir a questão, especialmente quando há poucos resultados. Tags repetidas não aumentam a chance de uma questão. O conjunto de IDs pode ficar em cache por até 15 segundos; a resposta sorteada nunca é reutilizada do cache. O conteúdo vem do banco local, sem disparar uma coleta no SAE.

Imagens

GET /api/media/123

Retorna os bytes do arquivo com seu Content-Type original, ou 404. As URLs do JSON e do HTML começam por /api/media/; combine-as com a mesma origem usada para chamar esta API.

Erros

StatusCódigo / motivo
400ID_INVALIDO: ID inválido ou parâmetros adicionais no detalhe. BNCC_INVALIDA: parâmetro ausente, vazio, repetido ou inválido; ou parâmetro adicional.
404QUESTAO_NAO_ENCONTRADA, MIDIA_NAO_ENCONTRADA ou ROTA_NAO_ENCONTRADA.
405METODO_NAO_PERMITIDO: POST, PUT, PATCH ou DELETE. Utilize GET.
503BASE_INDISPONIVEL: falha ao consultar a base; tente novamente.
{"error":{"codigo":"QUESTAO_NAO_ENCONTRADA","mensagem":"Nenhuma questão com esta tag BNCC foi encontrada na base local."}}

Disponibilidade

GET /health
{"status":"ok","servico":"banco-unificado-question-api"}

Acesso pelo navegador de outra origem não tem CORS habilitado. Integrações de servidor podem chamar a API diretamente; esta documentação funciona na mesma origem.