Dezvoltatori → Webhooks

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.

Adăugați un endpoint

Î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
$ 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.

Ce primiți

POST https://example.com/hooks/nameocean
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.

Verificați semnătura

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.

X-NameOcean-Signature
t=1794300000,v1=hex(HMAC_SHA256(secret, "1794300000." + raw_body))
Python
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", ""))
Node.js
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);
}
Go
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))
}

Reîncercări și dezactivare

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.

Evenimente

domain.registeredUn domeniu a fost înregistrat în contul dumneavoastră.
domain.renewedData de expirare a unui domeniu a fost prelungită (reînnoire).
domain.expiringUn domeniu expiră în 30, 7 sau 1 zile.
domain.expiredUn domeniu a expirat ieri.
domain.nameservers.updatedServerele de nume ale unui domeniu s-au schimbat.
domain.transfer.startedA fost solicitat la registru un transfer de intrare sau de ieșire.
domain.transfer.completedUn transfer s-a finalizat.
domain.transfer.failedUn transfer a fost respins sau anulat.
dns.zone.createdA fost creată o zonă DNS.
dns.zone.deletedA fost ștearsă o zonă DNS.
dns.record.createdA fost adăugată o înregistrare DNS.
dns.record.updatedO înregistrare DNS a fost modificată.
dns.record.deletedA fost ștearsă o înregistrare DNS.
ssl.issuedUn certificat a fost emis pentru prima dată.
ssl.renewedUn certificat a fost reînnoit.
ssl.expiringUn certificat expiră în 7 zile și nu a fost încă reînnoit.
email.mailbox.createdA fost adăugată o căsuță de e-mail la unul dintre domeniile dumneavoastră de e-mail.
email.mailbox.deletedO căsuță de e-mail și mesajele sale au fost șterse.
email.forwarding.enabledRedirecționarea e-mailurilor a fost activată pentru un domeniu.
email.forwarding.disabledRedirecț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.testTrimis 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.

Bine de știut

  • NameOcean trimite doar către adrese publice, verificate din nou la fiecare livrare, și nu urmează niciodată redirecționări.
  • Dacă secretul este compromis, regenerați-l din panoul de control; evenimentele sunt semnate imediat cu cel nou.
  • Trimiteți test trimite imediat un eveniment webhook.test, indiferent de filtrul de evenimente al endpointului.