Pular para o conteúdo

Visão geral da API HTTP

Todo DTVSOL Super Router responde a uma API HTTP. Ela é servida pelo daemon do roteador, dtvsold, e é o que a CLI dtvsol, o monitor de OLT e o seu sistema de cobrança usam para ler e alterar o roteador. Esta página cobre o que todos os endpoints têm em comum. As páginas seguintes cobrem uma área cada.

Página Cobre
Clientes Clientes por MAC, seus planos, suspensão e datas de término
Serviços Serviços de assinante (ONT, VLAN, endereço e velocidade em uma só chamada)
Redes Redes atendidas, DHCP, pools IPv6, delegação de prefixo, DNS
VLANs, endereços IP, rotas Interfaces VLAN, endereços, rotas estáticas, pools de NAT
Planos Planos de velocidade
OLT Operações de OLT e o registro de OLTs
CGNAT e anti-spoofing NAT de nível de operadora e vinculação IP/MAC/VLAN
Proteção Lista de permitidos, fail2ban, redirecionamentos de porta, visão do firewall, Option 82, agente SNMP
Configuração de rede As portas, bonds, VLANs e endereços do próprio roteador, com rollback em 120 s
Alarmes e saúde O registro de alarmes e as leituras de cada área
Sistema Status, doctor, alertas, backup, versões de configuração, gráficos, licença
API compatível com MikroTik O listener RouterOS-API para sistemas de cobrança (TCP 8728)
http://ROUTER-IP:8880

A API escuta no endereço e na porta definidos na configuração do roteador (listen_ip e listen_port). A porta padrão é 8880. O dtvsold fala HTTP simples. Se você precisa de TLS, coloque a API atrás de um proxy reverso ou de uma VPN.

A porta da API fica atrás da lista de permitidos do roteador. Só as redes dessa lista podem se conectar a ela (e ao monitor de OLT na porta 8881). Gerencie a lista com dtvsol protect, /protect ou em Settings → Protection no monitor. Enquanto a lista estiver vazia, as duas portas ficam abertas para todos, então adicione suas redes de gerência antes de o roteador entrar em produção. Mantenha a lista o menor possível.

Toda requisição precisa da chave de API do roteador. A chave é api_key na configuração do roteador. Envie-a no cabeçalho X-API-Key:

Janela do terminal
curl -s -H "X-API-Key: YOUR_API_KEY" http://ROUTER-IP:8880/status

Somente quando um cliente não consegue definir cabeçalhos, envie-a como parâmetro de consulta:

Janela do terminal
curl -s "http://ROUTER-IP:8880/status?api_key=YOUR_API_KEY"

Prefira o cabeçalho. URLs acabam em logs e no histórico do shell. O roteador compara a chave em tempo constante. Um roteador sem chave configurada recusa todas as requisições.

Uma requisição sem chave válida recebe:

{
"error": "Unauthorized. Provide X-API-Key header or ?api_key= parameter."
}

com status 401. O roteador registra cada tentativa falha, com o endereço de quem chamou, no seu log de autenticação, mascarando qualquer valor pass, password ou api_key na URL. O fail2ban monitora esse log, então falhas repetidas banem quem chamou (veja fail2ban).

  • Caminhos. O primeiro segmento do caminho é o recurso e o segundo é o seu parâmetro: /clients/AA:BB:CC:DD:EE:FF, /olts/olt-1, /services/svc_1a2b3c/suspend. Barras no final são ignoradas. Codifique os parâmetros do caminho para URL quando necessário.
  • Parâmetros de consulta são usados para filtros em GET (/clients?network=10.110.0.0/21).
  • Corpos de requisição são objetos JSON. Envie-os com Content-Type: application/json. Um corpo que não seja um objeto JSON é tratado como vazio. O maior corpo que o roteador lê é de 4 MiB; um maior recebe 413.
  • Métodos. Leituras são GET. Alterações são POST (e PUT onde a página indicar) ou DELETE. Alguns endpoints DELETE aceitam um corpo JSON. Cada página lista o método de todos os endpoints.
  • Credenciais da OLT nunca vão em uma URL. POST /olt/{op} recusa qualquer outro método (veja OLT).

Os endpoints que alteram o roteador são marcados em cada página com um quadro Altera o roteador.

Toda resposta é JSON, formatado com indentação de quatro espaços e seguido de uma quebra de linha. Os gráficos (PNG) e o download do backup (um arquivo compactado) são as únicas exceções.

O roteador escreve JSON do seu próprio jeito, sempre igual. Qualquer parser JSON o lê sem problemas, mas vale conhecer três hábitos:

  • Barras dentro de strings são escapadas: "10.110.0.0\/21" é a string 10.110.0.0/21.
  • Um objeto vazio pode voltar como []. Trate um [] vazio e um {} da mesma forma.
  • Um float com valor inteiro é escrito como inteiro (8, não 8.0).

A maioria das respostas que alteram algo traz ok, e muitas trazem code e message:

{
"ok": true,
"code": 201,
"message": "Client added successfully",
"client": { "mac": "AA:BB:CC:DD:EE:FF", "ip": "10.110.0.2" }
}

Uma resposta de erro tem um texto error. Normalmente também tem "ok": false e o code repetido no corpo:

{
"ok": false,
"code": 409,
"error": "MAC AA:BB:CC:DD:EE:FF already registered"
}
Status Significado
200 Sucesso (leituras e a maioria das alterações)
201 Criado (por exemplo um cliente, um serviço, uma versão de configuração salva)
400 Um parâmetro está faltando ou é inválido. O texto error diz qual.
401 Sem chave de API, ou com a chave errada
404 O cliente, serviço, OLT, plano ou operação não existe
405 O método não é permitido nesse caminho. O texto error normalmente lista as formas válidas.
409 Conflito: o item já existe, ou (na configuração de rede) a sua version está desatualizada
413 Corpo da requisição maior que 4 MiB
500 O roteador não conseguiu concluir a alteração (um comando falhou, um arquivo não pôde ser gravado). O texto error diz o que falhou, muitas vezes com um detail.

Quando uma resposta 5xx é causada por um documento de configuração que não pode ser lido, a resposta também lista os arquivos danificados em broken_data_files. O dtvsol doctor relata o mesmo problema.

Um caminho que não é um recurso da API recebe uma resposta 200 com o resumo de uso embutido da API, e não um 404. Se você vir uma resposta com "api": "DTVSOL DHCP API v1.0", confira se escreveu o recurso corretamente.

Para clientes que só conseguem fazer requisições GET simples (um navegador, um sistema de cobrança com callbacks por URL), a maioria das operações também existe como ações. O nome da ação e todos os argumentos vão na query string:

Janela do terminal
curl -s -H "X-API-Key: YOUR_API_KEY" \
"http://ROUTER-IP:8880/api?action=get&mac=AA:BB:CC:DD:EE:FF"

Cada ação chama o mesmo código do seu endpoint REST, então o efeito é idêntico. Prefira REST em integrações novas: ele mantém as alterações fora de requisições GET e as credenciais fora das URLs. Para a OLT especialmente, use POST /olt/{op}.

As ações que alteram o roteador funcionam com GET. A única exceção é config-save, que precisa ser POST. Uma ação desconhecida recebe 400 com "error": "Unknown action" e uma lista curta de ações.

Ação Parâmetros de consulta Equivale a
action=list [network] GET /clients
action=search q GET /clients?q=
action=get mac GET /clients/{mac}
action=add mac, ip, [hostname], [comment], [ipv6] POST /clients
action=delete mac DELETE /clients/{mac}
action=active, action=connected [state] GET /clients/active
action=clients6 [iface], [routers=1] GET /clients6
action=ip-info [network] GET /ips
action=set-plan mac, plan POST /plan
action=suspend, action=resume mac POST /suspend, POST /resume
action=set-expires mac, expires POST /expires
action=status GET /status
action=networks GET /networks
action=reload POST /dhcp/reload
action=interfaces GET /interfaces
action=iface-list GET /iface
action=add-net, action=remove-net iface, [label] POST /net, DELETE /net
action=net6-add, action=net6-del iface POST /net6, DELETE /net6
action=net6-pool iface, [start], [end] POST /net6/pool
action=net6-lease valid, [preferred] POST /net6/lease
action=net6-dns servers, [domain], [clear_domain=1] somente os resolvedores DHCPv6 (dns-set define os dois)
action=pd-list GET /pd
action=pd-add iface, [size] POST /pd
action=pd-resize iface, size POST /pd/resize
action=pd-del iface DELETE /pd
action=pd-assign, action=pd-unassign mac, [prefix] fixação de prefixo delegado
action=pd-sync [dry=1] reconcilia agora as rotas dos prefixos delegados
action=dns-list GET /dns
action=dns-set [v4], [v6], [domain], [iface], [apply=all] POST /dns, POST /dns/{iface}
action=dns-del iface ou global=v4|v6|domain|all DELETE /dns/{iface}, DELETE /dns
action=vlan-list GET /vlans
action=vlan-add parent, vlan_id, [ip], [ipv6], [label], [protocol], [force=1], [serve=0] POST /vlans
action=vlan-disable name, [reason] POST /vlans/disable
action=vlan-enable name POST /vlans/enable
action=vlan-del name DELETE /vlans
action=ip-add, action=ip-del iface, ip, [force=1] POST /ip, DELETE /ip
action=route-list, action=route-add, action=route-del prefix, [via], [dev], [comment] /routes
action=nat-list, action=nat-add, action=nat-del iface, pool_start, pool_end, [exempt], [comment] /nat
action=plan-list GET /plans
action=plan-add name, down_mbps, up_mbps, [comment] POST /plans
action=plan-del name DELETE /plans/{name}
action=service-list [state], [olt], [q], [fast=1] GET /services
action=service-get id GET /services/{id}
action=service-add como em POST /services, na query POST /services
action=service-set id, campos como em POST /services/{id} POST /services/{id}
action=service-suspend, action=service-resume id POST /services/{id}/suspend, /resume
action=service-del id, [keep_ont=1] DELETE /services/{id}
action=service-unregistered [olt] GET /services/unregistered
action=service-expiry aplica agora as datas de término dos serviços (o timer do roteador faz isso sozinho)
action=olts-list GET /olts
action=olts-add, action=olts-set name, campos da OLT POST /olts, POST /olts/{name}
action=olts-del name DELETE /olts/{name}
action=olt-sync [olt], [dry_run=1] POST /olt/sync
action=olt-backup [olt] POST /olt/backup
action=olt-backups [olt], [n] GET /olt/backups
action=olt-diff [olt], [rev], [to] GET /olt/diff
action=olt-info, action=olt-autofind, … (olt-<op>) olt=<name> e os argumentos da operação POST /olt/{op}
action=protect-list GET /protect
action=protect-add network, [comment] POST /protect
action=protect-delete network DELETE /protect
action=firewall [network] GET /firewall
action=firewall-full GET /firewall/full
action=fail2ban, action=fail2ban-status GET /fail2ban
action=fail2ban-unban ip POST /fail2ban
action=pf-list, action=pf-add, action=pf-del como em /pf, na query /pf
action=option82 GET /option82
action=snmp-status, action=snmp-set como em /snmp, na query /snmp
action=cgnat-status, action=cgnat-set como em /cgnat, na query /cgnat
action=cgnat-lookup public_ip, port GET /cgnat/lookup
action=antispoof-status GET /antispoof
action=antispoof-set enabled, [mode], [log], [exempt] POST /antispoof
action=antispoof-iface iface, mode POST /antispoof/{iface}
action=antispoof-log [since], [limit] GET /antispoof/log
action=antispoof-sync POST /antispoof/sync
action=doctor [olt=1] GET /doctor
action=alerts GET /alerts
action=config-status, action=config-versions, action=config-diff, action=config-show veja Sistema versões de configuração
action=config-save (POST) [comment] salva a configuração em execução como uma nova versão

As operações de OLT disponíveis como olt-<op> são: action=olt-info, action=olt-autofind, action=olt-onus, action=olt-vlans, action=olt-serviceports, action=olt-profiles, action=olt-config, action=olt-run, action=olt-exec, action=olt-vlan-add, action=olt-vlan-del, action=olt-port-vlan, action=olt-profile-add, action=olt-profile-del, action=olt-ont-add, action=olt-ont-del, action=olt-ont-reboot, action=olt-ont-desc, action=olt-ont-optical, action=olt-ntp, action=olt-sysname, action=olt-save, action=olt-plan-sync e action=olt-init. Qualquer outra operação da lista de GET /olt é aceita da mesma forma.

As áreas mais novas não têm forma de ação: o registro de alarmes e as leituras de saúde, a configuração de rede do roteador, os gráficos, o download do backup e a restauração.

O repositório do site tem tools/api-inventory.mjs. Ele lê o código-fonte do dtvsold e lista todos os recursos, endpoints e ações que a API roteia. Com --check, lista tudo o que estas páginas não documentam. Ele roda a cada release.

Este site foi escrito com a ajuda de IA e revisado pela nossa equipe.