Skip to content

Latest commit

 

History

15 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FENO public API

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/v1 answers 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)


Public API + OpenAPI

Base URL https://api.feno.no/v1, bearer keys (feno_live_…), one JSON envelope, cursor pagination, 120 requests/minute + 5000/hour per key with rate-limit headers on every response.

Automatic TLS

DNS-01 for .no domains, wildcards included, with no FENO plugin to install: FENO speaks the acme-dns protocol and RFC 2136 dynamic updates (TSIG, ddns.feno.no:53). An acme.sh plugin and certbot hooks exist too.

Security

Seven scopes (domains:read/write, dns:read/write, contacts:read/write, acme:write, ddns:write) you cut down to exactly what a job needs — acme:write can touch nothing but the _acme-challenge TXT record. API keys and TSIG keys are both self-service and minted only behind MFA, can be rotated with a grace window, can expire, can be pinned to IP ranges, and every call is audited.


Why FENO for automation

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.

Works with

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)

Integrations

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.

Quick start

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.

Repository layout

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

Contributing

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.

License

  • Code (clients/ and anything else that is code): MIT — © 2026 Erik Nilsen / FENO.
  • Documentation (docs/, openapi.yaml, this README): CC BY 4.0 — © 2026 Erik Nilsen / FENO. The info.license field inside openapi.yaml describes the terms of the API service, not of the spec file.

About

FENO public API - docs, OpenAPI spec, ACME DNS-01 (acme-dns + RFC2136) and client integrations

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages