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

# WebSocket Stream

> Hook directly into our engine. Zero polling, zero latency.

<Note>
  WebSockets are only available on the **Pro** and **Enterprise** tiers.
  If you connect with a Free tier key, the server will instantly drop your connection. Use [GET /alerts/latest](/api-reference/alerts/get-latest) instead if you're on Free.
</Note>

## The Endpoint

Hook your client into this URL. **Do not** put your API key in the `Authorization` header—WebSocket libraries are notoriously inconsistent with custom headers. Pass it exactly as shown in the query string.

```
wss://polychadsbot.xyz/ws/alerts?api_key=YOUR_KEY_HERE
```

## Setup Example

<CodeGroup>
  ```javascript Node / Browser theme={null}
  const ws = new WebSocket(
    "wss://polychadsbot.xyz/ws/alerts?api_key=YOUR_KEY_HERE"
  );

  ws.onmessage = (event) => {
    const msg = JSON.parse(event.data);

    switch (msg.type) {
      case "connected":
        console.log(`🔌 Wired in! Running on ${msg.tier} tier.`);
        break;
      case "alert":
        const a = msg.data;
        console.log(`🚨 WHALE ALERT: ${a.side} ${a.outcome} on '${a.event_title}'`);
        console.log(`Size: $${a.usdc_value} @ ${a.entry_price}¢`);
        console.log(`Conviction Score: ${a.signal_score}/100`);
        break;
    }
  };

  // CRITICAL: Send a ping every 25 seconds to keep the socket alive
  setInterval(() => {
    if (ws.readyState === WebSocket.OPEN) ws.send("ping");
  }, 25000);
  ```

  ```python Python (websockets) theme={null}
  import asyncio, json, websockets

  async def listen_for_whales():
      uri = "wss://polychadsbot.xyz/ws/alerts?api_key=YOUR_KEY_HERE"
      
      async with websockets.connect(uri) as ws:
          async for message in ws:
              msg = json.loads(message)
              
              if msg["type"] == "alert":
                  a = msg["data"]
                  print(f"🚨 ALERT: {a['side']} {a['outcome']} @ {a['entry_price']}¢")
                  print(f"Size: ${a['usdc_value']} | Score: {a['signal_score']}")
                  print(a["event_title"], "\n")

  # Run the event loop
  asyncio.run(listen_for_whales())
  ```
</CodeGroup>

## Payload Specifications

### `connected`

Fired exactly once the millisecond your connection is successfully authenticated.

```json theme={null}
{
  "type": "connected",
  "message": "Connected to Polychads alert stream",
  "tier": "pro"
}
```

### `alert`

A live insider alert. The `data` property contains the exact [Alert Object](/reference/alert-object) you get from the REST API.

```json theme={null}
{
  "type": "alert",
  "data": {
    "id": 2221,
    "alert_type": "fresh",
    "side": "BUY",
    "outcome": "Yes",
    "entry_price": 0.42,
    "usdc_value": 2100.0,
    "signal_score": 72,
    "event_title": "Will ETH hit $5000 by April?",
    "category": "crypto"
  }
}
```

### `pong`

Sent by the server immediately after you send a `ping`.

<Warning>
  **Keep-Alives are mandatory.** The server unapologetically drops connections that fail to send a `ping` string within any rolling 30-second window. Set your interval to 20-25 seconds to be safe.
</Warning>

## Handling Disconnects

Networks hiccup. Servers redeploy. Your bot should be resilient. Always use exponential backoff when reconnecting so you don't get banned for hammering the auth server if something goes down.

```javascript Reconnection Logic theme={null}
let retryDelay = 1000;

function connect() {
  const ws = new WebSocket("wss://polychadsbot.xyz/ws/alerts?api_key=KEY");
  
  ws.onopen = () => { 
    console.log("Connected");
    retryDelay = 1000; // Reset backoff on success
  };
  
  ws.onclose = () => {
    console.log(`Disconnected. Retrying in ${retryDelay}ms...:(`);
    setTimeout(connect, retryDelay);
    // Exponential backoff, capping at 30 seconds
    retryDelay = Math.min(retryDelay * 2, 30000); 
  };
}

connect();
```
