Dezvoltatori → Webhooks
NameOcean trimite un eveniment JSON semnat către endpointul dumneavoastră HTTPS atunci când se întâmplă ceva în contul dumneavoastră, astfel încât codul dumneavoastră să poată reacționa fără interogări periodice.
În Panou de control → Webhookuri, prin API sau cerându-i asistentului AI prin MCP (create_webhook). Alegeți tipuri de evenimente, grupuri precum dns.* sau toate evenimentele. Răspunsul include secretul de semnare (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"]}'
URL-ul trebuie să fie https pe un server public. Răspundeți cu orice cod 2xx în maximum 10 secunde; efectuați operațiunile lente după ce ați răspuns.
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"}
}
}
ID-ul evenimentului rămâne același atunci când o livrare este reîncercată sau retrimisă: folosiți-l pentru a omite evenimentele pe care le-ați procesat deja. Evenimentele pot sosi în altă ordine.
t este timpul Unix al cererii, iar v1 este HMAC-SHA256 în format hex al lui t, urmat de un punct și de corpul brut, calculat cu secretul dumneavoastră drept cheie. Calculați-l pe baza octeților bruți, înainte de parsarea JSON-ului, comparați în timp constant și respingeți marcajele de timp mai vechi de cinci minute.
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))
}
O livrare care nu primește niciun răspuns, expiră sau primește un cod 5xx, 408 ori 429 este reîncercată după 1m, 5m, 30m, 2h, 5h, 10h, 10h: 8 încercări pe parcursul a aproximativ o zi. Orice alt cod 4xx eșuează imediat. După 5 livrări consecutive eșuate definitiv, endpointul este dezactivat și primiți un e-mail; îl puteți reactiva din panoul de control sau cu PATCH active: true. Fiecare livrare, cu codul de stare și începutul răspunsului dumneavoastră, apare în panoul de control și la GET /api/v1/webhooks/{id}/deliveries, de unde o puteți retrimite.
| domain.registered | Un domeniu a fost înregistrat în contul dumneavoastră. |
| domain.renewed | Data de expirare a unui domeniu a fost prelungită (reînnoire). |
| domain.expiring | Un domeniu expiră în 30, 7 sau 1 zile. |
| domain.expired | Un domeniu a expirat ieri. |
| domain.nameservers.updated | Serverele de nume ale unui domeniu s-au schimbat. |
| domain.transfer.started | A fost solicitat la registru un transfer de intrare sau de ieșire. |
| domain.transfer.completed | Un transfer s-a finalizat. |
| domain.transfer.failed | Un transfer a fost respins sau anulat. |
| dns.zone.created | A fost creată o zonă DNS. |
| dns.zone.deleted | A fost ștearsă o zonă DNS. |
| dns.record.created | A fost adăugată o înregistrare DNS. |
| dns.record.updated | O înregistrare DNS a fost modificată. |
| dns.record.deleted | A fost ștearsă o înregistrare DNS. |
| ssl.issued | Un certificat a fost emis pentru prima dată. |
| ssl.renewed | Un certificat a fost reînnoit. |
| ssl.expiring | Un certificat expiră în 7 zile și nu a fost încă reînnoit. |
| email.mailbox.created | A fost adăugată o căsuță de e-mail la unul dintre domeniile dumneavoastră de e-mail. |
| email.mailbox.deleted | O căsuță de e-mail și mesajele sale au fost șterse. |
| email.forwarding.enabled | Redirecționarea e-mailurilor a fost activată pentru un domeniu. |
| email.forwarding.disabled | Redirecționarea e-mailurilor a fost dezactivată pentru un domeniu, de către dumneavoastră sau pentru că domeniul nu mai îndeplinește condițiile (motivul este indicat în eveniment). |
| webhook.test | Trimis când apăsați Trimiteți test; ignoră filtrul de evenimente al endpointului. |
data conține domeniul sau zona și obiectul: înregistrarea (cu previous la actualizări), data expirării, serverele de nume (cu previous). Câmpurile exacte ale fiecărui obiect sunt cele din API-ul REST.
E-mailurile primite pot fi trimise și ele către un URL: setați-l pentru fiecare adresă în Redirecționare e-mail. Aceste POST-uri folosesc aceleași antete și aceeași semnătură, cu X-NameOcean-Event: email.received.