Market Channel
The market channel is a public WebSocket feed delivering real-time order book data, price-level mutations, trade fills, and lifecycle events for prediction markets. No authentication needed.
Endpoint
Section titled “Endpoint”wss://api.openfish.fun/ws/marketSubscription
Section titled “Subscription”Two subscription methods are available:
JSON Subscription (Recommended)
Section titled “JSON Subscription (Recommended)”After establishing the connection, send a JSON message to subscribe:
{ "type": "subscribe", "assets_ids": ["71321045679252212594626385532706912750332728571942532289631379312455583992563"], "level": 2, "initial_dump": true}| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | "subscribe" or "unsubscribe" |
assets_ids | array | Yes | Token asset IDs to subscribe/unsubscribe |
level | integer | No | Subscription level: 1=trades only, 2=+best bid/ask (default), 3=+full book |
initial_dump | boolean | No | Send initial book snapshot after subscribing (default: false) |
Add or drop subscriptions on the fly without reconnecting:
{ "type": "subscribe", "assets_ids": ["new_asset_id_here"] }{ "type": "unsubscribe", "assets_ids": ["asset_id_to_remove"] }Legacy Query Parameters
Section titled “Legacy Query Parameters”For backward compatibility, query parameters still work:
| Parameter | Type | Description |
|---|---|---|
market | string | Filter by condition ID |
asset_id | string | Filter by specific token asset ID |
wss://api.openfish.fun/ws/market?market=0xbd31dc...&asset_id=71321045...If neither query parameters nor a subscription message is provided, the connection receives events for all markets.
Subscription Levels
Section titled “Subscription Levels”| Level | Events Received |
|---|---|
| 1 | last_trade_price only |
| 2 | Level 1 + best_bid_ask, price_change |
| 3 | Level 2 + book snapshots |
Lifecycle events (new_market, market_resolved, tick_size_change) arrive regardless of subscription level.
Heartbeat
Section titled “Heartbeat”The server sends a text message "PING" every 10 seconds. Reply with a text message "PONG" to keep the connection alive.
Note: These are text messages, not WebSocket-level ping/pong frames.
Event Types
Section titled “Event Types”Every message is a JSON object. A type or event_type field identifies the event kind.
Complete order book snapshot. Delivered on initial connection and whenever trades reshape the book.
{ "event_type": "book", "asset_id": "71321045679252212594626385532706912750332728571942532289631379312455583992563", "market": "0xbd31dc8a20211944f6b70f31557f1001557b59905b7738480ca09bd4532f84af", "bids": [ { "price": "0.48", "size": "30" }, { "price": "0.49", "size": "20" } ], "asks": [ { "price": "0.52", "size": "25" }, { "price": "0.53", "size": "60" } ], "timestamp": "1700000000000"}price_change
Section titled “price_change”Fired when an order placement or cancellation alters a price level. Requires subscription level >= 2.
{ "type": "price_change", "market": "0x5f65177b394277fd294cd75650044e32ba009a95022d88a0c1d565897d72f8f1", "asset_id": "71321045...", "price": "0.50", "size": "200", "side": "BUY", "hash": "abc123", "best_bid": "0.50", "best_ask": "0.52", "timestamp": 1700000001}A size of "0" means the price level has been completely emptied.
last_trade_price
Section titled “last_trade_price”Fired when a maker and taker order match, producing a fill.
{ "event_type": "last_trade_price", "asset_id": "71321045...", "market": "0x6a67b9d8...", "price": "0.456", "side": "BUY", "size": "219.217767", "fee_rate_bps": "0", "timestamp": "1700000002000"}best_bid_ask
Section titled “best_bid_ask”Fired when the top-of-book bid or ask shifts.
{ "event_type": "best_bid_ask", "market": "0x0005c0d3...", "asset_id": "85354956...", "best_bid": "0.73", "best_ask": "0.77", "spread": "0.04", "timestamp": "1700000003000"}tick_size_change
Section titled “tick_size_change”Fired when the minimum tick size for a market changes — typically when the book price exceeds 0.96 or drops below 0.04.
{ "event_type": "tick_size_change", "asset_id": "71321045...", "market": "0xbd31dc8a...", "old_tick_size": "0.01", "new_tick_size": "0.001", "timestamp": "1700000004000"}new_market
Section titled “new_market”Fired when a new prediction market appears on the platform.
{ "type": "new_market", "market": "0x311d0c4b...", "question": "Will ETH reach $5000 by March?", "slug": "eth-5000-by-march", "outcomes": ["Yes", "No"], "clob_token_ids": ["76043073...", "31690934..."], "tags": ["crypto", "ethereum"], "timestamp": 1700000005}market_resolved
Section titled “market_resolved”Fired when a market’s outcome is determined.
{ "type": "market_resolved", "market": "0x311d0c4b...", "winning_token_id": "76043073...", "winning_outcome": "Yes", "assets_ids": ["76043073...", "31690934..."], "tags": ["crypto", "ethereum"], "timestamp": 1700000006}Broadcast Filtering
Section titled “Broadcast Filtering”Events carrying market and asset_id fields are filtered server-side based on your subscription or query parameters. Events lacking these fields (such as new_market, market_resolved, and tick_size_change) are broadcast to every connected client regardless of filters.
Rust SDK Example
Section titled “Rust SDK Example”use openfish_client_sdk::ws::MarketSocket;use futures_util::StreamExt;
#[tokio::main]async fn main() -> anyhow::Result<()> { // Connect with optional market filter let mut ws = MarketSocket::connect( "wss://api.openfish.fun/ws/market?asset_id=71321045679252212594626385532706912750332728571942532289631379312455583992563" ).await?;
while let Some(event) = ws.next().await { match event.event_type.as_str() { "book" => { println!("Book: {} bids, {} asks", event.bids.len(), event.asks.len()); } "last_trade_price" => { println!("Trade: {} @ {}", event.size, event.price); } "best_bid_ask" => { println!("BBO: {} / {} (spread {})", event.best_bid, event.best_ask, event.spread); } "new_market" => { println!("New market: {}", event.question); } "market_resolved" => { println!("Resolved: {} -> {}", event.question, event.winning_outcome); } _ => {} } }
Ok(())}Next Steps
Section titled “Next Steps”- User Channel — Authenticated order and trade updates.
- WebSocket Overview — All available channels.