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

# Datastream Protocol

> Connect, authenticate, join/leave rooms, and handle JSON ping/pong heartbeats on the Solana Tracker Datastream WebSocket.

<Info>
  **URL:** `wss://datastream.solanatracker.io/{apiKey}`\
  Use your Data API key in the path. Available on Premium, Business, and Enterprise plans.
</Info>

All Datastream rooms share one hub and the same JSON control protocol. Room data always arrives as `{ "type": "message", "room": "...", "data": ... }`.

## Connection URL

Always connect to the canonical Datastream host:

```text theme={null}
wss://datastream.solanatracker.io/{apiKey}
```

Customer-specific Data API REST hostnames do **not** terminate Datastream. Use the path key above — not a REST base URL — for WebSocket auth.

## Authentication failures

An invalid or missing API key may still complete the WebSocket handshake, then close almost immediately with:

* no JSON error payload
* no `joined` acknowledgment

Treat that clean-but-immediate close as authentication failure, not a normal shutdown. Retry only after fixing the key/URL.

## Join and leave

```javascript theme={null}
const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY");

ws.onopen = () => {
  ws.send(JSON.stringify({ type: "join", room: "price-by-token:TOKEN_MINT" }));
};

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

  if (msg.type === "joined") {
    console.log("Subscribed", msg.room);
  }

  if (msg.type === "message") {
    // Room payload in msg.data
  }

  // Application heartbeat (not WebSocket protocol ping/pong)
  if (msg.type === "ping") {
    ws.send(JSON.stringify({ type: "pong" }));
  }
};

// Unsubscribe — there is no separate `left` acknowledgment
ws.send(JSON.stringify({ type: "leave", room: "price-by-token:TOKEN_MINT" }));
```

| Envelope                                | Direction       | Meaning                     |
| --------------------------------------- | --------------- | --------------------------- |
| `{ "type": "join", "room" }`            | Client → server | Subscribe                   |
| `{ "type": "joined", "room" }`          | Server → client | Subscribe confirmed         |
| `{ "type": "leave", "room" }`           | Client → server | Unsubscribe (no `left` ack) |
| `{ "type": "message", "room", "data" }` | Server → client | Room data                   |
| `{ "type": "ping" }`                    | Server → client | App heartbeat               |
| `{ "type": "pong" }`                    | Client → server | Heartbeat reply             |

## Heartbeat (JSON ping/pong)

The server may emit a JSON control frame:

```json theme={null}
{ "type": "ping" }
```

Reply with:

```json theme={null}
{ "type": "pong" }
```

These are **application** frames. They are separate from WebSocket protocol-level ping/pong and from room `message` payloads. Native clients should answer JSON `ping` to keep the session stable.

## Wallet balance amounts

On `wallet:{wallet}:balance` and `wallet:{wallet}:{token}:balance`:

* `amount` is a **UI decimal** (human units), not raw integer base units / lamports
* native SOL uses mint `So11111111111111111111111111111111111111112`

```json theme={null}
{
  "type": "message",
  "room": "wallet:WALLET:balance",
  "data": {
    "wallet": "WALLET",
    "token": "So11111111111111111111111111111111111111112",
    "amount": 1.2345
  }
}
```

## Limits and quotas

Premium+ Datastream includes **unlimited messages** (no per-message fees). There is **no limit** on concurrent WebSocket connections or rooms per connection.

REST monthly request quotas do **not** disconnect an established Datastream session when exhausted.

## Next

<CardGroup cols={2}>
  <Card title="Live Prices" href="/guides/datastream-prices">
    Price and candle rooms.
  </Card>

  <Card title="Token Discovery" href="/guides/datastream-tokens">
    Launches, graduations, and market events.
  </Card>

  <Card title="Safety Streams" href="/guides/datastream-safety">
    Snipers, bundlers, and holder signals.
  </Card>

  <Card title="PnL V2 Datastream" href="/guides/datastream-pnl">
    Live wallet and position PnL.
  </Card>
</CardGroup>
