Introduction
Open Trade provides Quotes and Limit Order book for SPOT Crypto. This document describes Open Trade WebSocket communication with Open Trade trading services.
Open Trade Taker WEBSOCKET API provides the ability to connect to the venue server, subscribe to market data, place and control orders, receive executions and updates. The API is based on WEBSOCKET specification.
WebSocket Server URLs
Available Channels
- ASSET_LIST
- INSTRUMENT_LIST
- ORDER_BOOK_PUBLIC
- TRADE_PUBLIC
- ACTIVE_SUBSCRIPTIONS
- BALANCE
- TRADE_PRIVATE
Precision & Symbols
Price Precision
The precision level of all trading prices is based on significant figures. All pairs on Bitfinex use up to 7 significant digits and up to 8 decimals (e.g., 1.234567, 123.4567, 1234.567, 0.0001234567). Prices submitted with a precision larger than 7 will be cut by the API.
Amount Precision
The amount field allows up to 8 decimals. Anything exceeding this will be rounded to the 8th decimal.
Symbols
A symbol can be a trading pair or a margin currency.
Connection
Establishing Connection
Connect to the WebSocket endpoint using any standard WebSocket client. Upon connection, you'll receive a confirmation message.
const ws = new WebSocket('wss://opentrade.io/exchange/ws');
ws.onopen = () => {
console.log('Connected to Open Trade');
// Send ping every 30 seconds to keep connection alive
setInterval(() => {
ws.send(JSON.stringify({
command: "PING",
channel: "PING"
}));
}, 30000);
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Received:', data);
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('Connection closed');
};
Subscription
Subscription is required to establish a data channel the server will push updates to. If private channels are required, the valid API key must be provided in every Subscribe request.
{
"requestId": "123",
"command": "SUBSCRIBE",
"signature": "put your token here for private channels",
"channel": "CHANNEL_NAME",
"channelArgs": [
{
"name": "parameter_name",
"value": "parameter_value"
}
]
}
Example: Subscribe to Balance (Private Channel)
{
"command": "SUBSCRIBE",
"signature": "",
"channelArgs": [
{
"name": "currency",
"value": "[BTC, USDT]"
}
],
"channel": "BALANCE"
}
{
"command": "SUBSCRIBE",
"event": "SNAPSHOT",
"channel": "BALANCE",
"channelArgs": [
{
"name": "currency",
"value": "[BTC, USDT]"
}
],
"data": [
{
"class": "Balance",
"currencyCode": "USDT",
"balance": 313037.3739066097,
"available": 313037.3739066097,
"locked": 0.0
},
{
"class": "Balance",
"currencyCode": "BTC",
"balance": 3.28944117,
"available": 2.7886285699999998,
"locked": 0.5008126
}
]
}
Rate Limits
To ensure fair usage and system stability, rate limits are enforced on WebSocket connections. Exceeding these limits may result in temporary connection rejection.
Heartbeat / Ping
Ping is a service that users need to upkeep to notify that WebSocket connection is still open.
Maintains the WebSocket connection active. Must be sent at least once every 2 minutes.
{
"command": "PING",
"channel": "PING"
}
{
"event": "PONG",
"channel": "PING"
}
Public Channels
Public channels provide market data and instrument information without requiring authentication. These channels are available to all connected clients.
Provides a list of supported assets and their trading specifications.
{
"command": "GET",
"channel": "ASSET_LIST"
}
{
"event": "GET",
"channel": "ASSET_LIST",
"data": [
{
"class": "Currency",
"code": "USC",
"name": null
},
...
]
}
Provides a list of supported Instruments and their trading specifications. When no symbol is provided, all Instruments are returned, a specific Instrument is provided only selected is returned.
{
"command": "GET",
"channel": "INSTRUMENT_LIST"
}
{
"event": "GET",
"channel": "INSTRUMENT_LIST",
"data": [
{
"class": "Instrument",
"quoteCurrencyCode": "BAT",
"code": "BAT/ETH",
"name": null
},
...
]
}
Provides streaming services an order book for selected symbol, user needs to provide levels of order book to receive. MAX is 20. MIN is 1. Order books are sorted based on NBBO price: BIDs best (Max) first then descending, ASKs best (MIN) first then ascending. The whole Order book is updated every 20MS regardless of changes.
{
"command": "SUBSCRIBE",
"channel": "ORDER_BOOK_PUBLIC",
"channelArgs": [
{
"name": "instrument",
"value": "[USD/ADA,ETH/BTC]"
}
]
}
{
"command": "SUBSCRIBE",
"event": "ACK",
"channel": "ORDER_BOOK_PUBLIC"
}
{
"command": "SUBSCRIBE",
"event": "UPDATE",
"channel": "ORDER_BOOK_PUBLIC",
"data": [
{
"class": "OrderBook",
"exchange": "CROSSTOWER",
"symbol": "BTC/USD",
"bids": [
[19292.21, 0.0124],
[19242.45, 3.0516],
[10000.0, 0.0002]
],
"asks": [
[85100.0, 0.01009],
[19397.85, 21.6067],
[84300.0, 0.00854]
],
"eventTime": 1664651366635
},
...
]
}
Provides streaming services a trading book (public trades) for selected symbol. Once subscribed updates will be pushed to user as they appear at Open Trade.
{
"command": "SUBSCRIBE",
"channel": "TRADE_PUBLIC",
"channelArgs": [
{
"name": "instrument",
"value": "[USD/ADA,ETH/BTC]"
}
]
}
{
"command": "SUBSCRIBE",
"event": "ACK",
"channel": "TRADE_PUBLIC"
}
{
"command": "SUBSCRIBE",
"event": "UPDATE",
"channel": "TRADE_PUBLIC",
"data": [
{
"class": "PublicTrade",
"exchange": "OKCOIN",
"symbol": "BTC/USD",
"price": 19308.6,
"quantity": 0.0103,
"tradeSide": "BUY",
"eventTime": 1664651920827
},
...
]
}
Authentication
To access private channels (Balance, Private Trades, Order Management), you need to obtain an authentication token through a two-step process.
- Login with username and password to obtain a session cookie
- Use the session cookie to obtain a JWT token
- Use the JWT token as the "signature" parameter in private channel requests
Authentication Flow
Step 1: Login with Username and Password
Using POST method, send your credentials to the login endpoint. Note that the credentials must be sent as form-data with keys in lowercase.
// TEST Environment
POST https://test.opentrade.io/auth/login
// PROD Environment
POST https://opentrade.io/auth/login
// Form Data (lowercase keys!)
username: your_username
password: your_password
Step 2: Obtain JWT Token
Use the JSESSIONID cookie from Step 1 to obtain your JWT token.
// TEST Environment
GET https://test.opentrade.io/auth/auth/jwt/client/{client-api-username}/token?clientSecret={secret}
// PROD Environment
GET https://opentrade.io/auth/auth/jwt/client/{client-api-username}/token?clientSecret={secret}
// Headers
Cookie: JSESSIONID={session_cookie_from_step_1}
Complete Authentication Flow with cURL
curl -s --cookie-jar cookies.txt -X POST \
"https://test.opentrade.io/auth/login" \
-d "username=[USER_NAME]&password=[USER_PASSWORD]" \
--next -s -b cookies.txt -X POST \
"https://test.opentrade.io/auth/auth/jwt/clients/[API_USER_NAME]/token" \
-H "accept: */*" \
-H "clientSecret: [API_SECRET]" \
-d ""
Using Your Token
Once you have obtained your JWT token from the authentication process, include it in every private channel request as the "signature" field.
{
"command": "SUBSCRIBE",
"signature": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"channel": "BALANCE",
"channelArgs": [
{
"name": "currency",
"value": "[BTC,USD]"
}
]
}
- Store your token securely and never expose it in client-side code
- Tokens typically expire after a certain period - monitor for authentication errors
- Implement token refresh logic to maintain continuous connection
- Use environment variables to manage tokens in different environments