# Stream

The stream delivers your account's events over one WebSocket at `wss://api.predictparity.com/stream`. Authenticate with your key, as in [Getting started](https://predictparity.com/docs/api/getting-started).

## Connect

With Node.js and [`ws`](https://github.com/websockets/ws):

```js
import WebSocket from "ws";

const ws = new WebSocket("wss://api.predictparity.com/stream", {
  headers: { Authorization: `Bearer ${process.env.PARITY_BUILDER_KEY}` },
});

ws.on("message", (raw) => {
  const event = JSON.parse(raw.toString());
  console.log(event.type, event.data);
});
```

Each message is one JSON event, described under **Events** below. To see one, follow a trader in the app and wait for them to trade.

## Keepalive

The server sends a WebSocket ping frame every 30 seconds, which most clients answer automatically. A connection that hasn't answered by the next ping is closed.

## Disconnects

The server closes the connection with `1001` when it restarts, e.g. for a deploy. It drops a connection without a close frame if it misses a ping or falls more than 1 MiB behind in reading messages. Reconnect after any disconnect.

## Delivery

Events are delivered at least once to every open connection for your account. They are not stored: events sent while you have no open connection are not delivered later, so re-fetch any state you depend on after reconnecting.

The same event can arrive more than once; drop repeats by `messageId`.

## Timestamps

What `ts` means for each event:

| Event | `ts` |
| --- | --- |
| `fill.followed_trader` | When the venue reports the fill. |
| `alert.price_change` | When the alert fired. |
| `market.resolved` | When Parity saw the resolution. Venues' own resolution times mean different things. |

## Events

Every stream message is one event: an envelope around its `data`.

| Field | Type | Description |
| --- | --- | --- |
| `type` | string | The event type, below. |
| `messageId` | string | The same for every repeat of an event; use it to drop duplicates. |
| `ts` | string (date-time) | When the event happened (ISO 8601, UTC). |

Expand an event type for its `data` fields and an example. Shared types are in [Models](https://predictparity.com/docs/api/models).

<details id="fill-followed-trader">
<summary><code>fill.followed_trader</code>: A trader you follow, by bookmark or trader group, had an order filled.</summary>

**`data`**

| Field | Type | Description |
| --- | --- | --- |
| `fillId` | string | The fill's key. |
| `platform` | [Platform](https://predictparity.com/docs/api/models#platform) | The venue. |
| `transactionHash` | string \| `null` | The on-chain transaction hash. Null on off-chain venues. |
| `marketId` | string | The market's key. |
| `outcomeId` | string | The outcome's key. |
| `outcomeName` | string | The outcome traded, as the venue names it. |
| `side` | `"BUY"` \| `"SELL"` | The trader's side of the fill. |
| `shares` | number (> 0) | Shares (contracts) filled. |
| `priceMicrodollars` | integer (0–1,000,000) | Price per share in microdollars: 1,000,000 is $1.00. |
| `isMaker` | boolean \| `null` | Whether the trader provided liquidity. Null when the venue doesn't say. |
| `trader` | [Trader](https://predictparity.com/docs/api/models#trader) | A trader on a venue. |

**Example**

```json
{
  "type": "fill.followed_trader",
  "messageId": "128054a0563e9ce3",
  "ts": "2026-11-04T14:21:43.000Z",
  "data": {
    "fillId": "polymarket:0x347d873696eaac9c4456a6be562cb003d16adb10be4507213ac3a24a879dd1ce:0x56687bf447db6ffa42ffe2204a05edaa20f55839:BUY:0x4d3b93d9fc34ecf78c4f87235214e96d9a6a4857d992264b40b89b74f942594a",
    "platform": "polymarket",
    "transactionHash": "0x347d873696eaac9c4456a6be562cb003d16adb10be4507213ac3a24a879dd1ce",
    "marketId": "polymarket:0x19d2ff72e389d190c183e6b114817301d29eba651d67d75a38ee201a05188fd9",
    "outcomeId": "polymarket:0x19d2ff72e389d190c183e6b114817301d29eba651d67d75a38ee201a05188fd9:72139607190315861034411702195742538105117960260100800877125381826122747504258",
    "outcomeName": "Yes",
    "side": "BUY",
    "shares": 2149.89,
    "priceMicrodollars": 850000,
    "isMaker": false,
    "trader": {
      "id": "polymarket:0x56687bf447db6ffa42ffe2204a05edaa20f55839",
      "platformTraderId": "0x56687bf447db6ffa42ffe2204a05edaa20f55839",
      "displayName": "Theo4"
    }
  }
}
```

</details>

<details id="alert-price-change">
<summary><code>alert.price_change</code>: A price alert or price movement alert you set has fired.</summary>

**`data`**

| Field | Type | Description |
| --- | --- | --- |
| `alertId` | string (uuid) | The alert, as listed in the app. |
| `platform` | [Platform](https://predictparity.com/docs/api/models#platform) | The venue. |
| `marketId` | string | The market's key. |
| `outcomeId` | string | The outcome's key. |
| `outcomeName` | string | The outcome the alert watches. |
| `direction` | `"rises"` \| `"falls"` | Whether the price rose to the target or fell to it. |
| `targetPriceMicrodollars` | integer (0–1,000,000) | The price the alert fired at, in microdollars. For a movement alert, the edge of the band it crossed. |

**Example**

```json
{
  "type": "alert.price_change",
  "messageId": "e3ccfd24e426897e",
  "ts": "2026-11-04T15:02:10.000Z",
  "data": {
    "alertId": "c038dbaa-9910-46dd-bcf0-aa362d780d9f",
    "platform": "kalshi",
    "marketId": "kalshi:KXFEDDECISION-26DEC-H0",
    "outcomeId": "kalshi:KXFEDDECISION-26DEC-H0:yes",
    "outcomeName": "Yes",
    "direction": "rises",
    "targetPriceMicrodollars": 700000
  }
}
```

</details>

<details id="market-resolved">
<summary><code>market.resolved</code>: A market you hold a position in has resolved.</summary>

**`data`**

| Field | Type | Description |
| --- | --- | --- |
| `platform` | [Platform](https://predictparity.com/docs/api/models#platform) | The venue. |
| `marketId` | string | The market's key. |
| `winningOutcomeId` | string \| `null` | The winning outcome's key. Null for a tie or a void. |
| `winningOutcomeName` | string \| `null` | The winning outcome's name. Null for a tie or a void. |

**Example**

```json
{
  "type": "market.resolved",
  "messageId": "868d2b4ab845722e",
  "ts": "2026-11-05T04:59:12.000Z",
  "data": {
    "platform": "polymarket",
    "marketId": "polymarket:0x19d2ff72e389d190c183e6b114817301d29eba651d67d75a38ee201a05188fd9",
    "winningOutcomeId": "polymarket:0x19d2ff72e389d190c183e6b114817301d29eba651d67d75a38ee201a05188fd9:48331043336612883890938759509493159234755048973500640148014422747788308965732",
    "winningOutcomeName": "No"
  }
}
```

</details>

Source: https://predictparity.com/docs/api/stream
