Skip to main content

WebSocket API

The backend does not handle WebSocket connections directly; it only mints the JWT a client presents to open a real-time connection. The active system is Supabase Realtime, exposed through a single endpoint — POST /websocket/token, documented below.

An earlier Cloudflare office-router Worker design (Durable Objects + an RS256 handshake token) was implemented but never routed. Its backend service (internal/platform/cloudflare/auth/, handler GenerateDOUrl) was removed in a dead-code purge (qubital-backend #4) and does not reflect any current code. See that PR and the git history if you need the details.

Supabase Realtime token

The backend mints a short-lived HS256 JWT that the client presents to authenticate its Supabase Realtime subscription. The response is { token, expiresAt }. See Chat for how the frontend mints and uses it, and Supabase Realtime for the service.

FieldValue
EndpointPOST /websocket/token
AlgorithmHS256
Signing keySUPABASE_JWT_SECRET env var
Issuerqubital-backend (hardcoded)
Audienceauthenticated (Supabase RLS requirement)
TTL3600 seconds

Roadmap: the realtime transport is slated to move from Supabase Realtime to Centrifugo. The POST /websocket/token → { token, expiresAt } contract is intended to stay stable across that swap, so it is the seam the frontend integrates against.