Core API & WebSocket proxy
The Supervisor proxies Core API traffic so that apps can talk to the Core runtime without knowing its address or holding a Core token. The canonical prefix is /core; the v1 tree also mirrors every route at the legacy /apexos prefix.
| Method | Path | Description |
|---|---|---|
| GET | /core/websocket | WebSocket proxy to the Core WebSocket API |
| GET | /core/api/websocket | Same handler, alternate path |
| GET | /core/api/stream | Proxy the Core event stream (long-lived) |
| GET / POST / DELETE | /core/api/{path} | Proxy an arbitrary Core REST call |
| GET | /core/api/ | Proxy the Core API root |
Only GET, POST, and DELETE are registered for the REST proxy — PUT and PATCH are not proxied.
Authentication
On the v1 tree these paths are exempt from the Supervisor's token middleware; the proxy performs its own check instead:
- REST/stream: the token is taken from
Authorization: Bearer ...(or a legacy access header) and must belong to an installed app that declares Core API access (apexos_api). Anything else gets401. - On the
/v2tree the paths are not exempt: the standard middleware requires a token whose role grants/core/*(roleapexosor higher) before the proxy's own check runs.
/core/api/supervisor/* (and the /apexos equivalent) is blocked outright with 403 — the proxy cannot be used to reach a Supervisor passthrough on the Core side.
All proxy calls fail with 502 Bad Gateway when the Core API is not up.
REST proxying details
- Request query string, body, and content type are forwarded; only a small header allowlist is passed through (
Accept,Last-Event-ID,Mcp-Session-Id,MCP-Protocol-Version,X-Speech-Content). - Responses with content type
text/event-stream(e.g. SSE endpoints) are streamed back unbuffered, preservingCache-ControlandMcp-Session-Id. - Other responses are relayed with their upstream status and content type.
- The default upstream timeout is 300 seconds;
/core/api/streamhas no timeout.
WebSocket proxy
GET /core/websocket performs a Core-style auth handshake with the connecting app, then bridges frames in both directions:
- Server sends
{"type": "auth_required", "apexos_version": "<core version>"}. - Client must reply within 10 seconds with a message containing its Supervisor token in
access_token(or the legacyapi_passwordfield). - The token must belong to an installed app with Core API access; otherwise the server sends
{"type": "auth_invalid", "message": "Invalid access"}and closes. - On success the server sends
{"type": "auth_ok", "apexos_version": "<core version>"}and opens a client connection to the Core WebSocket API.
After the handshake, text and binary frames are forwarded verbatim in both directions with a 30-second heartbeat; when either side closes, the other side is closed too.
:::info Legacy field
The frames also carry ha_version, a deprecated duplicate of apexos_version kept for older client libraries.
:::