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

# Overview

> A high-level guide to Benzinga's real-time WebSocket data streams.

Benzinga's WebSocket API delivers low-latency, push-based financial data directly to your application. Instead of repeatedly polling a REST endpoint, you open a single persistent connection and receive events the moment they're available — analyst ratings, earnings results, news, transcripts, and more.

All streams share the same base endpoint, authentication model, and message envelope, so the patterns you learn on one stream apply everywhere.

## How it works

<Steps>
  <Step title="Authenticate">
    Obtain a Benzinga API token from the [Benzinga Console](https://www.api.benzinga.com/token) and append it as a `token` query parameter when opening the connection.
  </Step>

  <Step title="Connect">
    Open a WebSocket connection to the stream URL for the data you need — for example `wss://api.benzinga.com/api/v1/analyst/insights/stream?token=YOUR_TOKEN`.
  </Step>

  <Step title="Receive events">
    Messages arrive as JSON objects with a consistent envelope: an `id`, `api_version`, `kind`, and a `data` block that carries the action (`created`, `updated`, or `deleted`) and the payload.
  </Step>

  <Step title="Keep the connection alive">
    Send a `ping` plain-text frame periodically (every 30–60 s). The server responds with `pong`. The server also sends its own ping every 10 s — most WebSocket libraries handle this automatically.
  </Step>
</Steps>

## One connection per API key

Each API key may hold **one active connection per stream** at a time. The limit is per stream and enforced across all of Benzinga's servers. You **can** run connections to several different streams at once with the same key — but only **one** connection to any given stream. This keeps delivery ordering consistent for your key on each stream and prevents a single token from fanning out into unbounded concurrent connections to the same stream.

<Warning>
  If a connection to a stream is already active for your token, another connection to that **same** stream is rejected with HTTP **429 Too Many Requests**. The existing connection is **not** dropped — the new attempt is refused. Open one connection per stream per key and fan messages out inside your own application.
</Warning>

### What this means in practice

* **Don't** open more than one connection to the **same** stream with a single key (per browser tab, worker, or server instance) — consolidate to one connection per stream and distribute messages internally.
* Connecting to **different** streams with the same key is fine — each stream permits its own single connection.
* If you need multiple concurrent consumers of the **same** stream, request additional API keys.
* Treat a `429` on connect as "another session is already active for this key on this stream," not as a rate limit on message volume.

### Reconnecting

When a connection drops (network blip, deploy, or a missed keepalive ping), reconnect — but expect a brief hand-off window before the previous session's slot frees:

<Steps>
  <Step title="Reconnect with backoff">
    Retry with exponential backoff (e.g. start at \~2 s, cap around 15 s). A `429` means your previous session for that stream is still considered active; keep backing off and retry until it succeeds.
  </Step>

  <Step title="Deduplicate">
    Use the message `id` to drop any events you may see again around the reconnect boundary.
  </Step>
</Steps>

<Note>
  If your process exits without closing the socket cleanly, the slot is released automatically after a short server-side timeout — no manual cleanup is required. Just reconnect with backoff; a freshly dropped connection can take a few seconds to free.
</Note>

## Available streams

<CardGroup cols={2}>
  <Card title="Analyst Insights" icon="chart-line" href="/ws-reference/data-websocket/get-analyst-insights-stream">
    Real-time analyst ratings, price targets, and detailed recommendations as they're published.
  </Card>

  <Card title="Ratings" icon="star" href="/ws-reference/data-websocket/get-calendar-ratings-stream">
    Analyst rating changes and price target updates from major firms.
  </Card>

  <Card title="Consensus Ratings" icon="scale-balanced" href="/ws-reference/data-websocket/get-consensus-ratings-stream">
    Aggregated consensus ratings and price targets across all tracked analysts.
  </Card>

  <Card title="Earnings" icon="sack-dollar" href="/ws-reference/data-websocket/get-calendar-earnings-stream">
    Earnings announcements with EPS, revenue, estimates, and surprise metrics.
  </Card>

  <Card title="Bulls/Bears Say" icon="comments" href="/ws-reference/data-websocket/get-bulls-bears-say-stream">
    Bull and bear case scenarios for securities, published in real time.
  </Card>

  <Card title="News" icon="newspaper" href="/ws-reference/data-websocket/get-news-stream">
    Breaking news articles and market updates from Benzinga's editorial team.
  </Card>

  <Card title="Earnings Call Transcripts" icon="microphone" href="/ws-reference/data-websocket/get-transcripts-stream">
    Live earnings call transcripts delivered sentence-by-sentence as they're spoken.
  </Card>
</CardGroup>

## Message envelope

Every stream message follows the same top-level structure:

```json theme={null}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "api_version": "websocket/v1",
  "kind": "<stream-type>",
  "data": {
    "action": "created",
    "id": "<record-id>",
    "timestamp": "2024-10-08T10:00:00Z",
    "content": { ... }
  }
}
```

| Field          | Description                                              |
| -------------- | -------------------------------------------------------- |
| `id`           | Unique message ID — use this to deduplicate on reconnect |
| `api_version`  | Protocol version of the message                          |
| `kind`         | Identifies which stream the message came from            |
| `data.action`  | One of `created`, `updated`, or `deleted`                |
| `data.content` | Stream-specific payload                                  |

## Reference pages

<CardGroup cols={3}>
  <Card title="Authentication" icon="key" href="/ws-reference/authentication">
    How to obtain and use your API token.
  </Card>

  <Card title="Supported Actions" icon="bolt" href="/ws-reference/actions">
    `ping` and `replay` commands you can send on any stream.
  </Card>

  <Card title="Errors" icon="triangle-exclamation" href="/ws-reference/errors">
    Error codes and how to handle connection failures.
  </Card>
</CardGroup>
