Skip to content
Browse docs

HTTP API reference

The service route inventory for health, public content, reviews, workbench records, comments, authentication, and MCP.

On this page

Scope and access#

The HTTP API is the service layer used by the browser, CLI, and MCP transports. Prefer those supported clients unless you are implementing an integration.

Public website routes never read the private project store. Review reads follow service sign-in and record visibility. Browser writes use a signed-in session. Personal CLI tokens identify their user. Machine tokens are for controlled automation. The direct hosted MCP accepts its own OAuth bearer token.

Paths below use :project, :ref, :id, and :action as placeholders. JSON request contracts and revision rules are enforced by the server; read the calling CLI or client source before issuing mutations directly.

Health and packages#

  • GET /healthz checks process liveness and reports the deployed version. On the hosted platform, an external frontend may own this path; use readiness from outside.
  • GET /readyz checks that service storage is writable and reports the deployed version.
  • GET or HEAD /mockspace-cli.tgz downloads the stable self-updating launcher.
  • GET or HEAD /mockspace-cli-:version.tgz downloads the immutable full CLI package for the current deployed version. Other versions return 404.
  • GET or HEAD /static/:file serves allowlisted site CSS, JavaScript, fonts, and icons from one flat static directory.

Public website#

  • GET or HEAD / renders the shared workspace with installation and onboarding. Authorized readers see their visible projects and drafts; signed-out visitors to a private service see the example and a sign-in entry. The response is never cached.
  • GET or HEAD /index.html redirects the old desk bookmark to /, preserving its query.
  • GET or HEAD /docs/ and /docs/:slug render the published documentation catalogue.
  • GET or HEAD /docs/search returns the public docs search index as JSON.
  • GET or HEAD /blog/ and /blog/:slug render published articles.
  • GET or HEAD /agent-guide.md returns the published agent guide as plain Markdown without front matter.

Unknown docs and blog entries return 404. Draft catalogue entries are never returned to renderers or search.

GET or HEAD /new-project supplies authenticated MCP connection commands and an agent prompt for registering a project and preparing its first review. Opening the page does not create or publish a project. Anonymous requests do not load the project catalogue, and all responses use no-store.

Browser pages behind the read gate#

  • GET or HEAD /app is the compatible entry to the same workspace as /, retaining its read gate.
  • GET or HEAD /get-started opens the compatibility guide.
  • GET or HEAD /releases renders internal release notes.
  • GET or HEAD /w/:project redirects the legacy workbench URL.
  • GET or HEAD /:project opens that product's workbench.
  • GET or HEAD /:project/chats opens its conversation index.
  • GET or HEAD /:project/drafts opens its build and draft index.

These route families remain protected even though similarly named /docs and /blog paths are public.

Projects and builds#

  • GET /api/projects lists projects and latest visible builds.
  • GET /api/builds?project=:project lists visible builds and refs for one project.
  • POST /api/builds publishes a validated tar archive using a personal or machine credential.
  • POST /api/builds/merged records whether a pull-request build merged. It requires a machine token.
  • POST /api/builds/rename renames a review for an authorized write actor.
  • POST /api/builds/visibility changes a draft between private and project visibility. It requires the owner, a machine token, or explicitly enabled local write.
  • DELETE /api/builds/:project/:id deletes one immutable build and requires a machine token.

Build IDs are immutable and content-addressed. Branch and latest refs are mutable pointers. Ref responses use no-store caching, an entity tag, and X-Mockspace-Build so a browser does not combine files from different builds.

Review documents and comparison#

  • GET or HEAD /p/:project/ lists published reviews for a project.
  • GET or HEAD /p/:project/compare opens a comparison between refs.
  • GET or HEAD /p/:project/:ref/* opens a review or serves one of its immutable files, subject to build visibility.
  • GET or HEAD /p/:project/:ref/ai-view reads the current agent focus marker.
  • POST /p/:project/:ref/mcp calls the legacy read-only MCP bound to one build. It uses the ordinary read gate and visibility rules.
  • Any method under /p/:project/app/* proxies the configured running prototype for an authorized reader.
  • GET /api/diff?project=:project&to=:ref&from=:ref compares two builds. Add frame=:frame for a word-level delta of one frame.
  • GET /api/prototype?project=:project returns the allowed same-origin running-app proxy for the workbench.

Presence and comments#

  • GET /api/presence/:project/:ref opens a server-sent event stream for signed-in reviewers in a deck.
  • POST /api/presence/:project/:ref updates a signed-in reviewer's current camera and selection.
  • GET /api/comments lists comments for a visible review.
  • POST /api/comments adds a comment or pin for an authorized write actor.
  • POST /api/comments/update edits, resolves, or reopens a comment. Comment words remain author-owned.
  • POST /api/comments/delete deletes an author-owned comment.

Presence represents signed-in people, not CI or MCP agents. A pin is stored relative to a nearby frame when possible so it survives zoom and layout changes.

Workbench reads and events#

  • GET /api/workbench?project=:project returns visible requests, messages, agent session mode, and preview state.
  • GET /api/workbench/events?project=:project&after=:sequence streams replayable request, message, and preview events. Last-Event-ID can also resume the cursor.
  • POST /api/workbench/messages appends a conversation message. Browser user messages use a session; agent or system roles require a machine token, and explicitly enabled local writes are limited to the local workbench mode.

Messages and events are durable. Advancing an event cursor does not delete or acknowledge the underlying message.

Automatic work#

  • GET /api/workbench/queue lists the requests the caller may start now, in the service's order. It can be scoped with ?project=, long-polled with &wait=0-25 and resumed with &after=:cursor. Entries carry ids, statuses, urgency and times, never request text.
  • POST /api/design-requests/:project/:id/dispatch takes {action: "acquire" | "renew" | "release"} and manages the lease that gives one run a request. Conflicts are 409 with a code: DISPATCH_HELD, DISPATCH_LOST, NOT_ELIGIBLE, RETRY_LIMIT or PROJECT_BUSY.
  • POST /api/design-requests/:project/:id/resume records a new run's workspace and branch on work another run left mid-status. Only the run holding the lease may call it.
  • POST /api/design-requests/:project/:id/urgency sets low, normal, high or urgent. The owner may choose among the first three; urgent and other people's requests need the review role.
  • POST /api/workers/heartbeat reports a worker's health, keyed by the authenticated principal. GET /api/workers lists every record and requires a machine token.

Once a request has been dispatched, agent-side writes must name its current run (x-mockspace-run-id or run_id). Anything else is 409 RUN_SUPERSEDED. See docs/REVIEW-AUTOMATION.md in the repository for the full contract.

Local agent connections and activity#

These records connect a local Codex or Claude Code conversation to a published review. They are separate from the hosted automation lease and do not require a web chat.

  • GET /api/agent-sessions?project=:project lists the current identity’s sessions for accessible reviews. Responses use no-store.
  • GET /api/agent-sessions/:project/:id reads that agent’s saved session and recovery (exact review URL, terminal command and MCP prompt). Reading never changes a connection.
  • POST /api/agent-sessions/:project/:id/restore takes expected_version, equal to the saved connection_version. It reopens the same session and increments that version, preserving history and browser binding. A competing recovery returns 409 rather than overwriting the winner.
  • POST /api/agent-sessions connects an agent with project, build, and provider (codex, claude, or other); label, summary, and context_id are optional. A browser context must belong to the same identity and project. Ownership comes from the authenticated identity.
  • POST /api/agent-sessions/:project/:id/activity records status (working, waiting, done, or error) and summary. Optional components and files identify reported changes; frame or flow identifies the work area. An optional build moves the session to another accessible published version. View-only updates may omit status and summary and send navigation fields with connection_version instead.
  • POST /api/agent-sessions/:project/:id/disconnect ends contact for an owned session and retains its history.

After REST recovery, send the returned connection_version with activity reports and expected_version with disconnect requests. Older or omitted versions return 409. MCP supplies the version from its own connection; one MCP conversation cannot report to or disconnect another agent. Recovery needs the same account and access to the saved review. It does not restore terminal processes or chat transcripts.

Mutation responses contain session. Its events record progress in chronological order. The connected field reflects recent contact, not independent proof of a running local process. Sessions and activity are private to their owner; knowing a session ID does not grant access. Canonical target identifiers must exist in the selected build. These endpoints accept supported authenticated identities or explicitly enabled local development access, never anonymous remote writes.

For view control, view accepts all (All screens), diff (Changes), or live (Prototype/Live app); prototype is normalized to live. Optional fit accepts screen with a supplied or retained frame, or flow with a supplied or retained frame or flow. Send only one of frame and flow. Use fit: null to clear a saved fit.

Every view-only update requires the owned session’s current connection_version, including before its first restore. The session must be connected and its build accessible. For example, POST this JSON to /api/agent-sessions/my-app/agent_returned-id/activity, substituting the project, session ID and version returned by the service:

{ "connection_version": 1, "view": "all" }

This mode-only update preserves the saved target, fit, work status, summary, files and components. The returned session.focus holds the view selection; a view history entry records the change. Omitted navigation fields preserve saved values, and retained targets must exist if build changes. Unknown modes or targets are rejected. Stale versions, expired/disconnected sessions, and unavailable modes return 409; another owner cannot write the session.

Changes needs a draft with a visible recorded comparison and detected changes. Live view needs the project’s configured app; callers cannot provide a URL or script. View updates require view permission, while work progress requires request permission. The browser applies updates only when the user selects that connection in Agents and enables Follow agent. Manual navigation stops following. The corresponding MCP tool is `set_agent_view`.

Browser context for agents#

  • GET /api/browser-contexts lists only the current identity’s recent, accessible contexts. Optional project limits the result. Responses use no-store.
  • POST /api/browser-contexts publishes a tab’s context using id, project, build, active, and monotonically increasing sequence; optional view, frame, or flow identifies the work area. The server validates targets and constructs the exact review URL. An existing context cannot switch projects.
  • DELETE /api/browser-contexts/:id removes that identity’s shared context.

Focus records are temporary and carry timestamps and freshness. Late writes cannot replace a newer position. An inactive or expired context is not a current user instruction, and the service does not copy focus from another tab into a linked connection. Each agent session may bind to a separate context. These endpoints use the same identity and local-access boundary as agent sessions; identifiers alone grant no access.

Hosted workbench agent sessions#

  • POST /api/workbench/session/attach opens the agent liveness lease and requires a machine token.
  • POST /api/workbench/session/heartbeat renews a lease. An expired lease returns a conflict and must be attached again.
  • POST /api/workbench/session/detach closes the lease.

The lease determines whether the workbench reports live or queued. A remembered preview URL is not proof that an agent is active.

Design requests#

  • POST /api/design-requests creates a durable request with a browser session, machine token, or explicitly enabled local write.
  • POST /api/design-requests/:project/:id/candidates offers a published candidate build to an authorized request actor.
  • POST /api/design-requests/:project/:id/choose records the selected candidate.
  • POST /api/design-requests/:project/:id/transition advances a request with its expected revision and correlated evidence.
  • POST /api/design-requests/:project/:id/approve moves an approved refined request into the execution queue.
  • POST /api/design-requests/:project/:id/visibility changes request visibility and requires its owner or a machine token.
  • POST /api/design-requests/:project/:id/worked records agent liveness and optional current frame.
  • POST /api/design-requests/:project/:id/activity sets ephemeral agent activity text and requires a machine token.
  • POST /api/design-requests/:project/:id/stop asks an active agent to pause. The request owner, a machine token, or explicitly enabled local writer may issue it.

Requests are private by default and use revisions to prevent two actors from silently overwriting state. The supported mockspace workbench commands encode this lifecycle and are safer than hand-written mutations.

Bug reports are an explicit shared-request entry point. An admin enables bug_reports.enabled in project settings, then a signed-in member with request permission can use /:project/report. The page discloses the project-member audience and submits to the same request endpoint with visibility:"project", a nonempty idempotency key, and source:{"kind":"bug_report","severity":"major"} (severity can also be minor or critical). Optional base and target:{build,frame} must identify visible, project-shared context; private captures are rejected. GET /api/projects/:project/report-context?build=latest&frame=<frame-id> resolves that context to an immutable build. Normal project automation and human review rules apply; reporting does not require Slack or an active runner.

Candidate attachment changes build metadata. A human caller needs request permission and must own the candidate build; for a publication without an owner, its verified publisher supplies that authority. A teammate’s build is rejected even when it is project-visible. To attach your private candidate to your own shared request, send { "build": "<build-id>", "share": true }; omitting explicit sharing returns 409. This cannot share a private candidate through somebody else’s request. Human attachment preserves the candidate’s owner. Trusted machine execution retains its request audience assignment; automated review projects require the runner to offer candidates.

Browser and CLI sign-in#

  • Any method on /auth/login, /auth/callback, and /auth/logout starts, completes, or clears the browser sign-in flow as appropriate.
  • GET /auth/cli/start starts a CLI authorization and returns the browser destination and verifier-bound session.
  • POST /auth/cli/approve approves the CLI identity from a signed-in browser session.
  • POST /auth/cli/token exchanges a one-time code and PKCE verifier for a personal CLI token.

CLI callback destinations are restricted to HTTP loopback. Codes expire quickly, can be exchanged once, and are held in process memory.

Hosted MCP and OAuth#

  • POST /mcp initializes a Streamable HTTP session and handles MCP JSON-RPC requests.
  • DELETE /mcp ends the named MCP session. GET /mcp is not supported because the service sends no server-initiated notifications.
  • GET /.well-known/oauth-protected-resource describes the protected hosted MCP resource.
  • GET /.well-known/oauth-authorization-server describes the service authorization endpoints.
  • POST /oauth/register performs rate-limited dynamic MCP client registration.
  • GET or POST /oauth/authorize obtains consent through a signed-in browser.
  • POST /oauth/token exchanges an authorization code and verifier, or a refresh token, for an OAuth bearer token.

Anonymous hosted MCP calls receive 401 with a WWW-Authenticate challenge. The direct hosted token is not the same credential as a CLI personal login or machine write token.

Error and method behavior#

Unsupported methods return 405 and name the allowed methods. Protected browser navigation receives the sign-in experience, while programmatic calls receive JSON errors. A private record hidden from the current identity can return 404 even when its ID exists.

For credential choices and visibility behavior, read Authentication. For supported command-line clients, read the CLI reference.