REST API Reference
Base URL: http://<pi-ip>/api. All endpoints except /api/health require Bearer authentication.
Authentication
Protected endpoints accept three auth methods:
- Bearer token (root API key or named API key):
Authorization: Bearer <KEY> - Session cookie: obtained via
POST /api/loginwith username + password - Basic auth (Traefik httpreq):
Authorization: Basic <base64(:<named-key>)>
Public endpoints (no auth): /api/health, /api/login, /api/setup/*, /dns-query (DoH).
# Bearer token
curl -H "Authorization: Bearer <YOUR_API_KEY>" \
http://<PI_IP>/api/zones
# Session login
curl -c cookies.txt -X POST http://<PI_IP>/api/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"<PASSWORD>"}'
curl -b cookies.txt http://<PI_IP>/api/zonesRetrieve your root API key from the Dashboard → Settings → Security. Named API keys can be created per tool — see Named API Keys.
Health
{ "status": "ok" }Zones
Create Zone — Example
curl -X POST http://<PI_IP>/api/zones \
-H "Authorization: Bearer <KEY>" \
-H "Content-Type: application/json" \
-d '{
"domain": "home.lan",
"ttl": 3600,
"nameservers": ["ns1.home.lan"],
"admin_email": "admin@home.lan"
}'Records
Add A Record — Example
curl -X POST http://<PI_IP>/api/zones/home.lan/records \
-H "Authorization: Bearer <KEY>" \
-H "Content-Type: application/json" \
-d '{
"name": "nas",
"type": "A",
"value": "192.168.1.100",
"ttl": 3600
}'Blocklist
Blocklist URLs
{"enabled": true}
Manual Domains
{"domain": "ads.example.com"}
Allow-list (Bypass Blocklist)
{"domain": "example.com"}
Patterns (Wildcard / Regex)
{"pattern": "*.ads.example.com", "type": "wildcard"} or "type": "regex"
Client IP Whitelist
{"ip_cidr": "192.168.1.0/24"}. Use "localhost" to add 127.0.0.1 + ::1.
192.168.1.0%2F24)
Config (Live Reload)
Some configuration values can be updated without restarting:
Update Upstream DNS — Example
curl -X PATCH http://<PI_IP>/api/config \
-H "Authorization: Bearer <KEY>" \
-H "Content-Type: application/json" \
-d '{
"dnsserver": {
"upstream": ["1.1.1.1", "1.0.0.1"]
}
}'Split-Horizon DNS
Serve different zone content to different client subnets. Requires dnsserver.split_horizon.enabled: true. All zone/record endpoints accept an optional ?view=<name> query parameter.
Configure Views — Example
curl -X PUT http://<PI_IP>/api/split-horizon \
-H "Authorization: Bearer <KEY>" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"views": [
{"name": "internal", "subnets": ["192.168.0.0/16", "10.0.0.0/8"]},
{"name": "external", "subnets": ["0.0.0.0/0"]}
]
}'DDNS / RFC 2136
DomU DNS accepts RFC 2136 DNS UPDATE messages on UDP/TCP port 53, authenticated with TSIG keys. Manage keys via the REST API. DHCP servers (e.g. ISC DHCP, Kea) can register A and PTR records automatically.
Create TSIG Key — Example
curl -X POST http://<PI_IP>/api/ddns/keys \
-H "Authorization: Bearer <KEY>" \
-H "Content-Type: application/json" \
-d '{"name": "dhcp-key", "algorithm": "hmac-sha256"}'
# Response: {"data":{"name":"dhcp-key","algorithm":"hmac-sha256","secret":"<BASE64 — shown once>"}}Cluster
Zone Import / Export
Import zones from RFC 1035 zone files or via live AXFR transfer. Export zones as standard zone files.
?view= for split-horizon zones.
?view= for split-horizon zones.
Import Zone File — Example
curl -X POST http://<PI_IP>/api/zones/import \ -H "Authorization: Bearer <KEY>" \ -F "file=@home.lan.zone"
Import via AXFR — Example
curl -X POST http://<PI_IP>/api/zones/import/axfr \
-H "Authorization: Bearer <KEY>" \
-H "Content-Type: application/json" \
-d '{
"master": "192.168.1.1:53",
"domain": "home.lan"
}'Export Zone — Example
curl -O -J \ -H "Authorization: Bearer <KEY>" \ "http://<PI_IP>/api/zones/home.lan/export" # Saves: home.lan.zone
Named API Keys
Create per-tool API keys (Traefik, Certbot, acme.sh, Proxmox) without sharing the root key. Each key is shown only once at creation time. Named keys and the root key are interchangeable for Bearer and Basic Auth.
Create Named API Key — Example
curl -X POST http://<PI_IP>/api/auth/api-keys \
-H "Authorization: Bearer <ROOT_KEY>" \
-H "Content-Type: application/json" \
-d '{"name": "traefik"}'
# Response: {"data":{"name":"traefik","key":"<RAW_KEY — shown only once>"}}ACME / DNS-01
Traefik httpreq provider endpoints for automating Let's Encrypt DNS-01 challenges. DomU DNS stores _acme-challenge TXT records and serves them over DNS. Works with Traefik, Certbot (certbot-dns-domudns), and acme.sh/Proxmox.
Present DNS-01 Challenge — Example
curl -X POST http://<PI_IP>/api/acme/httpreq/present \
-H "Authorization: Bearer <KEY>" \
-H "Content-Type: application/json" \
-d '{
"fqdn": "_acme-challenge.home.lan.",
"value": "base64encodedtoken..."
}'Cache
Inspect and control the DNS cache. Flush and per-entry delete are local-only operations — they are not propagated to cluster slaves. TTLs in cached responses are decremented in real time (RFC 1035).
example.com/A)
Get Cache Stats — Example
curl -H "Authorization: Bearer <KEY>" http://<PI_IP>/api/cache
# Response:
{
"data": {
"entries": 42,
"hits": 1204,
"misses": 38,
"hit_rate": 96.9,
"entry_list": [
{ "name": "example.com.", "type": "A", "remaining_ttl": 12, "expires_at": 1742900000, "cached_at": 1742899700 },
...
]
}
}Delete Cache Entry — Example
curl -X DELETE \ -H "Authorization: Bearer <KEY>" \ "http://<PI_IP>/api/cache/example.com/A"