API de DNS

Gerencie zonas e registros do DNS autoritativo do Ravi Monitor por integração externa e consulte as estatísticas do DNS recursivo. É a mesma API usada para publicar registros automaticamente a partir de ERPs e painéis do provedor.

Visão geral

A área dns da API pública permite criar e excluir zonas (domínios), criar, pesquisar e excluir registros (subdomínios) do DNS Autoritativo, além de ler as estatísticas do DNS recursivo do servidor. O caso de uso típico é o sistema de gestão do provedor criar zonas e registros sozinho, sem que ninguém precise abrir a tela do Ravi.

A criação de registros por API aceita o parâmetro priority (para registros MX) e o modo lote com defer_reload + reload_nsd.

Pré-requisitos

  • Chave de API com a permissão Acesso a DNS marcada. Chaves são criadas em Configurações, aba Integrações, card Gerenciamento de API (somente a conta Master gerencia chaves Somente Master). Veja Criar uma chave de API.
  • Ambiente DNS do Ravi instalado e ativo (área DNS do menu). A operação recursive retorna a última estatística coletada do DNS recursivo (é preciso que ele já tenha coletado dados ao menos uma vez; o estado atual do serviço vem no bloco service_status); as operações de autoritativo exigem o servidor autoritativo gerenciado pelo Ravi.
  • Sem a permissão, o gateway responde HTTP 403 com {"status":"error","message":"Access denied for dns"}. Token inválido responde HTTP 401.

Formato das chamadas e das respostas

Todas as operações usam o endpoint único da API, por GET ou POST:

URL base
https://SEU-SERVIDOR/api/api.php?token=CHAVE&action=dns&operation=OPERACAO&...

O módulo DNS responde JSON direto, sem envelope: sucesso vem como {"msg":"ok"} (nas mutações) ou como o objeto pedido (ex.: {"authoritative":[...]}). Os erros de negócio vêm com HTTP 200 e o texto em inglês no campo msg.

Não confie apenas no código HTTP: neste módulo, qualquer resposta cujo msg seja diferente de "ok" deve ser tratada como erro. Apenas os erros do gateway (token, permissão, action) usam códigos HTTP 400/401/403.

Parâmetros comuns

ParâmetroAlias aceitoUso
operation-Obrigatório em toda chamada.
domaindomZona alvo (ex.: provedor.com.br).
subdomainsubdomNome do registro (ex.: www, @, mail).
typetipoTipo do registro: A, AAAA, CNAME, MX, NS, PTR, TXT (SRV é aceito se o valor de host incluir prioridade, peso e porta).
host-Valor/destino do registro (IP, hostname ou texto TXT).
comment-Comentário livre gravado no registro (opcional).
adicionalalt_domainSomente para PTR: domínio alternativo (opcional; sem espaços nem caracteres especiais).
priorityprioridadePrioridade numérica para registros MX (opcional).
defer_reload-1 = não recarrega o servidor autoritativo nesta chamada (modo lote; veja reload_nsd).

Comportamento automático

  • Toda mutação (criar/excluir zona ou registro) sem defer_reload regenera e assina as zonas e recarrega o servidor autoritativo (NSD) de forma síncrona: a resposta demora cerca de 1,5 a 2 segundos a mais. Não trate isso como lentidão anômala.
  • Ao criar uma zona por API, o sistema já cria automaticamente 3 registros A: ns1, ns2 e www, apontando para os IPs detectados do próprio servidor. Com 2 IPs, ns1 usa o primeiro e ns2 o segundo; com 1 IP, ambos usam o mesmo; sem IP detectável, ficam 0.0.0.0 para o operador ajustar.
  • Excluir uma zona também exclui os registros de DNS reverso interligados a ela.
  • As estatísticas de recursive refletem o último ciclo de coleta do módulo DNS, não um instantâneo em tempo real absoluto.

Operações

O módulo aceita 8 operações. As de leitura funcionam bem por GET; para as mutações, prefira POST com HTTPS, porque a chave trafega na requisição.

GET /api/api.php?action=dns&operation=recursive

Retorna as estatísticas do DNS recursivo do servidor: status do serviço, métricas de consultas e cache, indicadores de segurança (DNSSEC) e o tamanho das listas de bloqueio ativas.

ParâmetroTipoObrigatórioDescrição
tokenstringSimChave de API com Acesso a DNS.

Blocos da resposta:

  • service_status: unbound_active (serviço realmente ativo) e unbound_enabled (recursivo ligado nas opções do Ravi).
  • current_metrics: consultas por segundo, tempo de resposta médio e mediano, taxa de acerto de cache (%), taxa de validação DNSSEC (%) e totais de consultas.
  • query_types: contagem por tipo (A, AAAA, PTR, CNAME, ANY).
  • security_metrics: validações DNSSEC, respostas bogus, consultas e respostas indesejadas.
  • network_metrics: consultas TCP e IPv6.
  • cache_metrics: tamanho do cache e fila de requisições.
  • blocklists: quantidade de entradas de cada lista de bloqueio ativa (só aparecem as categorias ligadas na tela do DNS; chaves possíveis: adware_malware, phishing, anatel, cryptomining, ads, adult, social, games_gambling, tracking_analytics, fake_news).
curl
curl -s "https://ravi.seuprovedor.com.br/api/api.php?token=SUA_CHAVE&action=dns&operation=recursive"
resposta (resumida)
{
  "recursive": {
    "service_status":  { "unbound_active": true, "unbound_enabled": true },
    "current_metrics": { "queries_per_second": 412.7, "cache_hit_ratio": 87.3, "dnssec_validation_ratio": 96.1, ... },
    "query_types":     { "A": 125034, "AAAA": 30211, "PTR": 812, "CNAME": 145, "ANY": 3 },
    "security_metrics":{ "dnssec_validated": 118220, "dnssec_bogus": 4, "unwanted_queries": 51, "unwanted_replies": 12 },
    "network_metrics": { "tcp_queries": 210, "ipv6_queries": 18754 },
    "cache_metrics":   { ... },
    "blocklists":      { "phishing": 41230, "anatel": 1287 }
  }
}

Erro: {"msg":"No DNS log data found"} quando nunca houve coleta de estatísticas.

GET /api/api.php?action=dns&operation=authoritative

Lista as zonas do DNS autoritativo com seus registros. Sem domain, retorna todas as zonas; com domain, apenas a zona informada.

ParâmetroTipoObrigatórioDescrição
tokenstringSimChave de API com Acesso a DNS.
domainstringNãoFiltra por uma zona específica.
curl
curl -s "https://ravi.seuprovedor.com.br/api/api.php?token=SUA_CHAVE&action=dns&operation=authoritative&domain=cliente.com.br"
resposta
{
  "authoritative": [
    {
      "id": 12,
      "domain": "cliente.com.br",
      "entries": [
        { "id": 301, "name": "ns1",  "value": "203.0.113.10", "type": "A",  "host": null, "priority": null, "alt_domain": null },
        { "id": 302, "name": "www",  "value": "203.0.113.20", "type": "A",  "host": null, "priority": null, "alt_domain": null },
        { "id": 303, "name": "@",    "value": "mail.cliente.com.br", "type": "MX", "host": null, "priority": 10, "alt_domain": null }
      ]
    }
  ]
}

Erro: {"msg":"No authoritative domains found"}.

Dois detalhes de compatibilidade: registros criados pela API 7.2 trazem o rótulo em name e o destino em value, mas registros antigos criados por versões anteriores da interface podem vir com a semântica trocada (value = rótulo, host = destino); verifique qual campo está preenchido. E uma zona sem registros retorna "entries":"null" como a string "null", não como o valor JSON null.

POST /api/api.php?action=dns&operation=add_domain

Cria uma zona no DNS autoritativo, já com os registros padrão ns1, ns2 e www (tipo A, apontando para os IPs do próprio servidor), e recarrega o servidor autoritativo.

ParâmetroTipoObrigatórioDescrição
tokenstringSimChave de API com Acesso a DNS.
domainstringSimZona a criar (ex.: cliente.com.br).
defer_reload1NãoPula a recarga do NSD nesta chamada (modo lote).
curl
curl -s -X POST "https://ravi.seuprovedor.com.br/api/api.php" \
  -d "token=SUA_CHAVE" -d "action=dns" \
  -d "operation=add_domain" -d "domain=cliente.com.br"
resposta
{"msg":"ok"}

Erros: Please provide a valid domain, Domain already exists.

POST /api/api.php?action=dns&operation=add_subdomain

Cria um registro dentro de uma zona existente. É permitido repetir nome+tipo com valores diferentes (ex.: @ NS ns1 e @ NS ns2, ou vários TXT); apenas a combinação exata nome+tipo+valor repetida é recusada.

ParâmetroTipoObrigatórioDescrição
tokenstringSimChave de API com Acesso a DNS.
domainstringSimZona onde o registro será criado.
subdomainstringSimNome do registro (www, @, mail...).
typestringSimA, AAAA, CNAME, MX, NS, PTR ou TXT (SRV é aceito se o valor de host incluir prioridade, peso e porta).
hoststringSimValor/destino do registro.
prioritynúmeroNãoPrioridade para registros MX.
commentstringNãoComentário livre gravado no registro.
adicionalstringNãoSomente PTR: publica o registro sob o domínio alternativo em vez da zona principal (aceita apenas letras, números, pontos e hífens).
defer_reload1NãoPula a recarga do NSD nesta chamada (modo lote).

Registros TXT: envie o texto puro em host, sem aspas. O sistema adiciona as aspas na zona e divide automaticamente valores com mais de 255 caracteres em blocos concatenados, conforme o padrão DNS. Chaves DKIM longas e registros SPF podem ser enviados inteiros em uma única chamada, sem tratamento prévio.

PTR com domínio alternativo: quando adicional é informado em um registro PTR, o registro passa a ser publicado sob o domínio alternativo em vez da zona principal. Exemplo: subdomain=host1 com adicional=reverso.exemplo.net cria o PTR como host1.reverso.exemplo.net (com subdomain=@, o nome publicado é o próprio domínio alternativo). O campo aceita apenas letras, números, pontos e hífens; qualquer outro caractere retorna o erro Alternative domain cannot contain spaces or special characters.

curl (registro MX)
curl -s -X POST "https://ravi.seuprovedor.com.br/api/api.php" \
  -d "token=SUA_CHAVE" -d "action=dns" -d "operation=add_subdomain" \
  -d "domain=cliente.com.br" -d "subdomain=@" -d "type=MX" \
  -d "host=mail.cliente.com.br" -d "priority=10"
curl (registro PTR com domínio alternativo)
curl -s -X POST "https://ravi.seuprovedor.com.br/api/api.php" \
  -d "token=SUA_CHAVE" -d "action=dns" -d "operation=add_subdomain" \
  -d "domain=exemplo.com" -d "subdomain=host1" -d "type=PTR" \
  -d "host=192.168.1.1" -d "adicional=reverso.exemplo.net"
resposta
{"msg":"ok"}

Erros: Please provide domain, subdomain, type and host, Domain not found, Entry already exists, Alternative domain cannot contain spaces or special characters (PTR com adicional inválido).

GET /api/api.php?action=dns&operation=search_subdomain

Verifica se um registro existe na zona. Útil antes de criar ou excluir, e para conferir o resultado de um lote.

ParâmetroTipoObrigatórioDescrição
tokenstringSimChave de API com Acesso a DNS.
domainstringSimZona onde procurar.
subdomainstringSimNome do registro.
typestringSimTipo do registro.
hoststringNãoSe informado, a busca passa a ser exata por nome+tipo+valor (útil quando há vários registros de mesmo nome e tipo).
curl
curl -s "https://ravi.seuprovedor.com.br/api/api.php?token=SUA_CHAVE&action=dns&operation=search_subdomain&domain=cliente.com.br&subdomain=www&type=A"
resposta
{"msg":"true"}

{"msg":"true"} = o registro existe; {"msg":"false"} = não existe. Erro: Domain not found.

DEL /api/api.php?action=dns&operation=delete_subdomain

Exclui um registro da zona. A busca é feita por nome+tipo, sem considerar o valor.

Se existem vários registros com o mesmo nome e tipo (ex.: dois NS, vários TXT), a exclusão remove o primeiro que casar e não é possível escolher qual. Remova um por chamada e confira o resultado com authoritative antes de repetir.

ParâmetroTipoObrigatórioDescrição
tokenstringSimChave de API com Acesso a DNS.
domainstringSimZona do registro.
subdomainstringSimNome do registro a excluir.
typestringSimTipo do registro a excluir.
defer_reload1NãoPula a recarga do NSD nesta chamada (modo lote).
curl
curl -s -X POST "https://ravi.seuprovedor.com.br/api/api.php" \
  -d "token=SUA_CHAVE" -d "action=dns" -d "operation=delete_subdomain" \
  -d "domain=cliente.com.br" -d "subdomain=www" -d "type=A"
resposta
{"msg":"ok"}

Erros: Subdomain not found, Domain not found.

DEL /api/api.php?action=dns&operation=delete_domain

Exclui uma zona inteira do DNS autoritativo.

A exclusão é irreversível e remove a zona, todos os seus registros e também os registros de DNS reverso interligados a ela. Confirme a zona antes de chamar.

ParâmetroTipoObrigatórioDescrição
tokenstringSimChave de API com Acesso a DNS.
domainstringSimZona a excluir.
defer_reload1NãoPula a recarga do NSD nesta chamada (modo lote; veja reload_nsd). A exclusão de zona dispara a mesma recarga automática das demais mutações e respeita o parâmetro da mesma forma.
curl
curl -s -X POST "https://ravi.seuprovedor.com.br/api/api.php" \
  -d "token=SUA_CHAVE" -d "action=dns" \
  -d "operation=delete_domain" -d "domain=cliente.com.br"
resposta
{"msg":"ok"}

Erro: Domain not found.

POST /api/api.php?action=dns&operation=reload_nsd

Recarrega o servidor autoritativo sob demanda. É o par do defer_reload: ao criar ou alterar muitos registros, envie defer_reload=1 em cada mutação (pulando a recarga individual) e chame reload_nsd uma única vez no fim. O resultado é 1 recarga em vez de N, e o lote fica muito mais rápido.

ParâmetroTipoObrigatórioDescrição
tokenstringSimChave de API com Acesso a DNS.

A chamada espera o serviço do Ravi processar a recarga, por até 15 segundos.

curl
curl -s -X POST "https://ravi.seuprovedor.com.br/api/api.php" \
  -d "token=SUA_CHAVE" -d "action=dns" -d "operation=reload_nsd"
resposta
{"msg":"ok","reload_confirmed":true,"waited_ms":1800}

Se a espera estourar os 15 segundos, a resposta vem como {"msg":"ok_reload_timeout","reload_confirmed":false,...}: a recarga ainda pode completar logo em seguida; confirme com dig e, se preciso, repita a chamada.


Exemplos práticos

Criar uma zona e um registro MX

O fluxo mais comum de integração: criar a zona do cliente e publicar um registro. O mesmo padrão vale para A, AAAA, CNAME, TXT e os demais tipos.

# 1) criar a zona (ns1/ns2/www são criados automaticamente)
curl -s -X POST "https://ravi.seuprovedor.com.br/api/api.php" \
  -d "token=SUA_CHAVE" -d "action=dns" \
  -d "operation=add_domain" -d "domain=cliente.com.br"

# 2) criar o registro MX
curl -s -X POST "https://ravi.seuprovedor.com.br/api/api.php" \
  -d "token=SUA_CHAVE" -d "action=dns" -d "operation=add_subdomain" \
  -d "domain=cliente.com.br" -d "subdomain=@" -d "type=MX" \
  -d "host=mail.cliente.com.br" -d "priority=10"

# 3) conferir
curl -s "https://ravi.seuprovedor.com.br/api/api.php?token=SUA_CHAVE&action=dns&operation=search_subdomain&domain=cliente.com.br&subdomain=@&type=MX&host=mail.cliente.com.br"
<?php
$base  = 'https://ravi.seuprovedor.com.br/api/api.php';
$token = 'SUA_CHAVE';

function dnsApi($params) {
    global $base, $token;
    $params += ['token' => $token, 'action' => 'dns'];
    $ch = curl_init($base);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($params),
        CURLOPT_RETURNTRANSFER => true,
    ]);
    $resp = json_decode(curl_exec($ch), true);
    curl_close($ch);
    // neste módulo, msg != "ok" significa erro (mesmo com HTTP 200)
    if (isset($resp['msg']) && strpos($resp['msg'], 'ok') !== 0
        && !in_array($resp['msg'], ['true', 'false'], true)) {
        throw new Exception('API DNS: ' . $resp['msg']);
    }
    return $resp;
}

dnsApi(['operation' => 'add_domain', 'domain' => 'cliente.com.br']);
dnsApi([
    'operation' => 'add_subdomain',
    'domain'    => 'cliente.com.br',
    'subdomain' => '@',
    'type'      => 'MX',
    'host'      => 'mail.cliente.com.br',
    'priority'  => 10,
]);
import requests

BASE  = "https://ravi.seuprovedor.com.br/api/api.php"
TOKEN = "SUA_CHAVE"

def dns_api(**params):
    params.update(token=TOKEN, action="dns")
    resp = requests.post(BASE, data=params, timeout=30).json()
    # neste módulo, msg != "ok" significa erro (mesmo com HTTP 200)
    msg = resp.get("msg", "ok")
    if not msg.startswith("ok") and msg not in ("true", "false"):
        raise RuntimeError(f"API DNS: {msg}")
    return resp

dns_api(operation="add_domain", domain="cliente.com.br")
dns_api(operation="add_subdomain", domain="cliente.com.br",
        subdomain="@", type="MX",
        host="mail.cliente.com.br", priority=10)

Lote de registros com uma recarga só

Cada mutação recarrega o servidor autoritativo e custa 1,5 a 2 segundos. Para publicar vários registros de uma vez (ex.: SPF, DKIM e MX de um domínio de e-mail), use defer_reload=1 em cada chamada e feche o lote com reload_nsd.

curl
# mutações sem recarga individual
curl -s -X POST "https://ravi.seuprovedor.com.br/api/api.php" \
  -d "token=SUA_CHAVE" -d "action=dns" -d "operation=add_subdomain" \
  -d "domain=cliente.com.br" -d "subdomain=@" -d "type=TXT" \
  -d "host=v=spf1 mx -all" -d "defer_reload=1"

curl -s -X POST "https://ravi.seuprovedor.com.br/api/api.php" \
  -d "token=SUA_CHAVE" -d "action=dns" -d "operation=add_subdomain" \
  -d "domain=cliente.com.br" -d "subdomain=mail" -d "type=A" \
  -d "host=203.0.113.25" -d "defer_reload=1"

# uma recarga só, no fim do lote
curl -s -X POST "https://ravi.seuprovedor.com.br/api/api.php" \
  -d "token=SUA_CHAVE" -d "action=dns" -d "operation=reload_nsd"

Se você usar defer_reload=1 e esquecer de chamar reload_nsd no fim, as mudanças ficam gravadas mas não entram em vigor no DNS até a próxima recarga. Se o dig ainda responde o valor antigo depois de um lote, esse costuma ser o motivo.

Migrando do webservice antigo

Integrações que usavam os endpoints antigos de /webservice/ (autenticação por token do sistema + usuário e senha na URL) deixaram de funcionar na 7.2 e devem migrar para /api/api.php com chave de API. Correspondência das chamadas:

Chamada legadaSubstituto na API atual
webservice/dns.php?acao=recursivoaction=dns&operation=recursive
...acao=autoritativooperation=authoritative
...acao=add_domoperation=add_domain
...acao=add_subdomoperation=add_subdomain
...acao=pesquisar_subdomoperation=search_subdomain
...acao=delete_subdomoperation=delete_subdomain
...acao=delete_domoperation=delete_domain

Além de voltar a funcionar, a migração troca usuário e senha em texto na URL por uma chave revogável com permissão restrita à área de DNS.

Solução de problemas

SintomaCausa provável
HTTP 403 Access denied for dnsA chave existe, mas a permissão Acesso a DNS não está marcada. A conta Master pode ajustar a chave em Configurações, aba Integrações.
{"msg":"ok"}, mas o dig ainda responde o valor antigoRecarga em andamento (ela é síncrona, mas há propagação e cache), ou uso de defer_reload=1 sem chamar reload_nsd no fim do lote.
reload_nsd devolve ok_reload_timeoutO serviço do Ravi estava ocupado e a confirmação passou de 15 segundos. A recarga costuma completar em seguida; verifique com dig e repita se preciso.
Registro criado não aparece como esperado no authoritativeVerifique os campos name e value: registros antigos criados pela interface de versões anteriores podem vir com a semântica trocada.
{"msg":"No DNS log data found"} no recursiveO DNS recursivo nunca coletou estatísticas neste servidor; confirme que o recursivo está ativo na área DNS.

Boas práticas: use HTTPS e POST (a chave trafega na requisição); crie uma chave exclusiva para a integração de DNS, só com Acesso a DNS marcado; em lotes, sempre defer_reload=1 + reload_nsd final.