How do I manage apps through the API?
http://localhost:3001 Apps are extensions of type app stored in ~/.daemion/apps/<name>/. Apps are Vite projects — not raw HTML files. Two subtypes (fullstack and interactive) run a Vite dev server managed by the gateway. The runtime API lets you start, stop, restart, and check status on those dev servers, and access the running app through a built-in dev proxy.
How do I check an app’s runtime status?
Return the current runtime state for a named app.
curl “http://localhost:3001/apps/my-dashboard/status”
-H “Authorization: Bearer $DAEMION_TOKEN”
Response shape:
{ “status”: “running”, “port”: 5173, “pid”: 84201, “subtype”: “interactive” }
Possible status values: running, stopped, crashed, starting. port and pid are null when not running.
How do I start an app’s dev server?
Start the Vite dev server for an app. Only works for fullstack and interactive subtypes.
curl -X POST http://localhost:3001/apps/my-dashboard/start
-H “Authorization: Bearer $DAEMION_TOKEN”
Response on success:
{ “status”: “running”, “port”: 5173, “pid”: 84201 }
The gateway allocates a port from the range 5173–5273, waits up to 5 seconds for Vite to signal readiness, then returns. If the dev server is already running, it is stopped first before restarting.
Only apps with subtype fullstack or interactive have a dev server. Calling start on other subtypes returns 400 {“error”: “<subtype> apps do not use a dev server”}.
How do I restart an app’s dev server?
Stop and restart the Vite dev server for an app. Only works for fullstack and interactive subtypes.
curl -X POST http://localhost:3001/apps/my-dashboard/restart
-H “Authorization: Bearer $DAEMION_TOKEN”
Returns the same shape as /start: { "status": "running", "port": 5173, "pid": 84201 }.
How do I stop an app’s dev server?
Stop the running Vite dev server for an app.
curl -X POST http://localhost:3001/apps/my-dashboard/stop
-H “Authorization: Bearer $DAEMION_TOKEN”
Returns { "status": "stopped" }. The gateway sends SIGTERM and waits up to 3 seconds; if the process has not exited by then, it sends SIGKILL.
How do I access a running app remotely?
Proxy requests to the app's running Vite dev server. Allows remote clients (phone, tablet) to access the app through the gateway without exposing the dev server port directly.
Fetch the app root
curl “http://localhost:3001/apps/my-dashboard/dev/“
Fetch a specific asset
curl “http://localhost:3001/apps/my-dashboard/dev/src/main.tsx”
The gateway forwards the request to http://127.0.0.1:<port>/<path> with a 10-second timeout. Query strings are preserved. The response content type and status code are passed through unchanged.
The dev proxy endpoint does not require a bearer token. This allows the Daemion mobile app to render apps without embedding credentials in asset requests. The dev server itself is bound to 127.0.0.1 and is not directly accessible remotely.
How does the proxy allowlist work?
Some apps fetch external data at runtime. The gateway includes a CORS proxy at GET /apps/:name/proxy?url=<target> that forwards HTTPS requests on behalf of the app. Only origins listed in data/.proxy-allowlist are permitted — one origin per line. The file is re-read on every request, so you can add origins without restarting the gateway.
Add an origin to the allowlist
echo “https://api.github.com” >> data/.proxy-allowlist
Proxy a request through the gateway
curl “http://localhost:3001/apps/my-dashboard/proxy?url=https://api.github.com/repos/octocat/hello-world”
-H “Authorization: Bearer $DAEMION_TOKEN”
The proxy only permits HTTPS targets. HTTP URLs return 403.
fullstack and interactive. Apps with other subtypes (e.g. html) are served statically from disk — they do not have a runtime process to start or stop.~/.daemion/apps/<name>/. The gateway looks for a local node_modules/.bin/vite binary first; if absent, it falls back to npx vite.crashed. Call POST /apps/:name/restart to bring it back up. The gateway logs the exit code.What can go wrong
404 {"error": "app not found", "name": "..."} — No app extension with that name exists in the database. Register the app as an extension first (type app).
400 {"error": "html apps do not use a dev server"} — Start/stop/restart only apply to fullstack and interactive subtypes. Check the app’s subtype field via /apps/:name/status.
500 {"error": "Failed to start: ..."} — Vite failed to launch. Common causes: missing node_modules (run npm install in the app directory), missing vite.config.ts, or no available port in the 5173–5273 range.
502 {"error": "Dev server proxy failed"} — The dev proxy could not reach the Vite process. The server may have crashed — check /apps/:name/status and restart if needed.
404 {"error": "No running dev server for ..."} — A dev proxy request was made but the app is not running. Call POST /apps/:name/start first.
403 {"error": "Origin not in allowlist. Add ... to data/.proxy-allowlist"} — The CORS proxy blocked the target origin. Add the full origin (e.g. https://api.example.com) to data/.proxy-allowlist.
401 {"error": "unauthorized"} — Bearer token is missing or invalid on a mutating endpoint (start/stop/restart/status). The dev proxy (/dev/*) does not require auth.
What’s next?
- Extensions API — register an app extension before managing its runtime
- Projects API — group apps with threads and agents into workspaces
- System API — reseed, daemon control, and filesystem browsing