The admin API
The admin API sets the household up and manages the server. Every call here is also a homefellow command (see
the homefellow command), which prints the same JSON with --json.
Who may call it
Section titled “Who may call it”- Before the household exists: the one-time setup code, in the header
X-Homefellow-Setup-Code. The server prints it when it starts.homefellow setup-codeshows it again. Five wrong codes in ten minutes answer429 slow_down. Once the household exists, the code is spent (403 set_up). - After: an owner’s device token, as
Authorization: Bearer <token>. A member’s token answers403 forbidden.
Setup mode. Until the household exists, only /api/health, /api/admin/*, /setup and the web app’s files
answer. The rest answers 503 not_set_up.
Settings chosen here go into the data folder’s settings.toml. Models take effect at once. Voice, home-network
access, the listening address and a restore take effect at the next start. restart_needed lists them.
The calls
Section titled “The calls”| Call | Command | What it does |
|---|---|---|
GET /api/admin/status[?probe=true] |
status, doctor |
the doctor’s report, what needs a restart, the addresses, the version |
GET /api/admin/plan |
setup --plan |
the setup steps and where each stands |
POST /api/admin/plan/later |
setup --later family |
leave inviting the household for later |
GET /api/admin/version |
version |
the version and database schema |
GET /api/admin/timezone |
the computer’s time zone | |
POST /api/admin/setup |
setup |
create the household and its first owner |
GET /api/admin/models |
models |
the models in use and the last test |
POST /api/admin/models/discover |
models discover |
look for model servers |
POST /api/admin/models/choose |
models choose |
use those models |
POST /api/admin/models/test |
models test |
test the models |
GET, POST /api/admin/voice |
voice |
how spoken answers are turned into text |
GET, POST /api/admin/voice/fetch |
voice fetch |
download the speech model and see its progress |
GET /api/admin/access |
access |
addresses, home network, Tailscale, iroh, the firewall |
POST /api/admin/access/lan |
access lan on|off |
the home network, over HTTPS |
POST /api/admin/access/tailscale |
access tailscale |
publish on the tailnet |
POST /api/admin/access/iroh |
access iroh on|off |
reach it from anywhere |
POST /api/admin/access/firewall |
access firewall |
record or open the firewall |
GET, POST /api/admin/invites |
invites, invite |
list or make invites |
DELETE /api/admin/invites/{id} |
invites revoke ID |
withdraw an open invite |
POST /api/admin/people/{id}/role |
people role ID owner|member |
change someone’s role |
GET, PUT /api/admin/backups |
backups, backups schedule |
the backups and their schedule |
POST /api/admin/backups/run |
backups run |
make a backup now |
POST /api/admin/backups/check |
backups check |
check a backup would restore |
POST, DELETE /api/admin/backups/restore |
backups restore |
stage a restore, or call it off |
The doctor and the plan
Section titled “The doctor and the plan”GET /api/admin/status answers {"doctor": Report, "restart_needed": [key], "setup": {"done"}, "addresses": [Address], "version"}. With probe=true it also asks the model servers and addresses, which takes a few seconds.
Report:{"ok", "problems", "warnings", "version", "checked_at", "checks": [Check]}.Check:{"id", "status": "ok"|"warn"|"fail"|"skip", "title", "detail", "fix"?}.- The check ids:
setup,models.keeper,models.explorer,goose,models.test,voice,disk,timezone,calendars,addresses,firewall,certificate,devices.pinning,iroh,backups,restore,version.
GET /api/admin/plan answers {"steps": [Step], "next": id|null, "done": bool}. Each step is {"id", "title", "state": "done"|"todo"|"attention"|"optional"|"later", "detail", "command", "api"}. The step ids are
household, models, goose, voice, access, calendars, family, backups.
Setting up
Section titled “Setting up”POST /api/admin/setup, with the setup code:
{ "household": "The Smiths", "owner": "Alex", "timezone": "America/New_York", "device": "setup agent", "lan": true, "anywhere": true }It answers {"household", "owner", "token", "invite"}.
timezonedefaults to the computer’s.lan: trueturns on home-network access and makes its certificate before the invite, so the owner’s first invite carries the fingerprint.anywhere: trueturns on reaching it from anywhere, with the relay inrelay(Homefellow’s by default), so the first invite carries the server’s key. Ask the person first: it keeps a connection to a relay on the internet.- With
device, the caller is signed in as the owner.tokenis its device token. Treat it as a password. invitesigns the owner in on another device: give itsurlto the person.- It works once. After that it answers
409 conflict.
Models
Section titled “Models”POST /api/admin/models/discover{"hosts"?: [host], "urls"?: [url]}answers{"found": [Found], "recommendation"}.Foundis{"kind", "url", "models": [{"name", "billions"|null, "context"|null}]}. The recommendation is{"keeper", "explorer", "verdict": "good"|"maybe"|"too_small"|"unknown"|"none", "words"}.POST /api/admin/models/choosetakes one of{"keeper": Pick, "explorer"?: Pick},{"keeper_profile", "explorer_profile"?}or{"recommended": true, "hosts"?, "urls"?}. APickis{"url", "model", "api_key"?, "context"?}.POST /api/admin/models/testanswers{"verdict": "good"|"slow"|"too_small"|"failed", "words", "reading_seconds", "question_seconds", "found", "missed", "question", "at"}. It makes real model calls.
Access
Section titled “Access”GET /api/admin/access answers {"addresses": [Address], "primary", "lan", "mdns", "tailscale", "iroh", "firewall", "restart_needed"}.
Address:{"kind": "tailnet"|"public"|"mdns"|"lan"|"local", "url", "pinned"}, in the order the apps prefer.pinnedmeans it uses the server’s own certificate.firewall:{"manager", "ports", "state": "open"|"blocked"|"unknown"|"opened"|"none", "blocked", "words", "commands", "can_allow"}.POST /api/admin/access/lan{"on", "port"?, "mdns"?}: HTTPS onport(8788) after the next start.POST /api/admin/access/iroh{"on", "relay"?: "homefellow"|"n0"|"off"|"https://…", "port"?}: reaching it from anywhere after the next start.422 no_irohmeans this build has no iroh.POST /api/admin/access/tailscalerunstailscale serveand records thets.netaddress.422 tailscalesays what’s wrong.POST /api/admin/access/firewall{"opened"?: bool, "allow"?: bool}: record that the ports are open, or run the commands (only when the server runs as root).
Invites
Section titled “Invites”POST /api/admin/invites{"role"?, "name"?, "user"?}answers{"id", "code", "url", "join", "qr_svg", "expires_at", "role", "fingerprint"}.usersigns in another device for that person.- The link is
https://homefellow.org/join#hf1.<payload>, from the server’sserver.join_url(--join-url). The payload is base64url JSON:{"v": 1, "household", "code", "addresses": [Address], "fingerprint"?, "iroh"?: {"key", "relay"?, "addrs"?}}. The part after#never reaches a server, so homefellow.org never sees the invite. The page there tells a newcomer to install the app. The apps open these links directly. - The older form,
<address>/invite/<code>#hf1.<payload>(or<address>/invite/<code>alone), is still accepted everywhere. The server makes it whenserver.join_urlisoff, or when the payload has no address for other devices and noirohpart. GET /api/admin/inviteslists them, newest first, eachopen,used,expiredorrevoked. An invite’s code isn’t kept, so it can’t be shown again.
Backups
Section titled “Backups”GET /api/admin/backupsanswers{"dir", "keep", "daily_at", "backups": [{"name", "path", "bytes"}], "last_check", "restore", "last_restore", "restart_needed"}.PUT /api/admin/backups{"dir"?, "keep"?, "daily_at"?: "HH:MM"|"off"}.POST /api/admin/backups/runmakes one now.POST /api/admin/backups/check{"name"?}answers{"ok", "words", …}: whether it would restore.POST /api/admin/backups/restore{"name"}stages a restore for the next start, after checking the backup and backing up the household as it is now.DELETEcalls it off. See backups and restoring.
The rest of the server’s API, for the apps, is documented in docs/design/API.md in Homefellow’s source.
Free and open source. For families of every shape.homefellow.orgPrivacyFor AI assistants