grithdocs

API overview

Where the daemon binds, how each route is authorised, the rate-limit buckets, and what an error body looks like.

The daemon serves its HTTP API on http://127.0.0.1:3141, loopback only. Start it with grith daemon start.

Shape of the surface

Every REST route is nested once under /api. The WebSockets are not - they sit at the root, at /ws/live and /ws/supervisor/{id}. Paths are written {id} here; the router uses axum's :id internally.

Three authorisation tiers

TierRoutesWhat you send
Open read/api/health, /api/tier, /api/license/status, /api/proxy/status, /api/onboarding/status, /api/sync/status, /api/notifications/channels, /api/notifications/statusNothing. Never token-gated.
Sensitive read/api/digest, /api/canaries, /api/audit*, /api/config, /api/analytics/v2/*, /api/policies*, /api/sync/configs, /api/inventory/{id}, /api/sessions/{id}/listener-rewritesx-grith-csrf: <dashboard token>, once a token exists.
WriteEvery dashboard POST, PUT and DELETEx-grith-csrf: <dashboard token>.

The five /api/supervisor/* routes take both layers: the token on every method, the CSRF header on the three mutations. The daemon IPC routes are a separate surface entirely, on a bearer token - see Daemon IPC.

Three writes carry their own proof instead and skip the CSRF layer: POST /api/digest/{id}/webhook-review (single-use nonce), POST /api/server/shutdown (daemon bearer token) and POST /api/dashboard/pair (the pairing code itself).

Open does not mean free. GET /api/sync/status and the two /api/notifications reads take no token but still return 403 FEATURE_GATED on Community - the gate is inside the handler. See Notifications.

Full details on the secrets and the pairing flow are on Authentication.

Rate limits

Each bucket is a sliding one-second window, counted after the auth layers, so an unauthenticated request never spends your quota.

BucketRequests per secondApplies to
General100Open reads, sensitive reads, supervisor GETs
Write10Every dashboard write
ProxyTest20POST /api/proxy/test
Ipc10000The daemon IPC routes

The first three are configurable under [server.rate_limit]; ipc_rps is not exposed in config. Over the limit is 429 with a Retry-After header and a body whose code is RATE_LIMITED.

Error bodies

Most failures are a two-field envelope of error and code. A tier refusal is 403 and carries enough to render an upgrade prompt:

403 FEATURE_GATED
{
"error": "usage_analytics requires a Pro subscription",
"code": "FEATURE_GATED",
"feature": "usage_analytics",
"current_tier": "community",
"required_tier": "Pro",
"upgrade_url": "https://grith.ai/pricing"
}

upgrade_url is the licence's billing portal when one is known, otherwise https://grith.ai/pricing. The analytics routes add one status of their own: 503 ANALYTICS_UNAVAILABLE, returned when the process holding the audit database is an older grith and cannot serve the projection.

Binding beyond loopback

server.localhost_only defaults to true and a non-loopback peer gets 403 LOCALHOST_ONLY. The daemon refuses to start if you turn it off without also setting an API key. Native TLS is available under [server.tls]; see Server config and Reverse proxy and TLS.

Where to go next

Last updated: 2026-08-24Edit this page on GitHub →