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

# WebSocket Stream

> Real-time article firehose over WebSocket (Pro and Max plans)

## Connection

```
wss://api.tradingnews.press/v1/stream?api_key=YOUR_KEY
```

API key is passed as a query parameter (not a header) since WebSocket connections don't support custom headers in browsers.

<Note>
  WebSocket streaming requires the **Pro** (\$50/mo) or **Max** plan. Starter plan connections are rejected with close code `1008`.
</Note>

## Protocol

### 1. Connect

Open a WebSocket connection to the URL above. No subscription step is needed — the server immediately begins pushing all articles as they arrive (firehose).

### 2. Receive articles

The server pushes JSON articles as they arrive:

```json Pro theme={null}
{
  "id": "01KNKV33C9DDADR1HRRWGCSA8V",
  "content": "BREAKING: MISSILES TARGET US FACILITY NEAR BAGHDAD",
  "urgency": "breaking",
  "sentiment": null,
  "published_at": "2026-04-07T20:22:42+00:00",
  "received_at": "2026-04-07T20:22:43.123456+00:00"
}
```

```json Max theme={null}
{
  "id": "01KNKV33C9DDADR1HRRWGCSA8V",
  "content": "Apple announces record Q2 earnings, beats estimates by 12%",
  "urgency": "breaking",
  "sentiment": null,
  "published_at": "2026-04-07T14:30:00+00:00",
  "received_at": "2026-04-07T14:30:02.123456+00:00",
  "tickers": [
    {"ticker": "AAPL", "sentiment": "positive"}
  ]
}
```

Max-plan streams add a `tickers` array on each message (empty when no tickers are detected). Pro streams omit the field entirely.

## Connection Limit

Each user is limited to **1 concurrent WebSocket connection**. Attempting a second connection returns close code `1008` with reason "Only 1 WebSocket connection allowed."

## Disconnection

The connection closes when:

* Your plan is not Pro or Max (close code `1008`)
* You already have an active connection (close code `1008`)
* Invalid or inactive API key (close code `1008`)
* Your subscription expires mid-stream — the server re-checks every 5 minutes (close code `1008`)
* Server maintenance (implement auto-reconnect)

## Example: Python

```python theme={null}
import asyncio
import json
import websockets

async def main():
    async with websockets.connect(
        "wss://api.tradingnews.press/v1/stream?api_key=YOUR_KEY"
    ) as ws:
        # Firehose — all articles pushed automatically
        async for message in ws:
            article = json.loads(message)
            if article["urgency"] == "breaking":
                print(f"ALERT: {article['content']}")

asyncio.run(main())
```

## Example: JavaScript

```javascript theme={null}
const ws = new WebSocket("wss://api.tradingnews.press/v1/stream?api_key=YOUR_KEY");

// Firehose — all articles pushed automatically
ws.onmessage = ({ data }) => {
  const article = JSON.parse(data);
  if (article.urgency === "breaking") {
    console.log(`ALERT: ${article.content}`);
  }
};

ws.onclose = ({ code }) => {
  if (code === 1008) console.log("Auth failed or plan does not include streaming");
  // Implement reconnection logic
};
```
