slug, a lifecycle state, a declared_port the in-VM server listens on, a run_mode, an auth_mode, and a ready-to-open url. This guide covers listing a conversation’s surfaces, listing the whole workspace’s app catalog, minting a time-limited share link, switching a surface between private and public, and the delete / restore lifecycle.
All requests go to https://api.hq.zone and authenticate with a personal access token:
The endpoints in this guide carry these scopes: reads (listing a conversation’s surfaces, listing apps) require
conversations:read; every mutation (share, visibility, restore, delete) requires conversations:write.What a surface is
A surface is the live app row attached to a conversation. The list endpoints return these fields per surface:id— the surface id used by the share / visibility / restore / delete endpoints.slug— the URL slug for the app.state— the lifecycle state. Non-destroyed surfaces are listed; the states you will see includebooting,live,paused,archived. Adestroyedsurface is filtered out of every listing.declared_port— the port the app’s server is bound to inside the VM.run_mode—devorprod.auth_mode—signed_url(private) orpublic. This is the underlying column; the Apps list also exposes it as a derivedvisibilityofprivateorpublic.url— a ready-to-open, visitor-facing URL: the bare public URL whenauth_modeispublic, or a signed plain-host URL when it issigned_url.
There is no
visibility column on a surface. Visibility is derived from auth_mode: public maps to visibility public, and signed_url maps to visibility private.List a conversation’s surfaces
List conversation surfaces returns the live application surfaces attached to one conversation, excluding destroyed ones, ordered by most recent activity.List the workspace app catalog
List apps returns the workspace-wide catalog of persistent app surfaces, visible to any member of the workspace, excluding destroyed apps and ordered by most recent activity.apps array plus the workspace quota (max_persistent) and how many apps currently count against it (used). Each app includes id, slug, state, a derived visibility (public or private), run_mode, declared_port, backing_conversation_id (null if that conversation was deleted), a visitor-facing url, and created_at / last_activity_at as Unix-seconds timestamps:
The conversation-surfaces list is conversation-scoped (one thread’s apps); the Apps catalog is workspace-scoped (every member sees the same apps). Use the conversation list to embed the app a thread just built; use the catalog for a workspace-wide management view.
Mint a time-limited share link
Share a surface mints a time-limited signed URL you can paste into chat, email, or a doc without making the surface publicly visible. The surface stays private; the URL carries the token that lets a recipient in.Mint a link with the default TTL
Omit the body (or send an empty one) to get the default validity window of 7 days:The response is the surface
id, the tokenized url, and exp (the expiry as a Unix-seconds timestamp):The share link keeps the surface private — it does not flip
auth_mode. To open a surface to anyone with the bare URL, change its visibility instead (next section). A 404 from this endpoint means the surface was not found in your workspace.Change visibility
Set surface visibility flips a surface between private and public. The only accepted values areprivate and public; anything else returns a 400.
id, the resulting visibility, and the underlying auth_mode it maps to (private to signed_url, public to public):
Visibility can only be changed on a surface in a non-terminal state (
live, paused, or booting). If the surface is not found or is in a terminal state, the call returns 404.Delete and restore
An app surface can be put to sleep and woken back up, or torn down for good.Restore a paused app
Restore a surface wakes a paused app back to The response carries the surface A
live. Restore is app-only.id and an outcome describing what happened — already_live, restored, or in_progress:404 means the surface was not found in your workspace.Delete an app
Delete a surface stops the app and releases its resources, flipping the surface to a destroyed state.The response carries the surface A
id and an outcome — destroyed (this call did the teardown) or already_destroyed (it was already gone, so the call is a no-op):404 means the surface was not found in your workspace.Delete is permanent: a destroyed surface is filtered out of every listing and cannot be restored — restore rejects surfaces in a terminal state (publish a fresh app instead). A non-admin caller must participate in the surface’s backing conversation; a workspace admin may delete any app in the workspace.