Sviluppatori → Webhooks
NameOcean invia un evento JSON firmato al Suo endpoint HTTPS quando succede qualcosa nel Suo account, così il Suo codice può reagire senza dover interrogare periodicamente l'API.
In Dashboard → Webhook, tramite l'API oppure chiedendolo alla Sua AI tramite MCP (create_webhook). Scelga i tipi di evento, gruppi come dns.* o tutti gli eventi. La risposta include il secret di firma (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"]}'
L'URL deve essere https su un server pubblico. Risponda con un qualsiasi 2xx entro 10 secondi; esegua le operazioni lente dopo aver risposto.
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"}
}
}
L'id dell'evento resta invariato quando una consegna viene ritentata o reinviata: lo usi per ignorare gli eventi già gestiti. Gli eventi possono arrivare in ordine diverso.
t è il timestamp Unix della richiesta, v1 l'HMAC-SHA256 esadecimale di t, un punto e il corpo grezzo, firmato con il Suo segreto. Lo calcoli sui byte grezzi, prima di effettuare il parsing del JSON, esegua il confronto in tempo costante e rifiuti i timestamp più vecchi di cinque minuti.
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))
}
Una consegna che non riceve risposta, va in timeout o riceve un 5xx, 408 o 429 viene ritentata dopo 1m, 5m, 30m, 2h, 5h, 10h, 10h: 8 tentativi nell'arco di circa un giorno. Qualsiasi altro 4xx fallisce subito. Dopo 5 consegne consecutive fallite definitivamente, l'endpoint viene disattivato e riceve un'email; può riattivarlo dalla dashboard o con PATCH active: true. Ogni consegna, con il codice di stato e l'inizio della Sua risposta, è elencata nella dashboard e in GET /api/v1/webhooks/{id}/deliveries, dove può reinviarla.
| domain.registered | Un dominio è stato registrato nel Suo account. |
| domain.renewed | La data di scadenza di un dominio è stata posticipata (rinnovo). |
| domain.expiring | Un dominio scade tra 30, 7 o 1 giorno. |
| domain.expired | Un dominio è scaduto ieri. |
| domain.nameservers.updated | I nameserver di un dominio sono cambiati. |
| domain.transfer.started | È stato richiesto un trasferimento in entrata o in uscita presso il registro. |
| domain.transfer.completed | Un trasferimento è stato completato. |
| domain.transfer.failed | Un trasferimento è stato rifiutato o annullato. |
| dns.zone.created | È stata creata una zona DNS. |
| dns.zone.deleted | È stata eliminata una zona DNS. |
| dns.record.created | È stato aggiunto un record DNS. |
| dns.record.updated | Un record DNS è stato modificato. |
| dns.record.deleted | È stato eliminato un record DNS. |
| ssl.issued | Un certificato è stato emesso per la prima volta. |
| ssl.renewed | Un certificato è stato rinnovato. |
| ssl.expiring | Un certificato scade tra 7 giorni e non è ancora stato rinnovato. |
| email.mailbox.created | È stata aggiunta una casella a uno dei Suoi domini di posta. |
| email.mailbox.deleted | Una casella e i relativi messaggi sono stati eliminati. |
| email.forwarding.enabled | L'inoltro email è stato attivato per un dominio. |
| email.forwarding.disabled | L'inoltro email è stato disattivato per un dominio, da Lei o perché il dominio non soddisfa più i requisiti (il motivo è indicato nell'evento). |
| webhook.test | Inviato quando preme Invia test; ignora il filtro eventi dell'endpoint. |
data contiene il dominio o la zona e l'oggetto: il record (con previous negli aggiornamenti), la data di scadenza, i nameserver (con previous). I campi esatti di ogni oggetto sono quelli della REST API.
Anche le email in arrivo possono essere inviate a un URL: lo imposti per ciascun indirizzo in Inoltro email. Questi invii usano gli stessi header e la stessa firma, con X-NameOcean-Event: email.received.