Documentation Index
Fetch the complete documentation index at: https://docs.renesis.fi/llms.txt
Use this file to discover all available pages before exploring further.
Global Orderbook Module Websocket
Real-time orderbook streaming using Socket.IO. Get live updates from multiple exchanges with aggregated global orderbook view.
Connection
import { io } from 'socket.io-client';
const socket = io('wss://api.renesis.fi', {
transports: ['websocket'],
path: '/order-execution/socket.io'
});
Authentication
No authentication required - Orderbook data is publicly available market data.
Connection Keepalive
Socket.IO handles keepalive automatically via ping/pong:
| Setting | Value | Description |
|---|
ping_interval | 25s | Server sends ping every 25 seconds |
ping_timeout | 20s | Connection dropped if no pong within 20s |
No client-side action required - the Socket.IO client library handles ping/pong responses automatically. As long as the connection is open and the network is stable, the connection stays alive.
If you need to detect connection health in your app:
socket.on('disconnect', (reason) => {
console.log('Disconnected:', reason);
// reason: 'ping timeout', 'transport close', 'io server disconnect', etc.
});
socket.io.on('reconnect', (attempt) => {
console.log('Reconnected after', attempt, 'attempts');
// Re-subscribe to orderbooks after reconnect
});
Events
Client → Server Events
| Event | Payload | Description |
|---|
subscribe_orderbook | {symbol, venues, include_global, depth} | Subscribe to orderbook stream |
unsubscribe_orderbook | {symbol} | Unsubscribe from stream |
get_snapshot | {symbol, venues} | Request current snapshot |
Server → Client Events
| Event | Payload | Description |
|---|
connected | {sid, message} | Connection acknowledged |
subscribed | {symbol, venues, include_global, depth} | Subscription confirmed |
orderbook_snapshot | {symbol, venues, timestamp} | Initial full snapshot |
orderbook_update | Per-venue book update | Real-time updates (~10-20/sec) |
global_book | Aggregated best prices | Combined view across venues |
error | {message} | Error notification |
unsubscribed | {symbol} | Unsubscribe confirmed |
Subscribing to Orderbooks
Subscribe to Single Exchange
socket.emit('subscribe_orderbook', {
symbol: 'BTC/USDT',
venues: ['binance'], // Single exchange
include_global: false, // No aggregation needed
depth: 10 // 10 price levels
});
Subscribe to Multiple Exchanges + Global Book
socket.emit('subscribe_orderbook', {
symbol: 'BTC/USDT',
venues: ['binance', 'bybit', 'gateio', 'kraken'],
include_global: true, // Get aggregated best bid/ask
depth: 10
});
Subscribe to All Exchanges
socket.emit('subscribe_orderbook', {
symbol: 'ETH/USDT',
venues: [], // Empty = all available venues
include_global: true,
depth: 5
});
Subscription Parameters
| Parameter | Type | Default | Description |
|---|
symbol | string | required | Trading pair (e.g., “BTC/USDT”) |
venues | string[] | [] (all) | Filter to specific exchanges |
include_global | boolean | true | Include aggregated global book |
depth | number | 5 | Price levels per side (1, 5, 10, or 20) |
Supported Venues
| Venue | Update Rate | Notes |
|---|
binance | ~9/sec | Highest liquidity |
bybit | ~28/sec | Fastest updates |
gateio | ~8/sec | Good depth |
kraken | ~15/sec | Reliable |
Per-Venue Update (orderbook_update)
Sent for each exchange when the orderbook changes:
{
"venue": "binance",
"symbol": "BTC/USDT",
"bids": [
[88150.50, 1.5], // [price, quantity]
[88150.00, 2.3],
[88149.50, 0.8]
],
"asks": [
[88151.00, 0.8],
[88151.50, 1.2],
[88152.00, 0.5]
],
"spread_bps": 0.57, // Spread in basis points
"mid_price": 88150.75,
"staleness_ms": 15.2, // How old the data is
"confidence": 0.98, // 0-1 reliability score
"quality": "GOOD", // GOOD, DEGRADED, STALE, UNAVAILABLE
"timestamp": "2025-12-19T15:30:00.000000"
}
Global Book (global_book)
Aggregated view showing best prices across all subscribed venues:
{
"symbol": "BTC/USDT",
"data": {
"symbol": "BTC/USDT",
"timestamp": "2025-12-19T14:56:00.000000",
"best_bid": {
"price": 87953.60,
"quantity": 0.23,
"venue": "gateio"
},
"best_ask": {
"price": 87949.90,
"quantity": 0.12,
"venue": "bybit"
},
"venues": {
"binance": {
"bid": 87951.30,
"ask": 87951.31,
"confidence": 0.95
},
"bybit": {
"bid": 87949.80,
"ask": 87949.90,
"confidence": 1.0
},
"gateio": {
"bid": 87953.60,
"ask": 87953.70,
"confidence": 0.92
},
"kraken": {
"bid": 87951.30,
"ask": 87951.40,
"confidence": 0.98
}
}
},
"timestamp": "2025-12-19T14:56:00.000000"
}
Initial Snapshot (orderbook_snapshot)
Sent immediately after subscribing:
{
"symbol": "BTC/USDT",
"venues": {
"binance": {
"venue": "binance",
"symbol": "BTC/USDT",
"bids": [[88150.50, 1.5], ...],
"asks": [[88151.00, 0.8], ...],
"spread_bps": 0.57,
"mid_price": 88150.75,
"staleness_ms": 10.5,
"confidence": 0.98,
"quality": "GOOD",
"timestamp": "2025-12-19T15:30:00.000000"
},
"bybit": { ... }
},
"timestamp": "2025-12-19T15:30:00.000000"
}
Quality Metrics
Quality Levels
| Quality | Staleness | Description |
|---|
GOOD | < 500ms | Fresh data, reliable for trading |
DEGRADED | 500ms - 2s | Slightly stale, use with caution |
STALE | 2s - 5s | Old data, risky for trading |
UNAVAILABLE | > 5s | Do not use |
Confidence Score (0.0 - 1.0)
Confidence is calculated based on:
- Staleness: Up to -0.4 penalty for old data
- Spread: Up to -0.2 penalty for wide spreads
- Sequence gaps: -0.05 per gap (max -0.3)
- If
UNAVAILABLE: confidence = 0
Recommendation: Only trade when confidence > 0.7
Complete Example (React)
import { useEffect, useState, useRef } from 'react';
import { io } from 'socket.io-client';
function OrderbookWidget({ symbol }) {
const [orderbook, setOrderbook] = useState(null);
const [globalBook, setGlobalBook] = useState(null);
const [connected, setConnected] = useState(false);
const socketRef = useRef(null);
useEffect(() => {
// Connect to WebSocket
const socket = io('wss://api.renesis.fi', {
transports: ['websocket'],
path: '/order-execution/socket.io'
});
socketRef.current = socket;
socket.on('connect', () => {
console.log('Connected to orderbook stream');
setConnected(true);
});
socket.on('connected', (data) => {
console.log('Server acknowledged:', data.message);
});
socket.on('subscribed', (data) => {
console.log(`Subscribed to ${data.symbol}`);
});
socket.on('orderbook_update', (data) => {
// Update orderbook state for specific venue
setOrderbook(prev => ({
...prev,
[data.venue]: data
}));
});
socket.on('global_book', (data) => {
// Update global aggregated view
setGlobalBook(data.data);
});
socket.on('orderbook_snapshot', (data) => {
// Initialize with full snapshot
setOrderbook(data.venues);
});
socket.on('error', (data) => {
console.error('Orderbook error:', data.message);
});
socket.on('disconnect', () => {
setConnected(false);
});
return () => {
socket.disconnect();
};
}, []);
// Subscribe when symbol changes
useEffect(() => {
if (connected && socketRef.current) {
// Unsubscribe from previous symbol
socketRef.current.emit('unsubscribe_orderbook', { symbol });
// Subscribe to new symbol
socketRef.current.emit('subscribe_orderbook', {
symbol,
venues: ['binance', 'bybit', 'gateio'],
include_global: true,
depth: 10
});
}
}, [symbol, connected]);
if (!connected) {
return <div>Connecting...</div>;
}
return (
<div>
{/* Global Best Prices */}
{globalBook && (
<div className="global-book">
<h3>Best Prices</h3>
<div>
Best Bid: ${globalBook.best_bid?.price}
@ {globalBook.best_bid?.venue}
</div>
<div>
Best Ask: ${globalBook.best_ask?.price}
@ {globalBook.best_ask?.venue}
</div>
</div>
)}
{/* Per-Venue Orderbooks */}
{orderbook && Object.entries(orderbook).map(([venue, data]) => (
<div key={venue} className="venue-book">
<h4>{venue} ({data.quality})</h4>
<div className="bids">
{data.bids?.slice(0, 5).map(([price, qty], i) => (
<div key={i}>{price} - {qty}</div>
))}
</div>
<div className="asks">
{data.asks?.slice(0, 5).map(([price, qty], i) => (
<div key={i}>{price} - {qty}</div>
))}
</div>
</div>
))}
</div>
);
}
export default OrderbookWidget;
Unsubscribing
// Unsubscribe from specific symbol
socket.emit('unsubscribe_orderbook', { symbol: 'BTC/USDT' });
// Disconnect completely
socket.disconnect();
Error Handling
socket.on('error', (data) => {
console.error('Orderbook error:', data.message);
// Common errors:
// - "symbol is required"
// - "Invalid venue"
// - "Subscription failed"
});
socket.on('disconnect', (reason) => {
console.log('Disconnected:', reason);
// Implement reconnection logic if needed
});
- Limit depth - Use
depth: 5 unless you need more levels
- Filter venues - Only subscribe to venues you’ll display
- Throttle UI updates - Don’t re-render on every update (10-20/sec)
- Use
include_global: false if you only need raw venue data
- Unsubscribe when components unmount
REST Fallback
If WebSocket is unavailable, use REST endpoints:
# Get current orderbook
curl -H "Authorization: Bearer $TOKEN" \
"https://api.renesis.fi/order-execution/orderbook/book?symbol=BTC/USDT"
# Get quality metrics
curl -H "Authorization: Bearer $TOKEN" \
"https://api.renesis.fi/order-execution/orderbook/quality?symbol=BTC/USDT"
See Orderbook REST API for full REST documentation.