GET that upgrades to a WebSocket:
A successful connection returns HTTP
101 Switching Protocols, same as any WebSocket upgrade. Anything that would otherwise be a Problem error (auth failure, missing sandbox, and so on) is returned as an ordinary application/problem+json response instead of a 101.
Options travel in the START frame, never the query string
Neither endpoint takes connection options — TTY size, the command to run, environment variables — as query parameters. The upgrade request itself carries only path parameters (sandbox_id, session_name) and the standard X-Bonya-Organization-ID header. Once the connection is upgraded, the client sends a START frame as the first message on the socket, and that frame carries the actual options:
- On
.../exec, the START frame is aTTYStartRequest. - On
.../sessions/{session_name}/attach, the START frame is anAttachStartRequest.
A 101 is not authorization
Getting a 101 Switching Protocols response means the WebSocket handshake succeeded — it does not by itself mean your request has been authorized. Per the contract, admission happens at START: the server evaluates auth and access when it receives your START frame, after the upgrade has already completed. Don’t treat a successful upgrade as confirmation that the call will proceed — wait for the server’s response to your START frame before assuming the exec or attach is actually admitted.
Auth on the upgrade
The upgrade request itself is authenticated the same way as any other sandbox-scoped call: apersonalApiKey bearer token (or supabaseJwt), plus the optional X-Bonya-Organization-ID header for org context. That authenticates the connection; the admission decision for the specific exec or session-attach action happens afterward, at the START frame, as described above.
Related
See Exec for the buffered, non-WebSocket alternative (POST /v1/sandbox/{sandbox_id}/exec, JSON in and out, no upgrade involved), and Sessions for how named sessions are created and killed.