API Gateway v1.4  ·  https://qapi.otunac.com/api

Base
de Questões de Concurso Público.

Simples, rápido e confiável.

exemplo.py
# pip install requests
import requests
 
BASE = "https://qapi.otunac.com/api"
KEY  = "qb_SuaChaveAqui"
H    = {"Q-Api-Key": KEY}
 
# buscar questões
r = requests.get(
    f"{BASE}/questions",
    params={"banca":"FGV", "ano":2024},
    headers=H
)
print(r.json()["total"])
 
$ python exemplo.py
Novo · MCP Server

Sua base de questões, direto no seu agente de IA

O QAPI MCP Server expõe toda a base de questões via Model Context Protocol (MCP) — o mesmo padrão aberto usado por Claude, ChatGPT e outros agentes de IA para chamar ferramentas externas. Em vez de você integrar cada endpoint REST manualmente no seu agente, conecte-o uma vez ao MCP e todas as ferramentas — questões, provas, concursos, flashcards, simulados, comentários — ficam disponíveis automaticamente para o modelo decidir quando e como chamar.

  • Endpoint único: https://qapi.otunac.com/mcp
  • Mesma API Key da sua conta, no header Q-Api-Key
  • 26 ferramentas — um espelho completo dos endpoints da API hoje disponíveis para clientes com chave e saldo
  • Custo em dobro por chamada — agentes de IA (sobretudo multi-agente/paralelos) multiplicam requisições; ver billing do MCP
Como o QAPI MCP Server funciona Um agente de IA se conecta ao QAPI MCP Server via protocolo MCP usando sua API Key; o servidor autentica, debita cotas em dobro e consulta a base de questões, devolvendo o resultado ao agente. Agente de IA Claude, GPT, etc. MCP Q-Api-Key QAPI MCP Server /mcp 26 ferramentas 2x custo/req HTTPS Base de Questões +27.000 itens 1. chama uma tool 2. autentica + debita cotas 3. consulta dados
Agente de IA ↔ MCP (JSON-RPC/HTTP) ↔ QAPI ↔ Base de Questões
+27 mil Questões na base
26 Ferramentas MCP
15 Endpoints REST
R$0,01 / req (2x via MCP)
JWT + API Key
recursos

Tudo que você precisa para integrar em minutos

API Key única

Cada conta recebe uma chave prefixada qb_ gerada com 40 caracteres aleatórios seguros.

Dashboard em tempo real

Gráfico de barras com consumo diário dos últimos 30 dias, custo mensal e histórico de pagamentos.

Leitura + colaboração

A maior parte da API é somente leitura. Comentários e chamados de suporte também podem ser criados, editados e removidos diretamente pela API.

Gabarito e comentário inclusos

Cada questão já chega com o gabarito e o comentario (justificativa da resposta) na mesma requisição — sem custo extra e sem endpoint separado.

CPF único por conta

Cadastro exige CPF válido e único, prevenindo criação de múltiplas contas por um mesmo usuário.

Créditos antecipados

Pague via PIX antes de usar e recarregue cotas a qualquer momento — sem fatura mensal. O crédito não expira: o saldo fica na conta até ser usado.

documentação

Referência completa da API

Base URL: https://qapi.otunac.com/api  ·  Header obrigatório: Q-Api-Key: qb_SuaChave

MCP Server — Visão geral

O QAPI MCP Server é uma segunda forma de acessar exatamente os mesmos dados da API REST abaixo — desenhada para ser consumida por agentes de IA (Claude, ChatGPT, e qualquer cliente compatível com Model Context Protocol) em vez de código escrito à mão. Onde a API REST exige que você implemente cada chamada HTTP individualmente, o MCP expõe um catálogo de 26 ferramentas que o próprio modelo descobre e decide quando invocar — você conecta uma vez, o agente aprende o resto.

Endpoint MCP (streamable HTTP)
POST https://qapi.otunac.com/mcp
Q-Api-Key: qb_SuaChaveAqui
Content-Type: application/json
MCPAPI REST
Consumidor típicoAgente de IA (LLM decide o que chamar)Código escrito por você
DescobertaAutomática — tools/listManual — esta página
AutenticaçãoHeader Q-Api-Key (mesma chave)Header Q-Api-Key
Custo por chamada2 cotas1 cota
Dados retornadosIdênticosIdênticos
Como funciona

O MCP usa o transporte streamable HTTP (JSON-RPC 2.0 sobre um único endpoint POST /mcp) — sem estado de sessão entre chamadas: cada requisição é independente, autenticada pelo próprio header Q-Api-Key.

1. Descoberta — não exige API Key

Ao conectar, o agente lista as ferramentas disponíveis (tools/list) junto com nome, descrição e parâmetros de cada uma — sem precisar de chave, igual à documentação pública desta página. Só a execução de uma ferramenta exige autenticação.

2. Execução — exige Q-Api-Key ativa e saldo

Cada chamada de ferramenta (tools/call) carrega o header Q-Api-Key. O servidor valida a chave (ativa, não suspensa) e o saldo de cotas exatamente como a API REST — e só então repassa a chamada para a base de questões.

3. Resposta

Em caso de sucesso, a ferramenta devolve o mesmo JSON que o endpoint REST equivalente retornaria. Em caso de erro (chave ausente/inválida, sem saldo, recurso não encontrado), a ferramenta devolve um resultado de erro (isError: true) com uma mensagem legível — o agente lê o motivo e pode agir (avisar o usuário, sugerir recarregar cotas etc.), em vez de travar. Ver Erros no MCP.

Configurar seu agente

A configuração varia por cliente, mas todos pedem a mesma URL e o mesmo header. Exemplos:

Claude Code (linha de comando)
claude mcp add --transport http qapi https://qapi.otunac.com/mcp \
  --header "Q-Api-Key: qb_SuaChaveAqui"
Claude Web (claude.ai)

Ao conectar o QAPI como servidor MCP no Claude Web, informe a chave no header x-api-key — o Claude Web não aceita o header Q-Api-Key. Use a mesma chave e a mesma URL:

URL:     https://qapi.otunac.com/mcp
Header:  x-api-key: qb_SuaChaveAqui
Configuração genérica (Claude Desktop, e outros clientes MCP)
{
  "mcpServers": {
    "qapi": {
      "type": "http",
      "url": "https://qapi.otunac.com/mcp",
      "headers": {
        "Q-Api-Key": "qb_SuaChaveAqui"
      }
    }
  }
}

Sua chave está disponível em /dashboard (se estiver logado, também aparece pronta pra copiar nos exemplos de código de lá).

Ferramentas disponíveis (26)

Uma ferramenta MCP para cada endpoint hoje protegido por Q-Api-Key na API REST — mesmos filtros, mesmos limites de paginação (máx. 10 itens/página), mesmos dados.

Questões e textos
FerramentaEquivalente RESTDescrição
get_questoesGET /api/questoesConsulta questões com filtros (qCode, banca, órgão, cargo, matéria, assunto, enunciado, ano) e paginação
get_textoGET /api/textos/:codigoTexto/base de referência associado a uma questão
Catálogos de filtros
FerramentaEquivalente RESTDescrição
get_bancasGET /api/bancasLista bancas organizadoras
get_orgaosGET /api/orgaosLista órgãos públicos
get_cargosGET /api/cargosLista cargos
get_materiasGET /api/materiasLista matérias
get_assuntosGET /api/assuntosLista assuntos de uma matéria (parâmetro materia obrigatório)
Provas
FerramentaEquivalente RESTDescrição
get_provasGET /api/provasLista provas com filtros e paginação — 200 cotas por chamada (tarifa diferenciada)
get_prova_por_idGET /api/provas/:idProva pelo ID, incluindo links de PDF quando disponíveis — 200 cotas por chamada (tarifa diferenciada)
Concursos
FerramentaEquivalente RESTDescrição
get_concursosGET /api/concursosLista concursos públicos com filtros (órgão, banca, status, ano, cargo, região, estado) e paginação
get_concurso_por_idGET /api/concursos/:idConcurso pelo ID
get_status_concursoGET /api/concursos/statusValores fixos aceitos pelo campo status
Disciplinas e conteúdo programático
FerramentaEquivalente RESTDescrição
get_disciplinasGET /api/disciplinasDisciplinas de edital (filtros: concurso, cargo, matéria)
get_disciplina_por_idGET /api/disciplinas/:idDisciplina de edital pelo ID
get_conteudosGET /api/conteudosLista plana do conteúdo programático de uma disciplina
get_conteudos_arvoreGET /api/conteudos/arvoreÁrvore completa (aninhada) do conteúdo programático
Flashcards
FerramentaEquivalente RESTDescrição
get_flashcardsGET /api/flashcardsLista flashcards com filtros e paginação
get_flashcard_por_idGET /api/flashcards/:idFlashcard pelo ID
Apostilas
FerramentaEquivalente RESTDescrição
get_apostilasGET /api/apostilasCatálogo de apostilas/e-books com filtros e paginação
get_apostila_por_idGET /api/apostilas/:idApostila pelo ID
Simulados
FerramentaEquivalente RESTDescrição
gerar_simuladoGET /api/simuladosMonta um simulado sob demanda a partir de filtros — não persiste nada
Comentários
FerramentaEquivalente RESTDescrição
listar_comentariosGET /api/comentariosLista comentários, opcionalmente filtrados por questão
criar_comentarioPOST /api/comentariosCria um comentário sobre uma questão
atualizar_comentarioPUT /api/comentarios/:idAtualiza texto e/ou autor de um comentário
remover_comentarioDELETE /api/comentarios/:idRemove um comentário
Suporte
FerramentaEquivalente RESTDescrição
abrir_chamado_suportePOST /api/suporteAbre um chamado de suporte (bug, questão incorreta, falha de serviço)
Billing do MCP 2x o custo normal

Cada chamada de ferramenta via MCP debita 2 cotas do seu saldo — o dobro de uma requisição equivalente na API REST (1 cota). O saldo é o mesmo das duas formas de acesso: cotas compradas em /payments valem tanto para REST quanto para MCP, sem plano separado.

Por que o dobro?

Agentes de IA — sobretudo fluxos multi-agente/paralelos, que exploram a base de forma automatizada — tendem a multiplicar o número de requisições em relação a um cliente programático tradicional. O custo em dobro contém abuso sem proibir o uso legítimo.

Sem saldo suficiente

Se o saldo for insuficiente para o custo em dobro (ex: 1 cota restante, que bastaria para uma requisição REST mas não para uma chamada MCP), a ferramenta recusa a chamada com uma mensagem de erro explicando o motivo — nenhuma cota é debitada nesse caso, sem consumo parcial.

Erros no MCP

Diferente da API REST (que usa códigos de status HTTP), erros de uma ferramenta MCP chegam como um resultado com isError: true e uma mensagem de texto — o formato que os agentes de IA esperam para decidir o que fazer a seguir.

SituaçãoMensagem (resumo)
Sem header Q-Api-Key"Header 'Q-Api-Key' é obrigatório..."
Chave inválida"API Key inválida."
Chave suspensa"Sua chave de API foi suspensa por falta de pagamento..."
Conta desativada"Conta desativada. Entre em contato com o suporte."
Saldo insuficiente p/ custo em dobro"Você não possui créditos (cotas) suficientes para usar o QAPI via MCP..."
Recurso não encontrado (ex: ID inexistente)"Prova não encontrada.", "Concurso não encontrado.", etc.
Autenticação

Todos os endpoints de consulta requerem uma API Key enviada no header HTTP Q-Api-Key. Você obtém sua chave ao criar uma conta — ela fica disponível no seu dashboard.

Header obrigatório em todas as requisições
Q-Api-Key: qb_SuaChaveAqui

A chave é prefixada com qb_ seguido de 40 caracteres aleatórios. Mantenha-a em segredo — nunca exponha em código público ou repositórios. Se necessário, redefina-a pelo suporte.

Paginação

Os endpoints que retornam listas suportam paginação via query parameters. Todos seguem o mesmo padrão de resposta com metadados de paginação.

Parâmetros de paginação comuns
ParâmetroTipoPadrãoDescrição
pageinteger1Número da página (começa em 1)
sizeinteger10Itens por página. Máximo de 10 em todos os endpoints de listagem (questões, provas, concursos, flashcards, apostilas, bancas, órgãos, cargos, matérias e assuntos). Valores maiores são reduzidos para 10 automaticamente
Estrutura de resposta paginada
{
  "page":  1,      // página atual
  "size":  10,     // itens nesta página
  "pages": 63,     // total de páginas
  "total": 624,    // total de itens encontrados
  "questoes": [/* array de itens */]
}

Para percorrer todos os resultados, itere de page=1 até page=pages. Cada página consome 1 requisição no seu billing.

Questões

Endpoint principal para consulta de questões com filtros opcionais e paginação. Limite máximo de 10 itens por página. Combine múltiplos filtros para refinar os resultados — todos os filtros são cumulativos (AND).

GET /api/questoes Q-Api-Key canônico
Parâmetros de query
ParâmetroTipoReq.Descrição
pageinteger—Página (padrão: 1)
sizeinteger—Itens por página — máximo 10 (padrão: 10)
qCodestring—Código único da questão (Q-XXXXXXX). Localiza uma questão específica; combina com os demais filtros. Aceita também sem o prefixo e em minúsculas. Código inexistente ou malformado retorna lista vazia
bancastring—Banca organizadora — casa pelo nome completo ou pela sigla (ex: "FGV" e "Fundação Getulio Vargas" retornam o mesmo conjunto). Use /api/bancas para listar valores válidos
orgaostring—Órgão da prova — mesma busca por nome completo ou sigla. Use /api/orgaos para listar valores válidos
cargostring—Cargo da prova. Use /api/cargos para listar valores válidos
materiastring—Disciplina/matéria. Use /api/materias para listar valores válidos
assuntostring—Assunto específico da matéria. Use /api/assuntos para listar
enunciadostring—Busca textual livre (contains, case-insensitive) no enunciado da questão
anointeger—Ano de realização da prova (ex: 2024)
Exemplo de request
GET https://qapi.otunac.com/api/questoes?page=1&size=10&banca=FGV&ano=2024
Q-Api-Key: qb_SuaChaveAqui
Response 200
{
  "page":  1,
  "size":  10,
  "pages": 63,
  "total": 624,
  "questoes": [
    {
      "_id":      "69a8224af6d9445ec04dad9c",
      "qCode":    "Q-7KD4M2P",  // identificador único e estável da questão
      "orgao":    "TJ/SE",
      "banca":    "FGV",
      "siglaBanca":"FGV",
      "siglaOrgao":"TJ/SE",
      "ano":      2023,
      "cargo":    "Analista Judiciário - Análise de Sistemas",
      "materia":  "Conhecimento Específico",
      "assunto":  "Arquitetura de Computadores",
      "enunciado":"Em sistemas operacionais, a métrica que mede...",
      "opcaoA":   "throughput;",
      "opcaoB":   "tempo de espera;",
      "opcaoC":   "tempo de turnaround;",
      "opcaoD":   "tempo de processador;",
      "opcaoE":   "utilização do processador.",
      "gabarito": "A",
      "comentario":"Throughput é o número de processos...",
      "texto":    "QTXT566467"  // código p/ buscar o texto em /api/texts/:codigo
    }
  ]
}

siglaBanca/siglaOrgao são a sigla resolvida a partir do catálogo (pode vir null quando a instituição não tem sigla cadastrada). A base tem questões salvas ora com o nome completo em banca/orgao, ora com a sigla — o filtro já casa os dois formatos automaticamente, então normalmente você não precisa olhar esses campos pra filtrar.

qCode — identificador único da questão. Toda questão tem um código externo no formato Q-XXXXXXX (a letra Q, um hífen e 7 caracteres alfanuméricos maiúsculos, sem 0, O, 1 e I). Ele é estável — nunca muda depois de criado — e único na base. Use-o como chave da questão na sua aplicação, no lugar do _id interno do banco: GET /api/questoes?qCode=Q-7KD4M2P. O mesmo filtro existe na ferramenta MCP get_questoes.

Markdown em enunciado e nas alternativas (opcaoA–opcaoE). As bancas destacam o termo cobrado dentro do próprio enunciado e da alternativa, e entregar texto puro apagava parte desse destaque. Por isso esses campos agora podem conter Markdown (negrito, itálico, sublinhado, listas...). Se você renderizava esses campos como texto simples, as marcações vão aparecer cruas na tela (ex.: **termo**). Ajuste sua aplicação para renderizar Markdown — qualquer biblioteca (marked, markdown-it, react-markdown, python-markdown) resolve; sanitize o HTML resultante antes de exibir.

Exemplos de código
## cURL
curl -X GET \
  "https://qapi.otunac.com/api/questoes?banca=FGV&materia=Direito+Administrativo&page=1&size=10" \
  -H "Q-Api-Key: qb_SuaChaveAqui"

## cURL — busca por enunciado
curl -X GET \
  "https://qapi.otunac.com/api/questoes?enunciado=direitos+fundamentais&size=10" \
  -H "Q-Api-Key: qb_SuaChaveAqui"

## Python
import requests

r = requests.get(
    "https://qapi.otunac.com/api/questoes",
    params={"banca": "FGV", "materia": "Direito Administrativo", "page": 1, "size": 10},
    headers={"Q-Api-Key": "qb_SuaChaveAqui"}
)
data = r.json()
print(f"Total: {data['total']} questões, {data['pages']} páginas")

## JavaScript
const params = new URLSearchParams({ banca: "FGV", materia: "Direito Administrativo", page: 1, size: 10 });
const r = await fetch(`https://qapi.otunac.com/api/questoes?${params}`, {
  headers: { "Q-Api-Key": "qb_SuaChaveAqui" }
});
const data = await r.json();
Alias de compatibilidade (mantido): /api/questions
Textos

Recupera o texto completo referenciado pelo campo texto de uma questão. Questões que não possuem texto base retornam esse campo como string vazia — verifique antes de fazer a chamada.

GET /api/textos/:codigo Q-Api-Key canônico
Parâmetro de path
ParâmetroTipoReq.Descrição
codigostring SimCódigo do texto — valor do campo texto retornado em /questoes
Exemplo de request
GET https://qapi.otunac.com/api/textos/QTXT566467
Q-Api-Key: qb_SuaChaveAqui
Response 200
{
  "_id":       "69b0cfaa20dadd7d66bfcec9",
  "codigo":    "QTXT566467",
  "titulo":    "A reinvenção da vírgula",
  "texto":     "No começo de 1902, Machado de Assis...",
  "fonte":     "Machado de Assis",
  "createdAt": "2026-03-11T02:12:58.079Z"
}
Padrão de uso recomendado
## Python — buscar questão e carregar seu texto base
import requests

BASE    = "https://qapi.otunac.com/api"
headers = {"Q-Api-Key": "qb_SuaChaveAqui"}

questoes = requests.get(f"{BASE}/questoes", params={"banca": "FGV"}, headers=headers).json()

for q in questoes["questoes"]:
    if q["texto"]:  # campo não vazio → tem texto base
        txt = requests.get(f"{BASE}/textos/{q['texto']}", headers=headers).json()
        print(txt["titulo"], txt["texto"][:200])
Alias de compatibilidade (mantido): /api/texts/:codigo
Provas

Lista e consulta provas cadastradas no sistema — cada prova agrupa as questões de um exame identificado por banca, órgão, cargo e ano. O campo linkProva aponta para o PDF do exame e linkGabarito para o gabarito oficial, quando disponíveis.

Tarifa diferenciada (desde 11/10/2026): R$ 1,00 por requisição (100 cotas), contra 1 cota nas demais rotas. Os PDFs ficam em armazenamento em nuvem mantido por nós, com acesso permanente ao arquivo original — o que gera custo de storage e transferência além do servidor e do banco. Cada requisição retorna até 10 provas, ou seja, ≈ R$ 0,10 por prova. Vale para GET /api/provas e GET /api/provas/:id; via MCP o custo é o dobro (200 cotas). Só é cobrado quando a resposta é 200. Com saldo positivo, mas abaixo de 100 cotas, a rota responde 402 sem consumir nada.

GET /api/provas Q-Api-Key
Query parameters
ParâmetroTipoReq.Descrição
pageinteger—Página (padrão: 1)
sizeinteger—Itens por página, máx. 10 (padrão: 10)
bancastring—Filtrar por banca organizadora
orgaostring—Filtrar por órgão
cargostring—Filtrar por cargo
anointeger—Filtrar por ano do exame
Exemplo de request
GET https://qapi.otunac.com/api/provas?banca=CEBRASPE&ano=2024&page=1&size=10
Q-Api-Key: qb_SuaChaveAqui
Response 200
{
  "provas": [
    {
      "_id":          "6a164c795e06528a230ff9d4",
      "orgao":         "Polícia Federal",
      "banca":         "CEBRASPE",
      "cargo":         "Delegado Federal",
      "ano":           2024,
      "linkProva":     "https://cdn.exemplo.com/prova.pdf",
      "linkGabarito":  "https://cdn.exemplo.com/gabarito.pdf",
      "createdAt":     "2025-05-30T14:00:00.000Z"
    }
  ],
  "total": 12,
  "page":  1,
  "size":  10,
  "pages": 2
}
GET /api/provas/:id Q-Api-Key
Parâmetro de path
ParâmetroTipoReq.Descrição
idstring SimID da prova (ObjectId MongoDB)
Exemplo de request
GET https://qapi.otunac.com/api/provas/6a164c795e06528a230ff9d4
Q-Api-Key: qb_SuaChaveAqui
Response 200
{
  "_id":          "6a164c795e06528a230ff9d4",
  "orgao":         "Polícia Federal",
  "banca":         "CEBRASPE",
  "cargo":         "Delegado Federal",
  "ano":           2024,
  "linkProva":     "https://cdn.exemplo.com/prova.pdf",
  "linkGabarito":  "https://cdn.exemplo.com/gabarito.pdf",
  "uploadProva":   { "filename": "pf_2024.pdf", "size": 2048576, "uploadedAt": "2025-05-30T14:00:00.000Z" },
  "uploadGabarito": { "filename": "gabarito_pf_2024.pdf", "size": 512000, "uploadedAt": "2025-05-30T15:00:00.000Z" },
  "createdAt":     "2025-05-30T14:00:00.000Z"
}
Retorna 404 quando o ID não existe. Os campos linkProva e linkGabarito são null quando o PDF ainda não foi enviado.
Concursos

Concursos públicos em andamento no Brasil, cadastrados pela equipe do QBase. Todos os campos além de orgao, descricao, status e ano são opcionais e salvos como texto livre, sem parsing de data/valor.

orgao e banca são objetos, não strings — cada um traz _id, nome, logo (URL da imagem, para exibir o concurso na sua interface) e website do órgão/banca, quando cadastrados no catálogo do QBase. Sem correspondência no catálogo, você recebe apenas { "nome": "..." }. banca é null quando ainda não definida. Os filtros de query orgao/banca continuam sendo pelo nome (string).

GET /api/concursos Q-Api-Key
Query parameters
ParâmetroTipoReq.Descrição
pageinteger—Página (padrão: 1)
sizeinteger—Itens por página, máx. 10 (padrão: 10)
orgaostring—Filtrar por órgão
bancastring—Filtrar por banca organizadora
statusstring—Filtrar por status (ver /concursos/status abaixo)
anointeger—Filtrar por ano do concurso
cargostring—Filtrar concursos que ofereçam este cargo
regiaostring—Filtrar por região: norte, nordeste, centro-oeste, sudeste, sul ou nacional
estadostring—Filtrar por estado — nome (Paraíba) ou sigla (PB); sem distinção de acento/caixa
siglaEstadostring—Filtrar pela UF (PB, SP...). Região/estado inexistentes retornam 400
searchstring—Busca parcial em órgão e descrição
Exemplo de request
GET https://qapi.otunac.com/api/concursos?status=editais+publicados&ano=2026&page=1&size=10
Q-Api-Key: qb_SuaChaveAqui
Response 200
{
  "concursos": [
    {
      "_id":            "6a582f98b7e102f6a66d0e16",
      "orgao": { "_id": "659a1b2c...", "nome": "DATAPREV", "logo": "https://cdn.../logo_dataprev.png", "website": "https://www.dataprev.gov.br" },
      "banca": { "_id": "65b2c3d4...", "nome": "FGV Conhecimento", "logo": "https://cdn.../logo_fgv.png", "website": "https://conhecimento.fgv.br" },
      "descricao":       "Informações sobre o concurso público...",
      "status":          "editais publicados",
      "vagas":           212,
      "cargos":          ["Engenharia", "Advocacia"],
      "requisitos":      "Nível superior",
      "remuneracao":     "até R$ 10.685,44",
      "taxaInscricao":   "110,00",
      "website":         "https://conhecimento.fgv.br/concursos/dataprev26",
      "inicioInscricao": "6 de julho de 2026 às 16h",
      "fimInscricao":    "6 de agosto de 2026 às 16h",
      "dataProva":       "11 de outubro de 2026",
      "horaProva":       null,
      "validade":        "2 anos (podendo ser prorrogado)",
      "ano":             2026,
      "regiao":          "nordeste",
      "estado":          "Paraíba",
      "siglaEstado":     "PB",
      "createdAt":       "2026-07-16T01:10:48.150Z"
    }
  ],
  "total": 2,
  "page":  1,
  "size":  10,
  "pages": 1
}
GET /api/concursos/:id Q-Api-Key
Parâmetro de path
ParâmetroTipoReq.Descrição
idstring SimID do concurso (ObjectId MongoDB)
Exemplo de request
GET https://qapi.otunac.com/api/concursos/6a582f98b7e102f6a66d0e16
Q-Api-Key: qb_SuaChaveAqui
Retorna o mesmo formato de objeto do endpoint de listagem. Retorna 404 quando o ID não existe.
GET /api/concursos/status Q-Api-Key

Retorna a lista fixa de valores aceitos pelo campo status, na ordem do fluxo de um concurso — útil para popular um filtro na sua aplicação.

Response 200
{
  "status": [
    "solicitado", "autorizado", "banca em definição",
    "banca contratada", "comissão formada", "previsto",
    "anunciado", "editais publicados"
  ]
}
Simulados

Gera um simulado sob demanda a partir dos filtros informados — nada é salvo no banco. Repita a mesma chamada e receba uma seleção e ordem diferentes a cada vez: com mais questões disponíveis que size, um subconjunto aleatório é sorteado a cada chamada; com poucas (ou nenhuma), você recebe o que existir, sempre embaralhado.

GET /api/simulados Q-Api-Key
Parâmetros de query
ParâmetroTipoReq.Descrição
bancastring—Banca organizadora
orgaostring—Órgão da prova
cargostring—Cargo da prova
materiastring—Disciplina/matéria
assuntostring—Assunto específico da matéria
anointeger—Ano de realização da prova
sizeinteger—Quantidade de questões — máximo 10 (padrão: 10)
Exemplo de request
GET https://qapi.otunac.com/api/simulados?banca=FGV&materia=Direito+Constitucional&size=10
Q-Api-Key: qb_SuaChaveAqui
Response 200
{
  "questoes": [ /* array de questões, na ordem sorteada */ ],
  "total": 137,   // total de questões que batem com o filtro
  "size":  10    // quantidade efetivamente retornada
}

Todos os filtros são opcionais e combináveis — chame sem nenhum para sortear questões de toda a base.

Catálogos de filtros

Use esses endpoints para descobrir os valores válidos dos filtros de /api/questions. Todos suportam paginação e busca por texto — em bancas/órgãos, o parâmetro search casa tanto pelo nome quanto pela sigla da instituição.

Parâmetros comuns a todos os catálogos:   page (integer, padrão: 1)  ·  size (integer, padrão e máximo: 10)  ·  search (string — busca parcial; em bancas/órgãos, casa nome ou sigla)
GET /api/bancas Q-Api-Key

Lista as bancas organizadoras. Use search para filtrar por nome ou sigla — ex: "fgv" encontra "Fundação Getulio Vargas" mesmo que você não digite o nome completo.

GET https://qapi.otunac.com/api/bancas?page=1&size=10&search=fgv
Q-Api-Key: qb_SuaChaveAqui
{
  "bancas": [
    {
      "_id":     "6a2cfe8e4d53df4eac8fe0b4",
      "nome":    "Fundação Getulio Vargas",
      "sigla":   "FGV",
      "logo":    "https://.../logo_fgv.png",
      "website": null
    }
  ],
  "total": 1, "page": 1, "pages": 1
}

sigla/logo/website vêm null quando não cadastrados no catálogo.

GET /api/orgaos Q-Api-Key

Lista os órgãos. Use search para busca parcial por nome ou sigla.

GET https://qapi.otunac.com/api/orgaos?page=1&size=5&search=ces
Q-Api-Key: qb_SuaChaveAqui
{
  "orgaos": [
    {
      "_id":     "659f...",
      "nome":    "Centro de Seleção e de Promoção de Eventos",
      "sigla":   "CESPE",
      "logo":    null,
      "website": null
    }
  ],
  "total": 1, "page": 1, "pages": 1
}
GET /api/cargos Q-Api-Key

Lista os cargos disponíveis na base.

GET https://qapi.otunac.com/api/cargos?page=1&size=10&search=professor
Q-Api-Key: qb_SuaChaveAqui
{
  "cargos": ["Professor de Ensino Básico", "Professor Adjunto"],
  "total": 2, "page": 1, "pages": 1
}
GET /api/materias Q-Api-Key

Lista as matérias e disciplinas disponíveis.

GET https://qapi.otunac.com/api/materias?page=1&size=5&search=Direito
Q-Api-Key: qb_SuaChaveAqui
{
  "materias": ["Direito Administrativo", "Direito Constitucional", "Direito Civil"],
  "total": 3, "page": 1, "pages": 1
}
GET /api/assuntos Q-Api-Key

Lista os assuntos de uma matéria. materia é obrigatório.

ParâmetroTipoReq.Descrição
materiastring SimNome exato da matéria (obter via /api/materias)
pageinteger—Página
sizeinteger—Itens por página
searchstring—Busca parcial no nome do assunto
GET https://qapi.otunac.com/api/assuntos?materia=Tecnologia+Java&page=1&size=5&search=hibernate
Q-Api-Key: qb_SuaChaveAqui
{
  "materia": "Tecnologia Java",
  "assuntos": ["Hibernate / JPA", "Hibernate Cache"],
  "total": 2, "page": 1, "pages": 1
}
Comentários

Comente em qualquer questão — para tirar dúvidas, discutir a resolução ou reportar um gabarito incorreto. Os comentários são compartilhados: qualquer chamada à API vê a mesma conversa em uma questão.

POST /api/comentarios Q-Api-Key
Request body
CampoTipoReq.Descrição
questaostringID da questão comentada
usuariostringNome de quem está comentando
comentariostringTexto do comentário
POST https://qapi.otunac.com/api/comentarios
Q-Api-Key: qb_SuaChaveAqui
Content-Type: application/json

{
  "questao":    "69a8224af6d9445ec04dad9c",
  "usuario":    "Maria Souza",
  "comentario": "O gabarito está incorreto, a alternativa correta é a B."
}
Response 201
{
  "_id":        "6a539f2c790ad5b7852c63ad",
  "questao":    "69a8224af6d9445ec04dad9c",
  "usuario":    "Maria Souza",
  "comentario": "O gabarito está incorreto, a alternativa correta é a B.",
  "createdAt":  "2026-07-12T14:05:32.740Z",
  "updatedAt":  "2026-07-12T14:05:32.740Z"
}
GET /api/comentarios?questao=:id Q-Api-Key

Lista os comentários de uma questão, em ordem cronológica. Lista vazia se a questão ainda não tiver comentários.

GET https://qapi.otunac.com/api/comentarios?questao=69a8224af6d9445ec04dad9c
Q-Api-Key: qb_SuaChaveAqui
{
  "comentarios": [
    { "_id": "...", "usuario": "Maria Souza", "comentario": "O gabarito está incorreto...", "createdAt": "..." }
  ]
}
PUT /api/comentarios/:id Q-Api-Key

Atualiza usuario e/ou comentario. Retorna 404 se o ID não existir.

PUT https://qapi.otunac.com/api/comentarios/6a539f2c790ad5b7852c63ad
Q-Api-Key: qb_SuaChaveAqui
Content-Type: application/json

{ "comentario": "Editado: na verdade o gabarito está certo." }
DELETE /api/comentarios/:id Q-Api-Key

Remove um comentário. Retorna 204 sem corpo. 404 se o ID não existir.

DELETE https://qapi.otunac.com/api/comentarios/6a539f2c790ad5b7852c63ad
Q-Api-Key: qb_SuaChaveAqui
Suporte

Abra um chamado diretamente pela API — bug na API, questão incorreta, falha de serviço, ou qualquer outro problema.

POST /api/suporte Q-Api-Key
Request body
CampoTipoReq.Descrição
incidentestringTítulo curto do problema
descricaostringDetalhes do problema
nomeDoClientestringNome de quem está reportando
emailstringE-mail para retorno
POST https://qapi.otunac.com/api/suporte
Q-Api-Key: qb_SuaChaveAqui
Content-Type: application/json

{
  "incidente":     "Falha no endpoint /api/questoes",
  "descricao":     "Recebendo 500 ao filtrar por banca=FGV.",
  "nomeDoCliente": "João Silva",
  "email":         "[email protected]"
}
Response 201
{
  "_id":           "6a539f3f790ad5b7852c63b8",
  "incidente":     "Falha no endpoint /api/questoes",
  "descricao":     "Recebendo 500 ao filtrar por banca=FGV.",
  "nomeDoCliente": "João Silva",
  "email":         "[email protected]",
  "createdAt":     "2026-07-12T14:05:51.772Z"
}

Apenas a abertura de chamados é exposta pela API pública — consulta, edição e remoção de chamados ficam restritas à equipe do QAPI.

Autenticação programática

Endpoints para criar conta e obter token via API. Útil para integrações automatizadas. O CPF brasileiro válido é obrigatório no cadastro — cada CPF pode ter apenas uma conta.

POST /api/auth/register

Cria uma nova conta e retorna a api_key gerada automaticamente — prefixada com qb_.

Request body
CampoTipoReq.Descrição
namestringNome completo
emailstringE-mail único (usado no login)
cpfstringCPF brasileiro válido (formato: 123.456.789-09 ou apenas dígitos)
passwordstringSenha com mínimo de 8 caracteres
POST https://qapi.otunac.com/api/auth/register
Content-Type: application/json

{
  "name":     "João Silva",
  "email":    "[email protected]",
  "cpf":      "123.456.789-09",
  "password": "minhasenha123"
}
Response 201
{
  "message": "Conta criada com sucesso.",
  "api_key": "qb_abc123xyz..."   // guarde esta chave!
}
POST /api/auth/login

Autentica com e-mail e senha. Retorna um JWT Bearer token e os dados da conta, incluindo a api_key.

Request body
CampoTipoReq.Descrição
emailstringE-mail cadastrado
passwordstringSenha da conta
POST https://qapi.otunac.com/api/auth/login
Content-Type: application/json

{
  "email":    "[email protected]",
  "password": "minhasenha123"
}
Response 200
{
  "token":          "eyJhbGci...",   // JWT — válido por 24h
  "api_key":        "qb_abc123xyz...",
  "api_key_active": true
}

O JWT retornado pode ser usado como Authorization: Bearer <token> em rotas autenticadas da web. Para acesso à API de questões, use sempre o Q-Api-Key header com sua api_key.

Tratamento de erros

A API retorna erros em formato JSON com um campo error descritivo. Use o HTTP status code para determinar o tipo de falha.

HTTP Status Codes
StatusSignificadoCausa comum
200OKRequisição processada com sucesso
400Bad RequestParâmetro inválido ou ausente (ex: materia ausente em /assuntos)
401UnauthorizedHeader Q-Api-Key ausente ou inválido
402Payment RequiredSem cotas (créditos) em saldo — modelo pré-pago vigente desde 01/08/2026
403ForbiddenChave de API suspensa
404Not FoundRecurso não encontrado (ex: código de texto inexistente)
422UnprocessableDado inválido no corpo (registro/login)
500Server ErrorErro interno — tente novamente ou contate o suporte
Estrutura de resposta de erro
{
  "error": "Chave de API inválida ou inexistente."
}
Exemplo de tratamento em Python
import requests

r = requests.get(
    "https://qapi.otunac.com/api/questions",
    headers={"Q-Api-Key": "qb_SuaChave"}
)

if r.status_code == 200:
    data = r.json()
elif r.status_code == 401:
    raise ValueError("API Key inválida")
elif r.status_code == 402:
    raise PermissionError("Sem créditos — insira cotas para continuar")
elif r.status_code == 403:
    raise PermissionError("Chave suspensa — contate o suporte")
else:
    r.raise_for_status()
preços

Créditos antecipados — pague antes, use sem surpresas

Sem mensalidade, sem taxa de adesão. Desde 01/08/2026, o QAPI funciona por cotas pré-pagas: recarregue a partir de R$ 50,00 (múltiplos de R$ 50,00) e use enquanto houver saldo — sem cotas, a API não responde.

R$10,00
a cada 1.000 requisições (até 10 itens cada) · recarga mín. R$ 50,00
  • Crédito sem prazo de validade — as cotas não expiram
  • Gabarito e comentário inclusos em cada questão, sem custo extra
  • Sem mensalidade ou taxa de adesão
  • Todos os endpoints contabilizados igualmente
  • Dashboard com saldo de cotas em tempo real
  • PIX automático — cotas creditadas na hora, sem espera
  • Recarga via PIX em múltiplos de R$ 50,00
  • Aviso por e-mail com saldo baixo ou zerado
Criar conta grátis