TypeScript SDK — WebSocket
The SDK provides real-time market data and account updates over WebSocket. Public streams require no authentication. Private streams and request methods (orders, balances, positions, RFQ deliveries, and order actions) require server-side WebSocket authentication and run only from the server entry point.
Public and private surfaces
The client makes the authentication boundary explicit in its API. A single server client can expose both surfaces, but they use separate WebSocket connections and never share frames or connection state.
| Surface | Available from | Authentication | Connection | Includes |
|---|---|---|---|---|
client.websocket.public | Browser and server | None | Shared public session | Trades, book tickers, depth updates, contract status, public RFQ discovery, and public controls |
client.websocket.private | Server only | HMAC or confidential OAuth | Separate authenticated session | Account/session orders, balances, positions (including terminal settlement details), RFQ deliveries, order actions, and RFQ quote mutations |
client.websocket.public.orderBook() | Browser and server | None | Separate shared order-book session | Self-healing order books and resync events |
client.websocket.public.depth() | Browser and server | None | One isolated session per snapshot stream | Partial-depth snapshots |
Use the public surface for information Gemini makes available to everyone. Use
the private surface for account-specific data or any operation that can change
state. The browser entry point intentionally does not expose .private; OAuth
in a browser authenticates REST only. See Authentication for why.
Public streams
Subscribe to market data without authentication:
Code
Public streams share a single underlying WebSocket connection. Opening multiple streams to different symbols reuses the same session.
Closing a stream
Code
Closing one stream does not affect others on the shared session. Call client.close() to shut down all streams and connections.
Live order book
The SDK maintains a self-healing L2 order book from WebSocket depth data:
Code
The first "update" event after subscribing (or after a "resync") carries the full book — treat it as a replacement, not an incremental diff. Subsequent updates carry only changed levels; a quantity of "0" means the level was removed.
For exact decimal arithmetic, use spreadDecimal() and midDecimal() which return string decimals ("0.01"). spread() and mid() return floating-point numbers for display only.
Code
Authenticated streams
Authenticated streams require the server entry point and an auth strategy. They use the ws package to set custom headers on the WebSocket upgrade request.
Code
The public RFQ discovery stream is deliberately separate from these private
deliveries: subscribe with client.websocket.public.rfqs() to discover open
auctions, then use client.websocket.private.rfq.submitQuote() or
confirmQuote() to perform authenticated maker actions. See the RFQ deep
dive for the complete flow and application decision hooks.
Browser limitation
Browser WebSocket cannot set custom HTTP headers on the upgrade request. BrowserOAuthAuth authenticates REST only; it does not authenticate private RIO WebSocket streams or request methods. The browser entry point exposes only client.websocket.public, so private operations are neither available in its API nor included in its WebSocket bundle. Browser apps can use:
- Public streams (trades, depth, book tickers) — no auth needed
- REST endpoints via OAuth for authenticated operations
If a first-party Gemini web application has a cookie-authenticated WebSocket endpoint, that is an application-specific integration and is not the SDK's browser authentication mechanism. Use the server entry point or a trusted server-side relay when an SDK integration needs private WebSocket access.
WebSocket order operations
Place and cancel orders over WebSocket for lower latency:
Code
Cancellation methods that affect multiple orders require explicit confirmation:
Code
Reconnection
WebSocket connections reconnect automatically on disconnection with exponential backoff:
- Public stream subscriptions are replayed after reconnect
- Authenticated streams re-authenticate with fresh credentials (nonces and tokens are regenerated)
- Mutating requests (order placement/cancellation) are never replayed — they reject with an error if the connection drops mid-request
Monitor reconnection:
Code
Stream state
Code
WebSocket architecture
The transport and session implementation is intentionally internal. Applications
should use the typed client.websocket.public or client.websocket.private facade returned by createClient();
this keeps connection lifecycle, request correlation, reconnection, and stream
cleanup in one place. Custom socket behavior can be supplied with the public
webSocketFactory option on the server entry point.
What's next
- WebSocket Reference — every stream, method, and wire-format field
- Order Book Reconstruction — snapshot + diff internals and gap recovery
- Error handling — WebSocket-specific errors and connection failures
- Patterns & recipes — heartbeat, liveness checks, and advanced configuration