API-dokumentasjon
Norgesdomene API — versjon 1. Base-URL: https://norgesdomene.no/api/v1
Introduksjon
API-et lar deg lese domenene dine, styre DNS og navnetjenere og følge ordrer programmatisk. Partnere med forhåndssaldo kan i tillegg registrere, flytte og fornye domener. Alle priser er i norske øre (NOK). Alle svar er JSON.
Alle endepunkter har base-URL https://norgesdomene.no/api/v1 og krever autentisering. Foretrekker du å la en AI-assistent gjøre jobben, se MCP for AI-assistenter under — samme nøkkel, samme tilgang.
Autentisering
Alle kunder kan lage API-nøkler under AI-assistenter (MCP) i foretaksmenyen i portalen. Partnere finner også nøklene under Partner-API. Send nøkkelen som et Bearer-token i Authorization-headeren. Alle nøkler starter med ndp_live_.
Authorization: Bearer ndp_live_xxxxxxxxxxxxxxxxxxxx
Nøkler har scopes. Lese-endepunkter krever domains:read eller dns:read, skriveoperasjoner krever domains:write eller dns:write. En nøkkel opprettet som «kun lesetilgang» har bare lese-scopene.
Endepunktene som bestiller mot forhåndssaldo (POST /domains, POST /domains/transfers, POST /domains/:id/renew og GET /account) svarer 403 api_disabled til kontoer uten partneravtale. Alle andre endepunkter er åpne for enhver gyldig nøkkel.
MCP for AI-assistenter
Norgesdomene har en MCP-server (Model Context Protocol) på https://norgesdomene.no/api/mcp. Koble den til Claude Code, Cursor eller en klient med støtte for MCP over HTTP og Bearer-nøkkel, så kan assistenten sjekke domener, lese og endre DNS, bytte navnetjenere og se tjenestene på kontoen. Bestilling og betaling skjer alltid i kassen på norgesdomene.no.
Uten nøkkel finnes bare de offentlige verktøyene. Med en API-nøkkel (samme Authorization: Bearer-header som REST-API-et) kommer kontoverktøyene i tillegg, styrt av nøkkelens scopes.
Claude Code
Oppsett med innlogging i Claude Code:
claude mcp add --scope user --transport http norgesdomene-oauth https://norgesdomene.no/api/mcp/oauth claude mcp login norgesdomene-oauth
Alternativt med API-nøkkel:
claude mcp add --scope user --transport http norgesdomene https://norgesdomene.no/api/mcp \ --header "Authorization: Bearer ndp_live_xxxx"
Cursor (~/.cursor/mcp.json)
{
"mcpServers": {
"norgesdomene": {
"url": "https://norgesdomene.no/api/mcp",
"headers": { "Authorization": "Bearer ndp_live_xxxx" }
}
}
}Du kan også koble til med innlogging på https://norgesdomene.no/api/mcp/oauth. Da velger du kundekonto og godkjenner lesetilgang uten API-nøkkel. OAuth er verifisert med Claude Code. ChatGPT, Claude Desktop og Cursor med OAuth avventer egne klienttester. Lag gjerne en egen nøkkel med kun lesetilgang for hver assistent.
Verktøy
| Verktøy | Krever | Gjør |
|---|---|---|
| check_domain | Ingen nøkkel | Ledighet, pris og bestillingslenke for et domene |
| get_domain_prices | Ingen nøkkel | Listepriser per toppdomene (inkl. mva) |
| create_order_link | Ingen nøkkel | Lenke til kassen for registrering eller flytting |
| get_account | domains:read | Hvilken konto nøkkelen tilhører |
| list_domains | domains:read | Kontoens domener med status og utløp |
| get_domain | domains:read | Detaljer om ett domene |
| list_services | domains:read | Webhotell, e-post, VPS, Microsoft 365, Deploy |
| list_dns_records | dns:read | DNS-oppføringer i Norgesdomenes DNS |
| create_dns_record | dns:write | Opprett DNS-oppføring |
| update_dns_record | dns:write | Endre DNS-oppføring |
| delete_dns_record | dns:write | Slett DNS-oppføring |
| set_nameservers | domains:write | Bytt navnetjenere hos registeret |
Serveren er stateless (ingen sesjoner) og følger MCP-spesifikasjonen 2026-07-28, med støtte for eldre klienter. Rate limit er den samme som for REST-API-et.
Forhåndssaldo
Bestilling via API er for partnere med avtale: ordrene trekkes fra kontoens forhåndsinnbetalte saldo. Saldoen er i øre. Har du for lav saldo ved bestilling returnerer API-et 402 insufficient_balance. Uten avtale bruker du kassen på norgesdomene.no — MCP-verktøyet create_order_link lager lenken for deg.
Sjekk gjeldende saldo med GET /account.
Idempotens
Alle skrive-operasjoner (POST /domains, POST /domains/:id/renew) krever headeren Idempotency-Key med en unik streng per forsøk. Send samme nøkkel ved retry; du får da samme svar uten at bestillingen dobles.
Idempotency-Key: ordre-klient-ref-abc123
Webhooks
Flytting og registrering er asynkrone — de fullføres hos registeret etter at API-et har svart. I stedet for å spørre om status gjentatte ganger kan du registrere et endepunkt under API i portalen, så sender vi en POST når noe skjer.
Hendelser
domain.transfer.completed — domenet er flyttet og aktivt hos oss
domain.transfer.failed — flyttingen feilet (feil transferkode, avvist av registeret e.l.)
Kropp
{
"event": "domain.transfer.completed",
"createdAt": "2026-08-04T12:00:00.000Z",
"data": {
"domainId": "dom_xxxxxxxxxxxx",
"domain": "mittdomene.no",
"orderId": "ord_xxxxxxxxxxxx"
}
}Verifisering
Hver leveranse har headeren X-Norgesdomene-Signature på formen t=<unix>,v1=<hmac>. Signaturen er HMAC-SHA256 over <t>.<rå kropp> med signeringsnøkkelen du fikk da endepunktet ble opprettet. Tidsstemplet er med i signaturen så en avlyttet leveranse ikke kan spilles av på nytt — avvis forespørsler der t er eldre enn fem minutter.
const [t, v1] = header.split(",").map((p) => p.split("=")[1])
const expected = crypto
.createHmac("sha256", process.env.NORGESDOMENE_WEBHOOK_SECRET)
.update(`${t}.${rawBody}`)
.digest("hex")
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1))) {
return res.status(400).end()
}
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) {
return res.status(400).end()
}Svar 2xx når du har tatt imot hendelsen. Får vi noe annet, prøver vi på nytt etter 1, 5 og 25 minutter, så 2 og 10 timer, før vi gir opp. Samme hendelse sendes aldri to ganger for samme domene, men bygg mottakeren idempotent likevel.
Endepunktet må bruke https og peke på en offentlig adresse. Interne og private adresser avvises.
Endepunkter
Sjekk om et domene er ledig og hent pris.
Query-parameter: domain (f.eks. mittdomene.no)
Svar — ledig
{
"domain": "mittdomene.no",
"available": true,
"priceOre": 19375,
"vatOre": 4844,
"totalOre": 24219,
"currency": "NOK"
}Svar — ikke ledig
{
"domain": "opptatt.no",
"available": false,
"reason": "taken"
}Registrer et nytt domene. Kun .no støttes i denne versjonen — forespørsler på andre toppdomener avvises med 400 invalid_request. Se Registrerings- og deklarasjonsflyt nedenfor.
Forespørselskropp
{
"domain": "mittdomene.no",
"period": 1, // valgfri, 1–10 år
"registrant": {
"type": "organisasjon", // "person" eller "organisasjon"
"name": "Mitt Firma AS",
"orgNumber": "123456789", // 9 siffer — kreves for organisasjon
// "personId": "...", // kreves for type person
"email": "eier@firma.no",
"phone": "+4712345678", // valgfri
"addressLine1": "Storgata 1", // valgfri
"postalCode": "0001", // valgfri
"city": "Oslo", // valgfri
"country": "NO" // valgfri, standard NO
},
"nameservers": [ // valgfri
"ns1.mittfirma.no",
"ns2.mittfirma.no"
]
}Svar — 202 Accepted
{
"orderId": "ord_xxxxxxxxxxxxxxxx",
"orderNumber": "10042",
"domain": "mittdomene.no",
"status": "pendingRegistration",
"declarationUrl": "https://norgesdomene.no/deklarasjon/a1b2c3d4e5f6"
}Flytt et domene fra en annen registrar. Kun .no støttes i denne versjonen. Flytting av .no er gratis og beholder utløpsdatoen — domenet forlenges ikke, og du betaler først ved neste fornyelse.
En ren registrarflytting endrer ikke eier, og krever derfor ingen egenerklæring fra innehaveren. Det er forskjellen fra nyregistrering, og det som gjør at en hel portefølje kan flyttes uten at hver sluttkunde må signere noe.
Forespørselskropp
{
"domain": "mittdomene.no",
"authCode": "TransferKode123" // fra nåværende leverandør
// "noRegistrar": true // kun .no som står uten registrar —
// de har aldri hatt en transferkode
}Navnetjenerne beholdes alltid slik de er, så nettsted og e-post fortsetter uten avbrudd gjennom flyttingen. Vil du over på NorgesDNS, gjør du det i to steg etterpå: opprett oppføringene med POST /domains/{id}/dns, og bytt så navnetjenere med PUT /domains/{id}/nameservers. Rekkefølgen er viktig — bytter du navnetjenere før sonen er fylt, peker domenet mot ingenting.
Svar — 202 Accepted
{
"orderId": "ord_xxxxxxxxxxxxxxxx",
"orderNumber": "10043",
"domain": "mittdomene.no",
"status": "pendingTransfer",
"declarationUrl": null
}Flyttingen kjøres mot registeret etter at svaret er sendt, fordi Norid behandler ett flyttekall om gangen. Poll GET /domains/{id} til status går fra pendingTransfer til active. Feiler den, blir domenet stående i pendingTransfer og forsøkes på nytt automatisk — ingenting går tapt.
Hent liste over alle domener på kontoen (maks 200, sortert på utløpsdato).
Svar — 200 OK
{
"domains": [
{
"id": "dom_xxxxxxxxxxxxxxxx",
"name": "mittdomene.no",
"status": "active",
"expiresAt": "2026-05-01T00:00:00.000Z",
"registrar": "norid"
}
]
}Hent detaljer for ett domene. Bruk status-feltet for å poll-e registreringsstatus.
Svar — 200 OK
{
"id": "dom_xxxxxxxxxxxxxxxx",
"name": "mittdomene.no",
"status": "active",
"expiresAt": "2026-05-01T00:00:00.000Z",
"registrar": "norid",
"autoRenew": false
}Forny et domene med TLD-ens standardperiode (typisk 1 år). Beløpet trekkes fra saldo. Krever ingen forespørselskropp.
Svar — 202 Accepted
{
"orderId": "ord_xxxxxxxxxxxxxxxx",
"orderNumber": "10043",
"status": "active"
}Får ikke registraren svart i tide, kan svaret (eller et replay med samme Idempotency-Key) ha pendingRenewal: utfallet verifiseres mot registraren og ordren fullføres automatisk hvis fornyelsen gikk gjennom. Ikke send en ny forespørsel med en annen nøkkel — et nytt forsøk kan opprette en duplikat fornyelse.
Oppdater nameservere for et domene (erstatter eksisterende liste). Minst én, maks 13.
Har domenet DNSSEC på, avvises et bytte bort fra NorgesDNS med 409 conflict. En DS-post uten matchende signering gjør domenet utilgjengelig for validerende resolvere. DNSSEC skrus av i kundeportalen under Navnetjenere — vent noen timer etterpå før du bytter nameservere, så rekker den gamle DS-posten å gå ut av cachene.
Forespørselskropp
{
"nameservers": [
"ns1.ditt-hosting.no",
"ns2.ditt-hosting.no"
]
}Svar — 200 OK
{
"ok": true,
"nameservers": ["ns1.ditt-hosting.no", "ns2.ditt-hosting.no"]
}Hent alle DNS-oppføringer for et domene kontoen eier.
Svar — 200 OK
{
"records": [
{
"id": "uuid",
"type": "A",
"name": "@",
"value": "203.0.113.10",
"ttl": 3600,
"priority": null,
"weight": null,
"flags": null,
"tag": null,
"port": null,
"disabled": false
}
]
}Opprett en ny DNS-oppføring. Se tabellen over støttede typer nedenfor for påkrevde tilleggsfelt per type.
Forespørselskropp
{
"type": "A",
"name": "@",
"value": "203.0.113.10",
"ttl": 3600
}Svar — 201 Created
{
"id": "uuid",
"type": "A",
"name": "@",
"value": "203.0.113.10",
"ttl": 3600,
"priority": null,
"weight": null,
"flags": null,
"tag": null,
"port": null,
"disabled": false
}curl-eksempel
curl -X POST https://norgesdomene.no/api/v1/domains/$DOMAIN_ID/dns \
-H "Authorization: Bearer $NDP_KEY" \
-H "Content-Type: application/json" \
-d '{"type":"A","name":"@","value":"203.0.113.10","ttl":3600}'Oppdater en eksisterende DNS-oppføring. Samme kropp-format som POST /dns.
Forespørselskropp
{
"type": "A",
"name": "@",
"value": "203.0.113.10",
"ttl": 3600
}Svar — 200 OK
{
"id": "uuid",
"type": "A",
"name": "@",
"value": "203.0.113.10",
"ttl": 3600,
"priority": null,
"weight": null,
"flags": null,
"tag": null,
"port": null,
"disabled": false
}Slett en DNS-oppføring. Returnerer tomt svar ved suksess.
Svar — 204 No Content
(tomt svar)
DNS-typer og påkrevde felt
ttl er valgfri (standard 3600, gyldig 60–86400). Tabellen viser hvilke tilleggsfelt som kreves per type.
| Type | Beskrivelse og krav |
|---|---|
| A | value = IPv4-adresse |
| AAAA | value = IPv6-adresse |
| CNAME | value = vertsnavn (kan ikke ligge på rotdomenet/@) |
| TXT | value = tekst |
| MX | value = mailserver-navn; krever priority |
| SRV | navn på formen _service._proto; krever priority, weight, port |
| CAA | krever flags og tag |
Navnetjenere og NorgesDNS
DNS-oppføringer trer i kraft når domenet bruker NorgesDNS-navnetjenere (ns1.norgesdns.no / ns2.norgesdns.no). Et domene registrert via API-et får dette automatisk ved første DNS-skriving. Har du satt egne eksterne navnetjenere, lagres oppføringene, men de resolver ikke før domenet peker til NorgesDNS.
Idempotens for DNS-skriving
DNS-skriving krever ikke Idempotency-Key. POST er ikke idempotent — et nytt forsøk kan opprette en duplikat. For å endre en eksisterende oppføring: hent listen (GET) og bruk PUT/DELETE på recordId.
Hent status og detaljer for en ordre. Bruk orderId fra POST /domains-svaret for å poll-e.
Svar — 200 OK
{
"orderId": "ord_xxxxxxxxxxxxxxxx",
"orderNumber": "10042",
"status": "pendingRegistration",
"totalOre": 24219,
"items": [
{
"kind": "domain_registration",
"description": "mittdomene.no (1 år)",
"meta": {}
}
]
}Hent gjeldende saldo på kontoen.
Svar — 200 OK
{
"balanceOre": 500000,
"currency": "NOK"
}Registrerings- og deklarasjonsflyt (.no)
For .no-domener er registrering en tostegs-prosess. Et 202-svar fra POST /domains betyr at ordren er mottatt og saldo er reservert — ikke at domenet er registrert hos Norid ennå.
Viktig: videresend deklarasjonslenken til din kunde
Svaret inneholder et declarationUrl-felt — en side hos Norgesdomene (norgesdomene.no/deklarasjon/…). Du sender lenken til domenets registrant (din sluttkunde), som fyller ut og signerer Norids egenerklæring der. Vi sender erklæringen til Norid og registrerer domenet først etter at den er levert.
Flyten steg for steg:
- Du kaller POST /domains → mottar 202 med status: "pendingRegistration" og declarationUrl.
- Du sender declarationUrl til din sluttkunde via e-post eller SMS.
- Sluttkunden åpner lenken (hos Norgesdomene), fyller ut og signerer egenerklæringen.
- Vi sender erklæringen til Norid og registrerer domenet. Status endres til active.
- Poll GET /domains/:id eller GET /orders/:id til status er active.
Håndter at declarationUrl kan være null
I sjeldne tilfeller (f.eks. om lenkegenerering ikke fullførte) er declarationUrl null selv om ordren er opprettet og saldo trukket. Ikke send en tom lenke til kunden — sjekk for null, og kontakt oss (eller prøv igjen) hvis den mangler. Feltet gjelder dessuten kun .no.
Feilkoder
Alle feil returneres med HTTP-statuskoden nedenfor og kroppen:
{ "error": { "code": "invalid_request", "message": "..." } }| Kode | HTTP | Betydning |
|---|---|---|
| unauthorized | 401 | Ugyldig eller manglende API-nøkkel. |
| forbidden_scope | 403 | Nøkkelen mangler nødvendig scope. |
| api_disabled | 403 | API-tilgang er ikke aktivert for kontoen. |
| rate_limited | 429 | For mange forespørsler. Vent og prøv igjen. |
| invalid_request | 400 | Manglende eller ugyldig felt i forespørselen. |
| domain_taken | 409 | Domenet er allerede registrert. |
| invalid_contact | 422 | Registrantdata godkjennes ikke (f.eks. manglende orgNumber). |
| insufficient_balance | 402 | Saldo er for lav til å gjennomføre ordren. |
| provisioning_failed | 502 | Ekstern feil ved provisjonering hos register. |
| not_found | 404 | Domene eller ordre finnes ikke. |
curl-eksempler
Sjekk om et domene er ledig
curl -s \ -H "Authorization: Bearer ndp_live_xxxx" \ "https://norgesdomene.no/api/v1/domains/check?domain=mittdomene.no"
Registrer et .no-domene (organisasjon)
curl -s -X POST \
-H "Authorization: Bearer ndp_live_xxxx" \
-H "Idempotency-Key: ordre-ref-001" \
-H "Content-Type: application/json" \
-d '{
"domain": "mittdomene.no",
"period": 1,
"registrant": {
"type": "organisasjon",
"name": "Mitt Firma AS",
"orgNumber": "123456789",
"email": "eier@firma.no"
}
}' \
"https://norgesdomene.no/api/v1/domains"