Utviklere → Webhooks

Webhooks

NameOcean sender en signert JSON-hendelse til HTTPS-endepunktet ditt når noe skjer på kontoen din, slik at koden din kan reagere i stedet for å spørre gjentatte ganger.

Legg til et endepunkt

I Dashbord → Webhooks, med API-et, eller ved å be AI-en din via MCP (create_webhook). Velg hendelsestyper, grupper som dns.*, eller alle hendelser. Svaret inneholder signeringshemmeligheten (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-en må være https på en offentlig server. Svar med en hvilken som helst 2xx innen 10 sekunder; gjør tidkrevende arbeid etter at du har svart.

Hva du mottar

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"}
  }
}

Hendelses-ID-en forblir den samme når en levering forsøkes på nytt eller sendes igjen: bruk den til å hoppe over hendelser du allerede har håndtert. Hendelser kan komme i feil rekkefølge.

Verifiser signaturen

t er Unix-tiden for forespørselen, v1 er heksadesimal HMAC-SHA256 av t, et punktum og den rå meldingskroppen, nøklet med hemmeligheten din. Beregn den over de rå bytene før JSON-en parses, sammenlign i konstant tid, og avvis tidsstempler som er eldre enn fem minutter.

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))
}

Nye forsøk og deaktivering

En levering som ikke får svar, får tidsavbrudd, 5xx, 408 eller 429, forsøkes på nytt etter 1m, 5m, 30m, 2h, 5h, 10h, 10h: 8 forsøk over omtrent ett døgn. Alle andre 4xx feiler umiddelbart. Når 5 leveringer på rad har feilet endelig, deaktiveres endepunktet og du får en e-post; aktiver det igjen i dashbordet eller med PATCH active: true. Alle leveringer, med statuskode og starten av svaret ditt, vises i dashbordet og på GET /api/v1/webhooks/{id}/deliveries, der du kan sende en på nytt.

Hendelser

domain.registeredEt domene ble registrert på kontoen din.
domain.renewedUtløpsdatoen for et domene ble flyttet frem (fornyelse).
domain.expiringEt domene utløper om 30, 7 eller 1 dag.
domain.expiredEt domene utløp i går.
domain.nameservers.updatedNavneserverne for et domene ble endret.
domain.transfer.startedEn overføring inn eller ut ble forespurt hos registeret.
domain.transfer.completedEn overføring ble fullført.
domain.transfer.failedEn overføring ble avvist eller kansellert.
dns.zone.createdEn DNS-sone ble opprettet.
dns.zone.deletedEn DNS-sone ble slettet.
dns.record.createdEn DNS-post ble lagt til.
dns.record.updatedEn DNS-post ble endret.
dns.record.deletedEn DNS-post ble slettet.
ssl.issuedEt sertifikat ble utstedt for første gang.
ssl.renewedEt sertifikat ble fornyet.
ssl.expiringEt sertifikat utløper om 7 dager og er ikke fornyet ennå.
email.mailbox.createdEn postboks ble lagt til i et av e-postdomenene dine.
email.mailbox.deletedEn postboks og e-posten i den ble slettet.
email.forwarding.enabledVideresending av e-post ble slått på for et domene.
email.forwarding.disabledVideresending av e-post ble slått av for et domene, enten av deg eller fordi domenet ikke lenger oppfylte kravene (årsaken står i hendelsen).
webhook.testSendes når De trykker på Send test; ignorerer endepunktets hendelsesfilter.

data inneholder domenet eller sonen og objektet: posten (med previous ved oppdateringer), utløpsdatoen, navneserverne (med previous). De nøyaktige feltene i hvert objekt er de samme som i REST API-et.

Innkommende e-post kan også sendes til en URL: angi den per adresse under E-postvideresending. Disse forespørslene bruker de samme headerne og signaturen, med X-NameOcean-Event: email.received.

Greit å vite

  • NameOcean sender kun til offentlige adresser, som kontrolleres på nytt ved hver levering, og følger aldri omdirigeringer.
  • Roter hemmeligheten i dashbordet hvis den lekker; hendelser signeres umiddelbart med den nye.
  • Send test sender en webhook.test-hendelse med en gang, uavhengig av endepunktets hendelsesfilter.