Surge Gateway Protocol
Surge provides low-latency price streaming via the Crossbar gateway. This page documents the HTTP + WebSocket protocol for clients that cannot use the SDK or need custom integrations.
When to use this protocol
You are implementing a non-JS client (Rust/Go/Python/etc.).
You are running custom infrastructure and need direct gateway control.
You are debugging auth/session issues or connection failures.
You are building a load-testing or monitoring client.
Protocol Overview
Discover a gateway endpoint.
Create signature headers.
Request a streaming session.
Open the WebSocket with auth headers.
Send a Subscribe message.
Receive bundled price updates.
Respond to keepalive pings.
1. Gateway discovery
Mainnet:
Devnet:
The response returns one or more gateway base URLs. Choose one and use it for the session request.
2. Signature headers
For every HTTP and WebSocket request, you must include signature headers derived from a recent Solana blockhash and current timestamp.
Message to sign
Sign the hash with Ed25519 using your Solana keypair.
Required headers
X-Switchboard-Signature— Ed25519 signature of the hashX-Switchboard-Pubkey— Solana public keyX-Switchboard-Blockhash— recent Solana blockhashX-Switchboard-Timestamp— current timestamp
Notes:
Use a fresh blockhash and timestamp for each request.
Keep client time in sync (clock skew can cause auth failures).
3. Session request
Include the signature headers. The response contains:
session_tokenoracle_ws_url
4. WebSocket connection
Open a WebSocket connection to oracle_ws_url with:
Authorization: Bearer {pubkey}:{session_token}The same signature headers (
X-Switchboard-*)
5. Subscribe message
Send a Subscribe message after connecting:
6. Price updates
The gateway sends BundledFeedUpdate messages. Each update includes feed_values[] entries. The value field is an 18-decimal big-integer string (no decimal point). Convert it to a decimal value by dividing by 1e18 (e.g., \"67335320000000000000000\" → 67335.32).
If you're using the SDK, helpers like getFormattedPrices() already apply this scaling for you. Only raw consumers need to handle the 1e18 divisor.
7. Keepalive
The gateway may send a SignedPing. Respond with a SignedPong that includes a fresh signature (new blockhash + timestamp):
Error handling and reconnects
Common causes of disconnects or auth errors:
Invalid signature
Expired timestamp
Stale blockhash
Invalid or expired session token
On failure, request a new session and reconnect with fresh signatures.
Last updated