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

  1. Discover a gateway endpoint.

  2. Create signature headers.

  3. Request a streaming session.

  4. Open the WebSocket with auth headers.

  5. Send a Subscribe message.

  6. Receive bundled price updates.

  7. 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 hash

  • X-Switchboard-Pubkey — Solana public key

  • X-Switchboard-Blockhash — recent Solana blockhash

  • X-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_token

  • oracle_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