> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shuriken.trade/llms.txt
> Use this file to discover all available pages before exploring further.

# WebSocket Overview

> Real-time streaming API for live market data, balance updates, and trading signals.

The Shuriken WebSocket API delivers real-time updates for token swaps, balances, pool data, alpha signals, and more. It uses a Pusher-compatible protocol over WebSocket, authenticated with the same API key you use for REST.

<Info>
  WebSocket streams require a Bearer token. Create an [Agent Key](/agent-kit/create-agent-key) from the Terminal to get started.
</Info>

## SDKs (recommended)

The WebSocket protocol involves session bootstrapping, Pusher-compatible handshakes, and channel authorization. **We strongly recommend using an official SDK** instead of implementing this yourself:

<CardGroup cols={2}>
  <Card title="TypeScript SDK" icon="js" href="https://github.com/ShurikenTrade/shuriken-sdk-ts">
    Full WebSocket support with typed events and automatic reconnection.
  </Card>

  <Card title="Rust SDK" icon="rust" href="https://github.com/ShurikenTrade/shuriken-sdk-rs">
    Async streams via `futures::Stream` with typed payloads and auto-reconnect.
  </Card>
</CardGroup>

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import { createShurikenClient } from '@shuriken/sdk-ts';

    const client = createShurikenClient({ apiKey: 'sk_your_api_key' });
    await client.ws.connect();

    client.ws.subscribe('svm.token.swaps', {
      tokenAddress: 'So11111111111111111111111111111111111111112',
    }, (event) => {
      console.log('Swap:', event.priceUsd, event.sizeSol);
    });
    ```
  </Tab>

  <Tab title="Rust">
    ```rust theme={null}
    use shuriken_sdk::{ShurikenWsClient, streams::{SVM_TOKEN_SWAPS, SvmTokenFilter}};
    use futures_util::StreamExt;

    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let mut ws = ShurikenWsClient::new("sk_your_api_key")?;
        ws.connect().await?;

        let mut sub = ws.subscribe(
            SVM_TOKEN_SWAPS,
            SvmTokenFilter { token_address: "So11111111111111111111111111111111111111112".into() },
        ).await?;

        while let Some(event) = sub.next().await {
            println!("Swap: {:?}", event);
        }

        ws.disconnect().await;
        Ok(())
    }
    ```
  </Tab>
</Tabs>

## Raw protocol details

The rest of this page describes the underlying WebSocket protocol. You only need this if you're building a custom client without an SDK.

## How it works

There is no static WebSocket URL. The connection details are discovered dynamically through a session bootstrap call to the same REST API:

<Steps>
  <Step title="Bootstrap a session">
    POST to `/api/v2/ws/session` with the streams you want to subscribe to. The response contains the WebSocket host, port, app key, and resolved subscription channels.

    ```bash theme={null}
    curl -X POST "https://api.shuriken.trade/api/v2/ws/session" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"subscriptions": [{"stream": "svm.token.swaps", "filter": {"tokenAddress": "So11111111111111111111111111111111111111112"}}]}'
    ```

    The response includes a `connection` object with `wsHost`, `wsPort`, `appKey`, and `forceTls` fields.
  </Step>

  <Step title="Open WebSocket connection">
    Construct the WebSocket URL from the session response and connect:

    ```
    wss://{wsHost}:{wsPort}/app/{appKey}?protocol=7
    ```

    Wait for the `pusher:connection_established` message to get your `socket_id`.
  </Step>

  <Step title="Subscribe to channels">
    For **public** streams, send a `pusher:subscribe` message with the channel name from the session response.

    For **presence** streams (authenticated), first authorize via `POST /api/v2/ws/auth` with your `socket_id` and channel name, then subscribe with the returned auth token.
  </Step>
</Steps>

## Stream discovery

Get the full catalog of available streams and their filters at any time:

```bash theme={null}
curl -X GET "https://api.shuriken.trade/api/v2/ws/streams" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

See the [Stream Catalog](/api-reference/websocket/streams) for the complete list.

## Stream types

| Type         | Auth required          | Description                                                     |
| ------------ | ---------------------- | --------------------------------------------------------------- |
| **Public**   | API key only           | Market data streams anyone can subscribe to                     |
| **Presence** | API key + channel auth | User-specific streams (portfolio, automation, personal signals) |

## Connection states

| State          | Description                              |
| -------------- | ---------------------------------------- |
| `Disconnected` | No active connection                     |
| `Connecting`   | Handshake in progress                    |
| `Connected`    | Ready to subscribe and receive events    |
| `Reconnecting` | Connection lost, attempting to reconnect |
| `Failed`       | Connection failed permanently            |

## Event format

All stream events arrive as JSON with the following structure:

```json theme={null}
{
  "event": "update",
  "channel": "private-svm.token.swaps.So111...",
  "data": { ... }
}
```

The `data` field contains the stream-specific payload described in the [Stream Catalog](/api-reference/websocket/streams).
