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
15 Endpoints
4 Verbos HTTP
R$1 / 1.000 req
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.

Token cacheado

O acesso à API privada usa token com cache de 23h — zero overhead de autenticação por requisição.

CPF único por conta

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

Billing transparente

Pagamento mensal via PIX com QR Code no último dia do mês. Histórico de pagamentos disponível na dashboard.

documentação

Referência completa da API

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

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. Em /questions, máximo de 100
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 100 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
pageintegerPágina (padrão: 1)
sizeintegerItens por página — máximo 100 (padrão: 10)
bancastringBanca organizadora. Use /api/bancas para listar valores válidos
orgaostringÓrgão da prova. Use /api/orgaos para listar valores válidos
cargostringCargo da prova. Use /api/cargos para listar valores válidos
materiastringDisciplina/matéria. Use /api/materias para listar valores válidos
assuntostringAssunto específico da matéria. Use /api/assuntos para listar
anointegerAno 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",
      "orgao":    "TJ/SE",
      "banca":    "FGV",
      "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
    }
  ]
}
Exemplos de código
## cURL
curl -X GET \
  "https://qapi.otunac.com/api/questoes?banca=FGV&materia=Direito+Administrativo&page=1&size=20" \
  -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": 20},
    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: 20 });
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.

GET /api/provas Q-Api-Key
Query parameters
ParâmetroTipoReq.Descrição
pageintegerPágina (padrão: 1)
sizeintegerItens por página, máx. 100 (padrão: 10)
bancastringFiltrar por banca organizadora
orgaostringFiltrar por órgão
cargostringFiltrar por cargo
anointegerFiltrar 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.

GET /api/concursos Q-Api-Key
Query parameters
ParâmetroTipoReq.Descrição
pageintegerPágina (padrão: 1)
sizeintegerItens por página, máx. 100 (padrão: 10)
orgaostringFiltrar por órgão
bancastringFiltrar por banca organizadora
statusstringFiltrar por status (ver /concursos/status abaixo)
anointegerFiltrar por ano do concurso
cargostringFiltrar concursos que ofereçam este cargo
searchstringBusca 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":           "DATAPREV",
      "banca":           "FGV Conhecimento",
      "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,
      "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
bancastringBanca organizadora
orgaostringÓrgão da prova
cargostringCargo da prova
materiastringDisciplina/matéria
assuntostringAssunto específico da matéria
anointegerAno de realização da prova
sizeintegerQuantidade de questões — máximo 100 (padrão: 10)
Exemplo de request
GET https://qapi.otunac.com/api/simulados?banca=FGV&materia=Direito+Constitucional&size=20
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":  20    // 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. O parâmetro search realiza busca parcial case-insensitive.

Parâmetros comuns a todos os catálogos:   page (integer, padrão: 1)  ·  size (integer, padrão: 10)  ·  search (string — busca parcial no nome)
GET /api/bancas Q-Api-Key

Lista as bancas organizadoras. Use search para filtrar por nome.

GET https://qapi.otunac.com/api/bancas?page=1&size=10&search=fgv
Q-Api-Key: qb_SuaChaveAqui
{
  "bancas": ["FGV"],
  "total": 1, "page": 1, "pages": 1
}
GET /api/orgaos Q-Api-Key

Lista os órgãos. Use search para busca parcial.

GET https://qapi.otunac.com/api/orgaos?page=1&size=5&search=ces
Q-Api-Key: qb_SuaChaveAqui
{
  "orgaos": ["CESPE", "CESGRANRIO"],
  "total": 2, "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)
pageintegerPágina
sizeintegerItens por página
searchstringBusca 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
403ForbiddenChave de API suspensa por inadimplência
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 == 403:
    raise PermissionError("Chave suspensa — regularize o pagamento")
else:
    r.raise_for_status()
preços

Pague apenas pelo que usar

Sem mensalidade, sem taxa de adesão. A cobrança é calculada com base no total de requisições realizadas via sua API Key no mês. O pagamento é feito no último dia de cada mês via PIX.

R$1
a cada 1.000 requisições
  • Sem mensalidade ou taxa de adesão
  • Todos os endpoints contabilizados igualmente
  • Dashboard com custo do mês em tempo real
  • Histórico de pagamentos com confirmação
  • Chave suspensa automaticamente em caso de atraso
Criar conta grátis