Skip to content

WebSocket API

JARVIS uses a WebSocket connection for the live dashboard experience.

Default endpoint:

ws://localhost:3142/ws

If you serve the dashboard over HTTPS behind a proxy, the browser will use wss://.../ws.

The daemon’s current WebSocket messages use this shape:

{
"type": "chat",
"payload": {},
"id": "optional-id",
"priority": "normal",
"timestamp": 1710000000000
}

Important note:

  • The field is payload, not data

The shipped daemon defines these top-level message types:

  • chat
  • command
  • status
  • stream
  • error
  • notification
  • tts_start
  • tts_end
  • voice_start
  • voice_end
  • workflow_event
  • goal_event
  • site_event

Send a normal user message:

{
"type": "chat",
"payload": {
"text": "Summarize the top issues in this repository"
},
"id": "client-message-id",
"timestamp": 1710000000000
}

Used for system-style requests such as health checks or ping:

{
"type": "command",
"payload": {
"command": "health"
},
"timestamp": 1710000000000
}

Used by the dashboard voice pipeline. Binary audio chunks are sent between those markers.

Streaming partial response chunks and tool/sub-agent progress.

Used for structured events such as:

  • task updates
  • content updates
  • approval requests
  • awareness events
  • assistant-side follow-up notifications

Used for operation status and command responses.

Used when the daemon needs to surface a request error over the socket.

Used by the voice system to coordinate streamed speech playback.

Dedicated event streams for those product areas.

The outer WebSocket envelope still uses the same top-level type, payload, and timestamp fields. The event-specific details live inside payload.

If auth.token is configured, the dashboard/API layer requires it.

Custom clients should send that token using the same mechanisms the daemon actually accepts:

  • HTTP API requests:
Authorization: Bearer your-auth-token
  • Browser/dashboard bootstrap:
http://localhost:3142/?token=your-auth-token

When that ?token= query value is valid on an HTTP page request, the daemon responds by setting this cookie:

token=<auth.token>; Path=/; SameSite=Lax; HttpOnly

That token cookie is what browser WebSocket upgrades use afterward.

If you are building your own client, use one of these patterns:

  1. Non-browser client: send Authorization: Bearer ... on API requests and Cookie: token=... on the WebSocket handshake
  2. Browser client: first load the dashboard or your bootstrap route with ?token=..., let the daemon set the token cookie, then open /ws

Important detail:

  • the daemon’s WebSocket upgrade path checks the token cookie, not an Authorization header on the WebSocket request itself
  • the cookie name is literally token
  • the daemon sets it as HttpOnly; Path=/; SameSite=Lax

If you rely on cookies in a browser-based custom client, make sure your proxy preserves Set-Cookie and that the browser origin matches the daemon’s configured public URL/origin handling.

If auth.token is unset, the dashboard is open access.

If you proxy the dashboard:

  • forward /ws
  • preserve Upgrade and Connection headers
  • make sure the browser origin matches the daemon’s expected public host setup

This page is for:

  • people building custom dashboard clients
  • people debugging WebSocket/proxy issues
  • people integrating around the live event stream

If you just want to use JARVIS normally, start with Dashboard and Troubleshooting.