Programadores → Webhooks
A NameOcean envia um evento JSON assinado para o seu endpoint HTTPS quando algo acontece na sua conta, para que o seu código possa reagir em vez de consultar repetidamente.
Em Painel → Webhooks, com a API ou pedindo à sua IA via MCP (create_webhook). Escolha tipos de evento, grupos como dns.* ou todos os eventos. A resposta inclui o segredo de assinatura (whsec_…).
$ curl -X POST https://nameocean.net/api/v1/webhooks \ -H "Authorization: Bearer $NAMEOCEAN_API_KEY" -H "Content-Type: application/json" \ -d '{"url": "https://example.com/hooks/nameocean", "events": ["dns.*", "ssl.issued", "domain.expiring"]}'
A URL deve ser HTTPS num servidor público. Responda com qualquer 2xx em até 10 segundos; faça o trabalho demorado depois de responder.
Content-Type: application/json
X-NameOcean-Event: dns.record.created
X-NameOcean-Delivery: whd_7c1e0f9a2b3d4e5f6a7b8c9d
X-NameOcean-Signature: t=1794300000,v1=5f2b…
{
"id": "evt_3a9f1c2e4b5d6a7c8e9f0a1b",
"type": "dns.record.created",
"created": "2026-11-10T09:20:00+00:00",
"data": {
"zone": "example.com",
"record": {"id": 4211, "type": "A", "hostname": "www", "ip": "203.0.113.10", "ttl": "1h"}
}
}
O id do evento permanece o mesmo quando uma entrega é repetida ou reenviada: use-o para ignorar eventos que você já processou. Os eventos podem chegar fora de ordem.
t é o tempo Unix da requisição e v1 é o HMAC-SHA256 em hexadecimal de t, um ponto e o corpo bruto, usando o seu segredo como chave. Calcule-o sobre os bytes brutos, antes de analisar o JSON, compare em tempo constante e rejeite timestamps com mais de cinco minutos.
t=1794300000,v1=hex(HMAC_SHA256(secret, "1794300000." + raw_body))
import hashlib, hmac, time
def verify(secret: str, header: str, body: bytes, tolerance: int = 300) -> bool:
fields = dict(part.split("=", 1) for part in header.split(","))
ts = int(fields["t"])
if abs(time.time() - ts) > tolerance:
return False
expected = hmac.new(secret.encode(), f"{ts}.".encode() + body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, fields.get("v1", ""))
import crypto from "node:crypto";
export function verify(secret, header, rawBody, tolerance = 300) {
const fields = Object.fromEntries(header.split(",").map((p) => p.split("=", 2)));
const ts = Number(fields.t);
if (Math.abs(Date.now() / 1000 - ts) > tolerance) return false;
const expected = crypto.createHmac("sha256", secret).update(`${ts}.`).update(rawBody).digest("hex");
const got = Buffer.from(fields.v1 || "", "hex");
return got.length === 32 && crypto.timingSafeEqual(Buffer.from(expected, "hex"), got);
}
func Verify(secret, header string, body []byte) bool {
var ts int64
var v1 string
for _, part := range strings.Split(header, ",") {
k, v, _ := strings.Cut(part, "=")
switch k {
case "t":
ts, _ = strconv.ParseInt(v, 10, 64)
case "v1":
v1 = v
}
}
if d := time.Now().Unix() - ts; d > 300 || d < -300 {
return false
}
mac := hmac.New(sha256.New, []byte(secret))
fmt.Fprintf(mac, "%d.", ts)
mac.Write(body)
return hmac.Equal([]byte(hex.EncodeToString(mac.Sum(nil))), []byte(v1))
}
Uma entrega sem resposta, com timeout, 5xx, 408 ou 429 é repetida após 1m, 5m, 30m, 2h, 5h, 10h, 10h: 8 tentativas ao longo de cerca de um dia. Qualquer outro 4xx falha imediatamente. Após 5 entregas seguidas falharem definitivamente, o endpoint é desativado e você recebe um email; reative-o no painel ou com PATCH active: true. Todas as entregas, com o código de status e o início da sua resposta, são listadas no painel e em GET /api/v1/webhooks/{id}/deliveries, onde você pode reenviar uma delas.
| domain.registered | Um domínio foi registrado na sua conta. |
| domain.renewed | A data de expiração de um domínio foi adiada (renovação). |
| domain.expiring | Um domínio expira em 30, 7 ou 1 dia. |
| domain.expired | Um domínio expirou ontem. |
| domain.nameservers.updated | Os nameservers de um domínio foram alterados. |
| domain.transfer.started | Foi solicitada no registro uma transferência de entrada ou de saída. |
| domain.transfer.completed | Uma transferência foi concluída. |
| domain.transfer.failed | Uma transferência foi rejeitada ou cancelada. |
| dns.zone.created | Uma zona DNS foi criada. |
| dns.zone.deleted | Uma zona DNS foi excluída. |
| dns.record.created | Um registro DNS foi adicionado. |
| dns.record.updated | Um registro DNS foi alterado. |
| dns.record.deleted | Um registro DNS foi excluído. |
| ssl.issued | Um certificado foi emitido pela primeira vez. |
| ssl.renewed | Um certificado foi renovado. |
| ssl.expiring | Um certificado expira em 7 dias e ainda não foi renovado. |
| email.mailbox.created | Foi adicionada uma caixa de correio a um dos seus domínios de e-mail. |
| email.mailbox.deleted | Uma caixa de correio e as respetivas mensagens foram eliminadas. |
| email.forwarding.enabled | O reencaminhamento de e-mail foi ativado para um domínio. |
| email.forwarding.disabled | O reencaminhamento de e-mail foi desativado para um domínio, por si ou porque o domínio deixou de cumprir os requisitos (o motivo consta do evento). |
| webhook.test | Enviado quando você clica em Enviar teste; ignora o filtro de eventos do endpoint. |
data contém o domínio ou a zona e o objeto: o registro (com previous nas atualizações), a data de expiração, os nameservers (com previous). Os campos exatos de cada objeto são os da API REST.
Emails recebidos também podem ser enviados para uma URL: configure-a por endereço em Encaminhamento de email. Esses envios usam os mesmos cabeçalhos e assinatura, com X-NameOcean-Event: email.received.