Ontwikkelaars → Webhooks
NameOcean stuurt een ondertekend JSON-event naar uw HTTPS-endpoint wanneer er iets gebeurt in uw account, zodat uw code kan reageren in plaats van te pollen.
Via Dashboard → Webhooks, met de API, of door het uw AI te vragen via MCP (create_webhook). Kies eventtypes, groepen zoals dns.*, of alle events. Het antwoord bevat het ondertekeningsgeheim (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"]}'
De URL moet https zijn op een openbare server. Antwoord binnen 10 seconden met een willekeurige 2xx; voer trage taken uit na het antwoorden.
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"}
}
}
Het event-id blijft hetzelfde wanneer een aflevering opnieuw wordt geprobeerd of opnieuw wordt verzonden: gebruik het om events over te slaan die u al hebt verwerkt. Events kunnen in een andere volgorde binnenkomen.
t is de Unix-tijd van het verzoek, v1 de hexadecimale HMAC-SHA256 van t, een punt en de onbewerkte body, met uw geheime sleutel als sleutel. Bereken deze over de onbewerkte bytes, vóórdat u de JSON parseert, vergelijk in constante tijd en weiger tijdstempels die ouder zijn dan vijf minuten.
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))
}
Een aflevering die geen antwoord, een time-out, een 5xx, 408 of 429 krijgt, wordt opnieuw geprobeerd na 1m, 5m, 30m, 2h, 5h, 10h, 10h: 8 pogingen verspreid over ongeveer een dag. Elke andere 4xx mislukt meteen. Nadat 5 afleveringen op rij definitief zijn mislukt, wordt het endpoint uitgeschakeld en ontvangt u een e-mail; schakel het weer in via het dashboard of met PATCH active: true. Elke aflevering, met de statuscode en het begin van uw antwoord, wordt weergegeven in het dashboard en op GET /api/v1/webhooks/{id}/deliveries, waar u er een opnieuw kunt verzenden.
| domain.registered | Er is een domein geregistreerd in uw account. |
| domain.renewed | De vervaldatum van een domein is verschoven (verlenging). |
| domain.expiring | Een domein verloopt over 30, 7 of 1 dag(en). |
| domain.expired | Een domein is gisteren verlopen. |
| domain.nameservers.updated | De nameservers van een domein zijn gewijzigd. |
| domain.transfer.started | Er is een inkomende of uitgaande verhuizing aangevraagd bij de registry. |
| domain.transfer.completed | Een verhuizing is voltooid. |
| domain.transfer.failed | Een verhuizing is afgewezen of geannuleerd. |
| dns.zone.created | Er is een DNS-zone aangemaakt. |
| dns.zone.deleted | Er is een DNS-zone verwijderd. |
| dns.record.created | Er is een DNS-record toegevoegd. |
| dns.record.updated | Er is een DNS-record gewijzigd. |
| dns.record.deleted | Er is een DNS-record verwijderd. |
| ssl.issued | Er is voor het eerst een certificaat uitgegeven. |
| ssl.renewed | Er is een certificaat verlengd. |
| ssl.expiring | Een certificaat verloopt over 7 dagen en is nog niet verlengd. |
| email.mailbox.created | Er is een mailbox toegevoegd aan een van uw maildomeinen. |
| email.mailbox.deleted | Een mailbox en de bijbehorende e-mail zijn verwijderd. |
| email.forwarding.enabled | E-mail doorsturen is ingeschakeld voor een domein. |
| email.forwarding.disabled | E-mail doorsturen is uitgeschakeld voor een domein, door u of omdat het domein niet langer in aanmerking kwam (de reden staat in de gebeurtenis). |
| webhook.test | Wordt verzonden wanneer u op Test verzenden klikt; negeert het gebeurtenisfilter van het endpoint. |
data bevat het domein of de zone en het object: het record (met previous bij updates), de vervaldatum, de nameservers (met previous). De exacte velden van elk object zijn die van de REST API.
Inkomende e-mail kan ook naar een URL worden gepost: stel dit per adres in via E-mail doorsturen. Die posts gebruiken dezelfde headers en handtekening, met X-NameOcean-Event: email.received.