Docs › Reference

API reference

Three interfaces, two of them protocols your existing software already speaks. Everything is served from api.home.network, which resolves straight to our own nameservers and terminates TLS there.

Dynamic DNS (dyndns2)

The classic protocol, unchanged. HTTP Basic authentication, with your label as the username and a DDNS token as the password.

dyndns2
GET https://api.home.network/nic/update?hostname=<fqdn>&myip=<address>
Authorization: Basic <label:token>

# myip=auto uses the source address of the request
curl -u 'alice:TOKEN' \
  'https://api.home.network/nic/update?hostname=nas.alice.home.network&myip=auto'
ResponseMeaningWhat a client should do
good <ip>Record updatedNothing
nochg <ip>Already correctNothing. Not an error
badauthWrong label or tokenStop and fix the credentials
nohostHostname not in your labelCreate it first
notfqdnMalformed hostnameFix the request
abuseRate limitedBack off
911Fault at our endRetry later, change nothing
Two ways to send credentials, because routers differ. pfSense, OPNsense and UniFi send a real HTTP Basic header from their own username and password fields. FRITZ!Box, OpenWrt and Synology have no separate authentication step and only substitute values into the update URL, so on those the credentials belong in the URL as https://label:token@api.home.network/nic/update?.... Both forms are accepted. The per-platform pages show the correct one, and picking the wrong one produces badauth on a credential that is perfectly valid.
911 and badauth are deliberately different. A router that receives badauth may disable the configuration permanently, so we return it only for genuinely wrong credentials. An outage on our side returns 911, which clients retry.

Certificates (acme-dns)

The acme-dns protocol, so any client supporting it works without a plugin written for us.

acme-dns
POST https://api.home.network/acmedns/update
X-Api-User: <username>
X-Api-Key:  <password>
Content-Type: application/json

{"subdomain": "<subdomain>", "txt": "<43-character challenge value>"}

The published record is always _acme-challenge.<label>.home.network. The subdomain field is accepted for wire compatibility and ignored, because the name is derived from the credential rather than the request. That is what makes per-hostname certificates impossible and keeps your device names out of Certificate Transparency logs.

Records (REST)

For automation. Bearer token authentication, and the token is scoped to one label.

REST
GET    /api/v1/me                       your label and quota
GET    /api/v1/hostnames                list hostnames
POST   /api/v1/hostnames                create one
GET    /api/v1/hostnames/:id/records    list records
POST   /api/v1/hostnames/:id/records    create or replace
DELETE /api/v1/records/:id              remove one
GET    /api/v1/status                   label state

curl -H "Authorization: Bearer $HN_TOKEN" \
  https://api.home.network/api/v1/hostnames

Accepted record values

A, AAAA, TXT and CNAME. Private addresses are the point of the service, so RFC 1918 ranges, unique local addresses and the RFC 6598 shared address space used by overlay networks are all accepted. Loopback, link-local, multicast and broadcast addresses are refused, since publishing them causes problems for the person who does it.

Rate limits

Update endpoints are rate limited per credential, and certificate challenge writes are limited per label. A client retrying in a loop is throttled rather than allowed to affect other customers. Limits are generous enough that normal use never reaches them, and a request that is throttled receives abuse or HTTP 429 rather than a failure that looks like a credential problem.

← All documentation