LogiShell docs Open app

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

  1. Session. The browser cookie you get after signing in. This is the door for a person at a screen.
  2. 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.
  3. Both. Routes marked both accept 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 -->

prefixgateMCPwhat
/apipublicCatch-all for API paths this deployment does not serve: answers 503 not_deployed instead of the SPA shell.
/api/achievementssessionAchievements shelf and claims; the founder counter (/founders, /early) is public because the landing has no session.
/api/adminadminAdmin LOG: notes queue (/notes), founders list, the first hundred by invite (/first-hundred) and game publish tokens; the MCP owner door reads and closes notes through the same gate.
/api/admin/me (GET)publicAnswers whether the current session is an admin; an anonymous caller gets {admin:false}, not 401.
/api/agent-grantssessionRevocable links that hand one agent to another person; only the owner mints and revokes them.
/api/agent-guestguest-tokenThe receiving side of an agent grant: the token opens one agent on one machine, never /api/agents or the organization.
/api/agentssessionConversational agents shelf and their turns; no m2m on purpose, a turn spends on behalf of the owner.
/api/appspublicapi_getApps & Plugins registry: the public shelf reads without a sign-in, publishing needs a session, and a self or org release is invisible to anyone it was not meant for.
/api/artifact-docsbothapi_getArtifacts by link: a document an AI session hands to the caller (report, spec, criteria), kept with its earlier versions and opened at /artifact/<id> under their sign-in. Personal: the owner is part of the key, so an id from another account answers 404. GET lists and reads, POST creates, PUT writes a new version; the body holds up to 512 KB. Not the data map at /api/artifacts, which only looks.
/api/artifacts (GET)bothThe data map of the caller: one list of where their data physically lives, grouped by store, with the groups that have no inventory named rather than hidden. Read only by construction, the handler answers 405 to anything else.
/api/askbothapi_getQuestions to people and agents; which door answered decides whether you may answer your own question.
/api/assistantbothLOG assistant chat and durable turns (/turn); m2m lets the desktop cube ask without an IDE window open.
/api/authpublicBetter Auth endpoints (sign-in, session, OAuth); /providers lists what this door offers, mail routes are rate limited.
/api/auth/apple/notifications (POST)publicApple's server-to-server notices (consent revoked, Apple ID deleted, mail forwarding toggled). Public by necessity: the address lives in Apple's console and nothing can be added to it, so the JWT signature over Apple's own keys IS the gate.
/api/auth/handoff (POST)publicSign-in handoff to another cookie jar (desktop window): /start and /redeem work without a session by design.
/api/auth/handoff/approve (POST)sessionApproves a handoff code; only a signed-in session can do it, because that session is what gets handed over.
/api/billingsessionEntitlements bought with money: the plan price list reads without a sign-in like the compute price list, everything else belongs to the signed-in person.
/api/boardbothapi_getKanban board cards and columns; the owner m2m door lets MCP tools move cards.
/api/booksessionBook of rules: types, rules and handle for the person behind the cookie.
/api/bought-accesssessionThe list of model access bought from a seller (address, format, model, requests per minute), the same on every device of the caller. Never the key: a record with a key-like field is refused, keys stay in the vault. PUT writes one record, the later edit wins; DELETE leaves a tombstone so another device does not bring it back.
/api/calendarsbothExternal calendars: connect Google and Microsoft accounts read-only (several per person), come back from consent, disconnect. Connecting needs a signed-in browser; events land in /api/time.
/api/calendars/accountsbothapi_getConnected calendar accounts of the caller with their state (ok or needs_reauth) and last sync time; never tokens.
/api/canvasbothapi_getWhiteboard canvases, personal to the caller; m2m lets LOG draw without a browser.
/api/cardsessionThe QR business card of the signed-in person.
/api/channelbothPersonal publishing channel and its posts.
/api/cloudbothapi_getThe cloud member of the fleet: GET /capacity says whether a short lived Cloudflare machine can take a run now; POST /runs {ref, command, cwd?, timeoutSec?} clones that ref of LogiShell/Monorepo read only and runs one command; GET /runs/{id} reads status and the output tail, /stream follows it, DELETE stops it. The machine is destroyed when the command ends. Owner and admins only (the account pays); otherwise owner_only, and not_deployed when this deploy has no sandbox.
/api/connect/events (POST, OPTIONS)publicLOG Connect event door for @logishell/connect: a batch of log.action / log.error, accepted from a connected Origin, a body signed with the project server key, or localhost with a dev key; rate limited per project, submit only.
/api/consentsessionConsent records of the signed-in person.
/api/ctxbothShared memory: contexts, topics, sessions, companion; the runner writes run traces here with the owner m2m token.
/api/delivery (GET)adminDelivery of LogiShell itself: CI runs and releases mirrored into D1 by the pipeline, read by the Delivery surface. A user’s own repository runs come from their forge through the runner, not from here.
/api/device-tokenssessionMachine tokens of the signed-in person: list and revoke, read authoritatively past the cookie cache; the token itself is never shown, only its hash is stored.
/api/diagnostic (POST)publicDiagnostic report ingest from the desktop; no session, because the first breakages happen before sign-in.
/api/diskbothapi_getDisk storage next to repos, behind the same two doors as /api/repos.
/api/docssessionPublishing a document to a link (/d/<id>): the snapshot, its list and its revocation. Session only on purpose: making a text public is a decision of the person at the screen, not of a machine token.
/api/documentsbothapi_getDocs pages of desks without a project, personal to the caller: the cloud mirror that makes them visible on another device and in the web app.
/api/e (POST)publicProduct event ingest; a user id is attached only from a verified session, never from the body.
/api/errorspublicErrors caught automatically: surfaces post with the consent of the person and an optional session, owner machines post with the service bearer, a wrong bearer is a 401.
/api/feedback/embed (POST, OPTIONS)publicSubmit-only feedback widget door; the project id grants no read access and the Origin must be on the project allowlist.
/api/gamespublicGames showcase: the catalog is public, publishing needs the author Bearer publish token minted by an admin.
/api/github/starsessionTracks whether the signed-in person starred the repo.
/api/github/star/webhook (POST)webhook-hmacGitHub star webhook, verified with GITHUB_STAR_WEBHOOK_SECRET (sha256 HMAC).
/api/handwritten-notesbothHandwritten notes captured from paper and their recognized text.
/api/hostedsessionHosted services under run.logishell.com (Workers for Platforms): upload, list and remove the scripts of the signed-in person.
/api/integrationsbothConnected integrations of the caller (MCP servers, services) and their approvals.
/api/internalinternalNode workers: saved-link capture (claims, uploads, gc behind SAVED_LINK_WORKER_TOKEN) and the GitHub token of the owner linked account for CI keepers (POST /api/internal/github/token, service bearer only, bound repositories).
/api/interpretationsbothapi_getLibrary interpretations of saved links and notes.
/api/invitessessionInviting people: the owner mints and revokes invitations, the invitee reads which profile was set for them; the role gate sits inside.
/api/islandsessioniPhone Live Activity island: which machine to follow, searched across all spaces of the person.
/api/labssessionLabs: published labs are readable without a session, writes resolve the cookie authoritatively.
/api/landing-sessionpublicOne-bit credentialed CORS bridge for the landing: signed in or not, false for an anonymous visitor rather than 401.
/api/library/searchbothapi_getSearch across the Library of the caller.
/api/llmbothLLM 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)publicNames which brains this deployment offers and carries no secret.
/api/marketsessionCompute market orders of the signed-in person.
/api/mcp-appssessionOwn MCP servers of the signed-in person for apps on the canvas (LSH-631): connect by https address, list tools with their ui:// templates, call a tool, read a template; everything goes through the MCP gateway.
/api/mesessionWho am I and from which machine: account email and the name of the device token the request came with (lsh whoami).
/api/mediabothEvidence frames of QA proofs: named, previewed and searchable on a board card; the runner uploads them with the owner m2m token, the owner reads them, a stranger gets the same 404 as a made-up id.
/api/navigator/embed (POST, OPTIONS)publicLOG Navigator door for the embeddable bubble: one LOG turn over the marks the page sends; the project key grants no read access and the Origin must be on the project allowlist.
/api/netsessionNetwork graph of people and organizations around the caller.
/api/networksessionNetwork editorial: the public page of a subject and its publication, behind the same door as the profile.
/api/nodesbothapi_getPaired machines (device relay): list, pair, settings and proxy; approve, revoke and forget need owner or admin in an organization and are journaled (GET /audit, last 200); delivery control under /proxy/delivery needs the m2m door, a cookie is not enough. The live screen address of a machine is kept per person and machine (GET /live-screens, PUT and DELETE /{id}/live-screen): http and https only, never for a work zone.
/api/nodes/claim (GET, POST)publicClaiming a machine by QR: an unpaired machine asks for a code (start), polls for an owner (status), and accepts or declines the account a phone brought it. Public by necessity, the machine has no passport yet; held by a per-IP ceiling, a ten-minute TTL and a one-time code whose hash alone is stored. The phone half of the same door, GET and POST /claim/<code>, asks for a session itself.
/api/nodes/connect (GET)publicThe 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-sourcesbothSources of handwritten notes (scans, photos) and their upload.
/api/notesbothapi_getNotes and the why-journal; m2m lets the local MCP door record decisions.
/api/notificationsbothIn-app notifications: list, create and mark read; m2m acts as the deploy owner, so a service (admin probe, node-watch) can wake the devices of the owner.
/api/onboardingbothOnboarding links (/onboarding/<code>) and the rides through them. Split gate on purpose: creating, listing and revoking a link needs a session, while starting a ride and marking a step work without one, because at a stand the guest scans a QR before they are anybody. The lock on a ride is its unguessable id.
/api/orgssessionOrganizations of the signed-in person, served by the Network handler.
/api/profilesessionProfile of the signed-in person: what they show to others.
/api/pushbothWeb push: public key, subscribe and unsubscribe; behind the same two doors as the inbox, so the owner m2m reaches it too.
/api/recent-tabsbothapi_getRecently opened tabs of the caller, synced across surfaces.
/api/recordingsbothRun and screen recordings; the runner uploads them with the owner m2m token because a terminal process has no cookie.
/api/remindersbothapi_getReminders at a set moment: create one for an event or on its own, answer it (done, snooze, cancel) and set quiet hours. The moment itself is kept by a per-person clock, so nothing here depends on an open window.
/api/reposbothapi_getRepositories: tree, files and git, proxied to the repo service with the caller stamped in.
/api/roomsbothAgent rooms, the executing side of a topic; an agent without a browser enters with the owner m2m token.
/api/saved-linksbothapi_getSaved links of the Library: save, tag, open, retry capture and delete.
/api/searchsessionBuilt-in LogiShell Search of the browser tab; behind the session so it is not an open proxy from our domain.
/api/seenbothapi_getWhat this person has looked at: marks, the unseen queue, a check for agents.
/api/services/brainssessionOwner side of hosted brains: create, key and revoke; agents reach /brains/:id/mcp with a key the owner minted.
/api/session-sharessessionSharing a live terminal session: only a signed-in person mints and revokes, never the m2m owner token.
/api/sessionssessionDevice Center: the sessions of the signed-in person, read authoritatively from the database and revocable.
/api/sharepublicShare links to clips: GET peeks and POST redeems without any account, PUT (create) and DELETE (revoke) need a session.
/api/sharedsessionThe guest side of a shared session: the guest is a signed-in person with their own account, the token from the link is presented here.
/api/shared-agentssessionThe receiving side of an agent handed to an account: the session is the key, so there is no token to forward and no expiry to remember.
/api/slatebothapi_getLogbook pages (internal name Slate) and their artifacts.
/api/storesessionStore: listings, purchases and the earn-only $LSH ledger of the signed-in person.
/api/surfacesbothapi_getSurfaces composed from bricks, saved per caller.
/api/talksessionMessenger: connect, people, search, calls, room links and attachments (/files) for the signed-in person.
/api/talk/calls/status (GET)publicWhether this deployment can call (hub, rooms, attachments, ICE, relay); carries no secret, the UI hides dead buttons by it.
/api/talk/guestguest-tokenGuest by link into a call room; what the guest may do next is decided by the guest boundary in TalkHub.
/api/themessessionThemes shelf: browsing works without a session, applying and publishing answer 401 inside themesApi.
/api/timebothapi_getTime tracking entries of the caller.
/api/todobothapi_getPersonal todo list: cards of the same board table under the reserved todo address, never part of a board; GET lists, POST {title, kind?} adds one line (the palette door).
/api/vaultsessionPersonal vault proxied to the vault worker; the worker itself trusts only the stamp this gate adds.
/api/voicesessionVoice: realtime session tokens for the signed-in person.
/api/window-budgetssessionHow much of the owner subscription each person may spend, counted per provider window; only the owner reads and sets it.
/api/workbothapi_getAcceptance of AI work: submissions with evidence, read receipts, verdicts.
/api/workspace-linkssessionWhere the cloud copy of a working copy lives, per person instead of per browser; the bytes stay in repo-service.

Gates:

98 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.