type field without a schema field. Event envelopes always carry "schema": "ws.firm.v1".
Server → client
connected
Sent exactly once, immediately after the upgrade succeeds.
scope.confirmed
Sent in response to every accepted scope.set.
pong
Reply to client ping.
error
Advisory error for the client. Does not close the socket on its own — the server may follow with a close frame (4001 for auth, 4002 for backpressure).
Client → server
scope.set
See Subscription scopes for the full schema. A second scope.set replaces the previous subscription.
ping
Application-level keepalive. Send every 20–30 seconds. The server also sends standard WebSocket control ping frames at ~30s intervals — most client libraries auto-respond to those.
Ordering guarantees
- The server processes client frames in order.
scope.settakes effect before any subsequent event is delivered. - Event envelopes are delivered in JetStream
seqorder per subject. Across subjects, ordering is best-effort; rely onseqper stream and ontsfor cross-subject reasoning.

