pfSense REST API v2 on Netgate | install, tradeoffs, and what it's good for
pfSense has a GUI for everything. That’s fine until you need the same change on three services, want a read-only check before a cutover, or need DNS/DHCP/syslog to stay in sync with the rest of your automation. Clicking through Services → DHCP Server every time a hostname or upstream moves is how config drift starts.
The community REST API v2 package (maintained by pfrest, not Netgate) closes that gap. I run it on a Netgate 2100 with pfSense Plus. It is not in System → Package Manager on Plus builds, so install is a manual pkg-static pull from GitHub releases matched to your /etc/version.
Install (two minutes on the firewall shell)
SSH in (console option 8 on Netgate), confirm version, install the matching .pkg:
cat /etc/version
# Example for 26.03.1:
pkg-static -C /dev/null add -f \
https://github.com/pfrest/pfSense-pkg-RESTAPI/releases/download/v2.8.2/pfSense-26.03.1-pkg-RESTAPI.pkg
Then in the GUI:
- System → REST API → Settings: enable Key authentication (and/or local database if you prefer basic auth).
- System → REST API → Access Lists: allow only your automation host or lab subnet, not
0.0.0.0/0. - System → REST API → Keys: create a least-privilege key (DNS Resolver + DHCP Server write for my use case; avoid WebCfg - All unless you mean it).
- System → REST API → Documentation: Swagger UI for endpoint discovery.
Smoke test from a trusted host:
export PFSENSE_URL="https://<firewall-ip>:4443" # LAN gateway, or your nginx ingress hostname
curl -ksS -H "X-API-Key: YOUR_KEY" \
"${PFSENSE_URL}/api/v2/status/system" | jq '.status, .data.hostname'
How it helps (what I actually use it for)
Once the API is up, the firewall becomes scriptable the same way the rest of the homelab is:
- Read-before-write gates. A preflight script hits DHCP, resolver, and DNS settings over GET and exits NO-GO if the network isn’t in the shape the plan assumes. That caught a real outage before a DNS cutover wrote anything. See the Netgate DNS Cutover Toolkit write-up.
- Idempotent policy apply. PATCH with
--dry-runfirst, then--confirmwhen the diff is what I expect. DHCP DNS server, Unbound host overrides, system DNS: one toolkit instead of six GUI tabs. - DNS sync from canonical source. Push lab host overrides to Unbound from a single target list in git, so the firewall stays authoritative without hand-editing overrides in the GUI.
- Remote syslog to Splunk. PATCH
/api/v2/status/logs/settingsto point filterlog at the homelab indexer. No clicking through Status → System Logs → Settings during an incident. - Swagger for exploration. Faster than grepping the GUI when you’re trying to learn what v2 exposes on your build.
The pattern is the same as any production change control: discover state, diff against intent, apply with an explicit flag, verify on a real client.
Pros
- Real automation surface. v2 covers DHCP, Unbound, system DNS, syslog, and more. Enough to treat pfSense like infrastructure, not a one-off appliance.
- Key-based auth with access lists. Scope who can call the API and from which subnets. Better than sharing the admin password with a cron job.
- Swagger docs in the GUI. Self-documenting for the build you actually installed.
- Fits bash/Ansible/curl workflows. No vendor SDK required.
jq,curl, and a shared helper file got me most of the way. - Free. Community package, no license tier unlock.
Cons (read these before you install)
- Not official Netgate packaging on Plus. You own version matching, upgrades, and breakage if pfSense revs before pfrest ships a
.pkg. Pin the release URL to your exact version string. - Another attack surface. An API key with write access to DHCP or DNS is a fast path to locking yourself out or handing clients the wrong resolver. Least privilege, IP allow lists, key rotation.
- Community support model. Bugs and API quirks are GitHub issues, not Netgate TAC. I hit one myself: sending
Content-Type: application/jsonon bodyless GETs makes pfSense look foridin a JSON body and returnMODEL_REQUIRES_IDeven when?id=lanis in the query string. Easy fix once you know; maddening until you do. - Manual install on Plus. No one-click Package Manager entry. Fine for a homelab you operate; harder to sell on a fleet you don’t touch.
- Apply semantics bite. Endpoints with
?apply=truepush config live. Pair every write path with read-only preflight or dry-run. I don’t run destructive applies without a snapshot or rollback plan. - Not a replacement for the GUI. WAN policy, complex NAT, and one-off troubleshooting still belong in the UI with human eyes.
When I’d skip it
If the firewall is set-and-forget and you touch it twice a year, the GUI is enough. If you can’t restrict API keys and access lists, don’t install it. If you need vendor-backed API support on a production edge with SLAs, evaluate what Netgate officially documents for your tier before betting the edge on a community package.
For a homelab or small MSP lab where you are the change control board and you want DNS/DHCP/syslog to move with the rest of your scripts, the tradeoff is worth it.
Related
- Netgate DNS Cutover Toolkit: preflight gate, API bug, live DHCP cutover
- Making pfSense the front door over Tailscale: subnet router on the firewall (GUI path, not API)
- pfrest REST API repo: releases, issues, Swagger source