Filter API
The filter’s API is on port 8091, reached on the LAN or over Tailscale (see
Away from home). Every route except
/api/health, /ca.pem and /ca.mobileconfig needs Authorization: Bearer <token>:
either state/api_token (Family Filter for Mac’s) or a parent phone’s own token.
Phone tokens are kept as hashes in state/tokens.json, and made with
filter/scripts/filter-token.sh add "<whose iPhone>". That puts the new token on
the clipboard rather than printing it. list and remove <id> revoke one
without touching the others.
Health and certificate
Section titled “Health and certificate”| Route | |
|---|---|
GET /api/health |
{ok, version, rules, uptime, paused, you: {ip, listed, off, filtered}}. No token needed; you is the asking address |
GET /ca.pem, GET /ca.mobileconfig |
The certificate, plain or as a profile |
Rules, never blocked, pass-through
Section titled “Rules, never blocked, pass-through”| Route | |
|---|---|
GET /api/rules, POST /api/rules {pattern, note}, DELETE /api/rules/<id> |
Block rules. A URL or a domain; 400 if it isn’t one |
GET /api/allow, POST /api/allow {pattern, note}, DELETE /api/allow/<id> |
Never blocked: same shape and matching |
GET /api/check?url= |
{blocked, allowed, beaten, passthrough}: what blocks this URL, or what lets it through and the block it beat |
GET /api/passthrough |
{builtin, intercepted, manual, auto} |
POST /api/passthrough {host, note}, DELETE /api/passthrough/<host> |
Manual pass-through. Deleting an automatic one retries decrypting it |
Log and alerts
Section titled “Log and alerts”| Route | |
|---|---|
GET /api/log?since=&kind=&limit= |
Log entries. kind is visit, blocked, allowed, passthrough or a focus-… kind, comma-separated. Default the last day, at most 2000 |
GET /api/alerts |
{cert_lost: [{client, device, since, hosts}], paused} |
GET /api/tunnel?since=&until= |
{devices, covered, active}: when each tunnel carried traffic. Default the last 8 days, at most 32 |
A log entry is {time, kind, client, device, url, rule?, status?, page?}. Visits
also have ua (the user agent, which says which app), dest and user (a
person clicked or typed, rather than a tab reloading by itself). Visits are
top-level page loads only, not every image and script.
Off switches
Section titled “Off switches”| Route | |
|---|---|
GET /api/pause, POST /api/pause {minutes}, DELETE /api/pause |
The whole filter. minutes null means until switched back on. by records which token switched it off |
GET /api/devices, POST /api/devices/<ip>/off {minutes}, DELETE /api/devices/<ip>/off |
One device |
GET /api/clients |
The devices from clients.txt |
Focus Mode
Section titled “Focus Mode”| Route | |
|---|---|
GET /api/focus |
{sets, windows, pauses, ondemand} |
PUT /api/focus/sets |
Replace the block sets: [{id?, name, patterns, note, allowance?}] |
POST /api/focus/sets/<id>/patterns {pattern, by?} |
Add one site or page to one set, safely alongside other clients |
PUT /api/focus/windows |
Replace the scheduled windows: [{id?, name, rules: [{set, mode, minutes}], days, start, end, all_day, from?, to?, button, enabled}]. mode is block, limit or open |
PUT /api/focus/pauses |
Replace the days off: [{id?, from, to?, note, sets}] |
GET /api/focus/now |
What’s blocking now, the limits and allowances on now, exceptions, windows started on demand, and scheduled windows ended early |
GET /api/focus/sessions, POST /api/focus/sessions |
Start a window now (its rules), or block sets, for minutes or until a time (at most a day) |
POST /api/focus/sessions/<id>/extend, DELETE /api/focus/sessions/<id> |
Extend one started on demand, or end any window’s run now |
GET/POST /api/focus/exceptions, DELETE /api/focus/exceptions/<id> |
Temporary allow or block, at most a day |
GET /api/focus/limits, POST /api/focus/limits/<id>/grant |
Time limits on now; more time |
GET /api/focus/allowances, POST /api/focus/allowances/<set>/add, POST/DELETE /api/focus/allowances/<set>/open |
Allowances today; more time today; open now |
GET /api/focus/done?since= |
“I’m done” presses |
POST /api/focus/done/ack {ids, by} |
Acknowledge presses |
POST /api/focus/done/<id>/end |
Let the child off: end the window the press came from |
The full request and response shapes are in the source.
Source: filter/README.md