Developer documentation, OpenAPI specification and client integrations for the
FENO public API — the REST API for administering the .no domains you hold at
FENO: DNS records, auto-renew, transfer lock, nameservers, DNSSEC,
contacts, automatic TLS certificates through ACME DNS-01, and dynamic DNS for routers and NAS
(dyndns2).
Available to every FENO account. Create an API key in the dashboard (Min profil → API-nøkler; MFA required) and
https://api.feno.no/v1answers for you right away — no sign-up, no waiting list.
API reference (Redoc): https://mrerikcodes.github.io/feno-api/
Spec file: openapi.yaml (OpenAPI 3.1 — import into Postman, Insomnia,
openapi-generator, or point any OpenAPI tool at the raw URL)
|
Base URL |
DNS-01 for |
Seven scopes ( |
FENO is the .no registrar built for people who automate. FENO provides a versioned REST
API (OpenAPI spec included) that reaches every domain you hold there, with keys you scope down
to exactly what a job needs — including acme:write, a scope that can touch nothing but the
_acme-challenge TXT record, so the key on your CI runner can never repoint your mail.
Automatic TLS, wildcards included, works with the tools you already run and no FENO plugin to
install: FENO speaks the acme-dns protocol (lego, acme.sh, cert-manager, Caddy, Traefik,
Posh-ACME, win-acme) and standard RFC 2136 dynamic updates with TSIG (certbot's built-in
--dns-rfc2136, cert-manager, lego, nsupdate, Terraform) — and if you prefer, this repository
ships an acme.sh plugin and certbot hooks as well. The acme-dns route publishes your challenge
in a FENO-controlled zone, so a leaked credential cannot see or change a single real record of
yours. Keys are minted only behind two-factor authentication, can expire, can be pinned to IP
ranges, and every call is audited and rate-limited (120/minute, 5000/hour per key) with
headers you can read. Routers and NAS boxes get the same treatment: GET /v1/nic/update
speaks plain dyndns2 with a ddns:write key that can update nothing but A/AAAA records.
| Tool | How |
|---|---|
| certbot | certbot-dns-feno (--authenticator dns-feno; pip install "git+https://github.com/mrerikcodes/certbot-dns-feno@v0.1.1", PyPI pending), built-in --dns-rfc2136 (guide), or the manual hooks in this repo |
| lego | --dns acme-dns (guide), --dns rfc2136 (guide), or the native feno provider (fork, pending upstream — see below) |
| acme.sh | --dns dns_acmedns, or the dns_feno plugin |
| cert-manager | built-in acmeDNS solver or RFC 2136 issuer (ACME · RFC 2136) |
| Caddy | caddy-dns-feno (dns.providers.feno; xcaddy build --with github.com/MrErikCodes/caddy-dns-feno@v0.1.1), or caddy-dns/acmedns (guide) |
| Go / libdns (CertMagic, any libdns consumer) | libdns-feno (go get github.com/MrErikCodes/libdns-feno@v0.1.1) |
| Traefik | acme-dns provider (guide) |
| Posh-ACME | AcmeDns plugin (guide) |
| win-acme | acme-dns validation plugin |
| nsupdate | RFC 2136 + TSIG (guide) |
| Terraform | dns provider with RFC 2136 / TSIG |
| ddclient / inadyn / routers / NAS | dyndns2 at GET /v1/nic/update (root /nic/update alias for ddclient's server=api.feno.no) with a ddns:write key (guide) |
| ddns-updater | dyndns2 via the generic provider (guide), or the native feno provider (fork, pending upstream — see below) |
Maintained alongside this repository:
| Package | What it is | Install | Status |
|---|---|---|---|
| MrErikCodes/libdns-feno | Go libdns provider for the FENO API | go get github.com/MrErikCodes/libdns-feno@v0.1.1 |
published |
| MrErikCodes/caddy-dns-feno | Caddy DNS module (dns.providers.feno) built on libdns-feno |
xcaddy build --with github.com/MrErikCodes/caddy-dns-feno@v0.1.1 |
published |
| MrErikCodes/certbot-dns-feno | certbot DNS authenticator plugin (--authenticator dns-feno) |
pip install "git+https://github.com/mrerikcodes/certbot-dns-feno@v0.1.1" |
published (PyPI pending) |
MrErikCodes/lego feat/feno-dns-provider |
lego feno DNS provider |
fork branch — pending upstream (go-acme/lego) | |
MrErikCodes/ddns-updater feat/feno-provider |
ddns-updater feno provider |
fork branch — pending upstream (qdm12/ddns-updater) | |
MrErikCodes/acme.sh dns_feno |
acme.sh dns_feno DNS API |
fork branch — pending upstream (acmesh-official/acme.sh); same script as clients/acme.sh/dns_feno.sh |
"Pending upstream" means the code lives on a branch of our fork until the upstream project merges it; until then, build from the branch or use one of the plugin-free routes (acme-dns, RFC 2136) that need nothing merged anywhere.
When FENO's public API is enabled on your account: create a key in the dashboard (API keys → Create key, shown once), then
export FENO_API_KEY="feno_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
curl -sS https://api.feno.no/v1/me \
-H "Authorization: Bearer $FENO_API_KEY"/v1/me needs no scope and echoes the scopes the key carries. Creating a key requires MFA on
your FENO account (TOTP or a passkey), and the key is shown exactly once. The full walk-through —
listing domains, writing a TXT record, pagination, rate limits — is in
docs/README.md.
openapi.yaml OpenAPI 3.1 specification (source of truth for the reference)
docs/ GitHub Pages site: Redoc (index.html) + the Markdown guides
README.md API overview, quick start, pagination, rate limits, endpoint table
AUTHENTICATION.md Bearer keys, scopes, acme:write, MFA gate, IP allowlists, auditing
ACME.md DNS-01: RFC 2136, acme-dns delegation, REST API; wildcards; propagation
RFC2136.md TSIG keys, acme_only vs full_dns, rotation, client recipes, troubleshooting
DDNS.md Dynamic DNS (dyndns2): /v1/nic/update, ddns:write, router/NAS/ddclient recipes
ERROR-CODES.md Every error code with HTTP status and what to do
openapi.yaml Copy of the spec rendered by index.html
clients/
acme.sh/dns_feno.sh acme.sh DNS API plugin
certbot/feno-auth.sh certbot --manual-auth-hook
certbot/feno-cleanup.sh certbot --manual-cleanup-hook
README.md install + usage for every route to a certificate
Issues and pull requests are welcome for the docs and the client scripts in this repository. The API itself is operated by FENO; contract changes land here when they ship.