Market Channel (WebSocket)
Overview
Section titled “Overview”Clients subscribe by specifying one or more asset IDs (token IDs). The server can send an initial order book snapshot on subscribe, then pushes incremental price-level changes, trade notifications, top-of-book updates, and lifecycle events to the connection.
Server: wss://api.openfish.me/ws/market
Subscribe
Section titled “Subscribe”Direction: Client -> Server
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | "subscribe" or "unsubscribe" |
assets_ids | array of strings | Yes | Asset IDs to subscribe/unsubscribe |
level | integer | No | Subscription level: 1=trades only, 2=+best bid/ask and price changes (default), 3=allows book initial dump |
initial_dump | boolean | No | Send one initial order book snapshot after subscribing when level >= 3 (default: false) |
{ "type": "subscribe", "assets_ids": ["52114319501245..."], "level": 2, "initial_dump": true}Complete Example
Section titled “Complete Example”const ws = new WebSocket("wss://api.openfish.me/ws/market");
ws.addEventListener("open", () => { ws.send(JSON.stringify({ type: "subscribe", assets_ids: [ "52114319501245915516055106046884209969926127482827954674443846427813813222426" ], level: 2, initial_dump: true }));});
ws.addEventListener("message", (event) => { if (event.data === "PING") { ws.send("PONG"); return; } console.log(JSON.parse(event.data));});Example server event:
{ "type": "best_bid_ask", "asset_id": "52114319501245915516055106046884209969926127482827954674443846427813813222426", "market": "0xbd31dc8a00000000000000000000000000000000000000000000000000000000", "best_bid": "0.54", "best_ask": "0.56", "timestamp": 1770000000000}Subscription Levels
Section titled “Subscription Levels”| Level | Events |
|---|---|
| 1 | last_trade_price |
| 2 | Level 1 + best_bid_ask, price_change |
| 3 | Level 2 + book when initial_dump=true |
Lifecycle events (new_market, market_resolved, tick_size_change) are always delivered.
Update Subscription
Section titled “Update Subscription”You can add or remove assets from your subscription without dropping the connection:
{ "type": "subscribe", "assets_ids": ["71321045679252..."]}{ "type": "unsubscribe", "assets_ids": ["71321045679252..."]}Legacy Query Parameters
Section titled “Legacy Query Parameters”For backward compatibility, ?market= and ?asset_id= query parameters are still accepted at connection time.
Heartbeat
Section titled “Heartbeat”The server emits a text "PING" frame every 10 seconds. The client must reply with text "PONG".
Events
Section titled “Events”book — Orderbook Snapshot
Section titled “book — Orderbook Snapshot”Sent as a one-time initial snapshot when subscribing with level >= 3 and initial_dump=true. Ongoing order book mutations are sent as price_change and best_bid_ask events.
| Field | Type | Description |
|---|---|---|
type | string | "book" |
asset_id | string | Asset ID |
market | string | Condition ID |
bids | array | [{ "price": "0.50", "size": "15" }] |
asks | array | [{ "price": "0.52", "size": "25" }] |
hash | string | Orderbook content hash |
timestamp | string | Unix ms |
price_change — Orderbook Delta
Section titled “price_change — Orderbook Delta”Requires level >= 2.
| Field | Type | Description |
|---|---|---|
type | string | "price_change" |
market | string | Condition ID |
asset_id | string | Asset ID |
price | string | Affected price level |
size | string | New size at this level ("0" = removed) |
side | string | "BUY" or "SELL" |
hash | string | Book content hash |
best_bid | string? | Current best bid (if changed) |
best_ask | string? | Current best ask (if changed) |
timestamp | integer | Unix timestamp |
last_trade_price — Trade Execution
Section titled “last_trade_price — Trade Execution”| Field | Type | Description |
|---|---|---|
type | string | "last_trade_price" |
asset_id | string | Asset ID |
market | string | Condition ID |
price | string | Execution price |
size | string | Trade size |
side | string | "BUY" or "SELL" (taker perspective) |
timestamp | integer | Unix ms |
best_bid_ask — Best Bid/Ask Update
Section titled “best_bid_ask — Best Bid/Ask Update”Requires level >= 2.
| Field | Type | Description |
|---|---|---|
type | string | "best_bid_ask" |
asset_id | string | Asset ID |
market | string | Condition ID |
best_bid | string? | Best bid price, or null when no bid is available |
best_ask | string? | Best ask price, or null when no ask is available |
timestamp | integer | Unix ms |
tick_size_change — Tick Size Update
Section titled “tick_size_change — Tick Size Update”| Field | Type | Description |
|---|---|---|
type | string | "tick_size_change" |
asset_id | string | Asset ID |
old_tick_size | string | Previous tick size |
new_tick_size | string | New tick size |
timestamp | integer | Unix ms |
new_market — Market Created
Section titled “new_market — Market Created”Broadcast to all connected clients regardless of subscription level.
| Field | Type | Description |
|---|---|---|
type | string | "new_market" |
market | string | Condition ID |
question | string | Market question |
slug | string | URL-friendly market slug |
outcomes | array | Outcome labels (e.g. ["Yes", "No"]) |
clob_token_ids | array | Token IDs for each outcome |
tags | array | Market tags |
timestamp | integer | Unix timestamp |
market_resolved — Market Resolved
Section titled “market_resolved — Market Resolved”Broadcast to all connected clients regardless of subscription level.
| Field | Type | Description |
|---|---|---|
type | string | "market_resolved" |
market | string | Condition ID |
winning_token_id | string | Winning asset ID |
winning_outcome | string | Winning outcome label |
assets_ids | array | All asset IDs in the market |
tags | array | Market tags |
timestamp | integer | Unix timestamp |