HTTP API and its gates
Everything under /api/* on app.logishell.com is served by one worker.
The table below is not written by hand: it is rendered from the route
registry that lives next to the code (apps/ui/src/routes.manifest.ts), and
a test fails the build when the worker routes on a path the registry does
not know. Prefixes, not every route: /api/repos also covers
/api/repos/<id>/tree. A path belongs to the longest prefix that covers it,
so /api/llm/status is public while /api/llm/complete is not.
Three ways in
- Session. The browser cookie you get after signing in. This is the door for a person at a screen.
- Owner machine token.
Authorization: Bearer <APP_M2M_TOKEN>. There is one token per deployment and it always acts as the deployment owner; a wrong bearer is a 401, never a silent fall back to the cookie. - Both. Routes marked
bothaccept either: a bearer when one is presented, the session otherwise. This is how the runner on your machine, the LOG cube on the desktop and the owner MCP door reach the same API.
The owner MCP door talks to this API with the machine token, so it
sees exactly the groups marked m2m, both and admin. The personal MCP
door runs inside the same worker and calls the handlers directly with the
identity of your OAuth token; there is no fourth way in.
Route groups
<!-- api-doc:start -->
| prefix | gate | what |
|---|---|---|
/api | public | Catch-all for API paths this deployment does not serve: answers 503 not_deployed instead of the SPA shell. |
/api/achievements | session | Achievements shelf and claims; the founder counter (/founders, /early) is public because the landing has no session. |
/api/admin | admin | Admin LOG: notes queue (/notes), founders list and game publish tokens; the MCP owner door reads and closes notes through the same gate. |
/api/admin/me (GET) | public | Answers whether the current session is an admin; an anonymous caller gets {admin:false}, not 401. |
/api/agent-grants | session | Revocable links that hand one agent to another person; only the owner mints and revokes them. |
/api/agent-guest | guest-token | The receiving side of an agent grant: the token opens one agent on one machine, never /api/agents or the organization. |
/api/agents | session | Conversational agents shelf and their turns; no m2m on purpose, a turn spends on behalf of the owner. |
/api/ask | both | Questions to people and agents; which door answered decides whether you may answer your own question. |
/api/assistant | both | LOG assistant chat and durable turns (/turn); m2m lets the desktop cube ask without an IDE window open. |
/api/auth | public | Better Auth endpoints (sign-in, session, OAuth); /providers lists what this door offers, mail routes are rate limited. |
/api/auth/handoff (POST) | public | Sign-in handoff to another cookie jar (desktop window): /start and /redeem work without a session by design. |
/api/auth/handoff/approve (POST) | session | Approves a handoff code; only a signed-in session can do it, because that session is what gets handed over. |
/api/board | both | Kanban board cards and columns; the owner m2m door lets MCP tools move cards. |
/api/book | session | Book of rules: types, rules and handle for the person behind the cookie. |
/api/canvas | both | Whiteboard canvases, personal to the caller; m2m lets LOG draw without a browser. |
/api/card | session | The QR business card of the signed-in person. |
/api/channel | both | Personal publishing channel and its posts. |
/api/consent | session | Consent records of the signed-in person. |
/api/ctx | both | Shared memory: contexts, topics, sessions, companion; the runner writes run traces here with the owner m2m token. |
/api/diagnostic (POST) | public | Diagnostic report ingest from the desktop; no session, because the first breakages happen before sign-in. |
/api/disk | both | Disk storage next to repos, behind the same two doors as /api/repos. |
/api/e (POST) | public | Product event ingest; a user id is attached only from a verified session, never from the body. |
/api/feedback/embed (POST, OPTIONS) | public | Submit-only feedback widget door; the project id grants no read access and the Origin must be on the project allowlist. |
/api/games | public | Games showcase: the catalog is public, publishing needs the author Bearer publish token minted by an admin. |
/api/github/star | session | Tracks whether the signed-in person starred the repo. |
/api/github/star/webhook (POST) | webhook-hmac | GitHub star webhook, verified with GITHUBSTARWEBHOOK_SECRET (sha256 HMAC). |
/api/handwritten-notes | both | Handwritten notes captured from paper and their recognized text. |
/api/integrations | both | Connected integrations of the caller (MCP servers, services) and their approvals. |
/api/internal | internal | Saved-link capture worker on the node: claims, uploads and gc behind SAVEDLINKWORKER_TOKEN. |
/api/interpretations | both | Library interpretations of saved links and notes. |
/api/island | session | iPhone Live Activity island: which machine to follow, searched across all spaces of the person. |
/api/labs | session | Labs: published labs are readable without a session, writes resolve the cookie authoritatively. |
/api/landing-session | public | One-bit credentialed CORS bridge for the landing: signed in or not, false for an anonymous visitor rather than 401. |
/api/library/search | both | Search across the Library of the caller. |
/api/llm | both | LLM facade: complete, stream, routed and platform completions, usage and gateway receipts; the brain, keys and limits are chosen on the server. |
/api/llm/status (GET) | public | Names which brains this deployment offers and carries no secret. |
/api/market | session | Compute market orders of the signed-in person. |
/api/net | session | Network graph of people and organizations around the caller. |
/api/network | session | Network editorial: the public page of a subject and its publication, behind the same door as the profile. |
/api/nodes | both | Paired machines (device relay): list, pair, settings and proxy; delivery control under /proxy/delivery needs the m2m door, a cookie is not enough. |
/api/nodes/connect (GET) | public | The machine door: a headless node dials out with its pair code or per-device token in X-LB-Node-* headers, no cookie exists. |
/api/note-sources | both | Sources of handwritten notes (scans, photos) and their upload. |
/api/notes | both | Notes and the why-journal; m2m lets the local MCP door record decisions. |
/api/notifications | session | In-app notifications: list, create and mark read. |
/api/orgs | session | Organizations of the signed-in person, served by the Network handler. |
/api/profile | session | Profile of the signed-in person: what they show to others. |
/api/push | session | Web push: public key, subscribe and unsubscribe for the signed-in browser. |
/api/recent-tabs | both | Recently opened tabs of the caller, synced across surfaces. |
/api/recordings | both | Run and screen recordings; the runner uploads them with the owner m2m token because a terminal process has no cookie. |
/api/repos | both | Repositories: tree, files and git, proxied to the repo service with the caller stamped in. |
/api/rooms | both | Agent rooms, the executing side of a topic; an agent without a browser enters with the owner m2m token. |
/api/saved-links | both | Saved links of the Library: save, tag, open, retry capture and delete. |
/api/search | session | Built-in LogiShell Search of the browser tab; behind the session so it is not an open proxy from our domain. |
/api/services/brains | session | Owner side of hosted brains: create, key and revoke; agents reach /brains/:id/mcp with a key the owner minted. |
/api/sessions | session | Device Center: the sessions of the signed-in person, read authoritatively from the database and revocable. |
/api/share | public | Share links to clips: GET peeks and POST redeems without any account, PUT (create) and DELETE (revoke) need a session. |
/api/slate | both | Slate documents and their artifacts. |
/api/store | session | Store: listings, purchases and the earn-only $LSH ledger of the signed-in person. |
/api/surfaces | both | Surfaces composed from bricks, saved per caller. |
/api/talk | session | Messenger: connect, people, search, calls, room links and attachments (/files) for the signed-in person. |
/api/talk/calls/status (GET) | public | Whether this deployment can call (hub, rooms, attachments, ICE, relay); carries no secret, the UI hides dead buttons by it. |
/api/talk/guest | guest-token | Guest by link into a call room; what the guest may do next is decided by the guest boundary in TalkHub. |
/api/themes | session | Themes shelf: browsing works without a session, applying and publishing answer 401 inside themesApi. |
/api/time | both | Time tracking entries of the caller. |
/api/vault | session | Personal vault proxied to the vault worker; the worker itself trusts only the stamp this gate adds. |
/api/voice | session | Voice: realtime session tokens for the signed-in person. |
Gates:
public: no sign-insession: signed-in browser session (cookie)m2m: owner machine token (Bearer APPM2MTOKEN), identity from M2MOWNEREMAILboth: session or owner m2madmin: ADMIN_EMAILS or owner m2minternal: service binding / internal secretguest-token: per-link guest tokenwebhook-hmac: HMAC-signed webhook
66 groups. A path belongs to the longest prefix that covers it. <!-- api-doc:end -->
Not on this page
Routes outside /api (/healthz, /mcp, /.well-known/*), an OpenAPI
document and per-route methods. Those come with the next step of the same
slice.