Public API

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.

Key Features Real-time market data streams, unified order management across exchanges, portfolio tracking, and instant execution notifications.

WebSocket Server URLs

TEST: wss://test.opentrade.io/exchange/ws
PROD: wss://opentrade.io/exchange/ws

Available Channels

Public Channels (No Authentication Required)
  • ASSET_LIST
  • INSTRUMENT_LIST
  • ORDER_BOOK_PUBLIC
  • TRADE_PUBLIC
  • ACTIVE_SUBSCRIPTIONS
Private Channels (Authentication Required)
  • BALANCE
  • TRADE_PRIVATE
See the Private API documentation for details on these channels.

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.

JavaScript Example
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.

Subscription Structure
{
    "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)

Request
{
    "command": "SUBSCRIBE",
    "signature": "",
    "channelArgs": [
        {
            "name": "currency",
            "value": "[BTC, USDT]"
        }
    ],
    "channel": "BALANCE"
}
Response
{
    "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

Connection Rate Limit The rate limit for wss://opentrade.io/exchange/ws is set at 5 connections per 15 seconds.

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

Critical! Failure to send a heartbeat within two minutes will lead to connection closure by the server!

Ping is a service that users need to upkeep to notify that WebSocket connection is still open.

PING Keep Alive

Maintains the WebSocket connection active. Must be sent at least once every 2 minutes.

Request
{
    "command": "PING",
    "channel": "PING"
}
Response
{
    "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.

GET Asset List

Provides a list of supported assets and their trading specifications.

Request
{
    "command": "GET",
    "channel": "ASSET_LIST"
}
Response
{
    "event": "GET",
    "channel": "ASSET_LIST",
    "data": [
        {
            "class": "Currency",
            "code": "USC",
            "name": null
        },
        ...
    ]
}
GET Instrument List

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.

Request
{
    "command": "GET",
    "channel": "INSTRUMENT_LIST"
}
Response
{
    "event": "GET",
    "channel": "INSTRUMENT_LIST",
    "data": [
        {
            "class": "Instrument",
            "quoteCurrencyCode": "BAT",
            "code": "BAT/ETH",
            "name": null
        },
        ...
    ]
}
Order Book (Price Book)

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.

Subscribe Request
{
    "command": "SUBSCRIBE",
    "channel": "ORDER_BOOK_PUBLIC",
    "channelArgs": [
        {
            "name": "instrument",
            "value": "[USD/ADA,ETH/BTC]"
        }
    ]
}
Acknowledgment
{
    "command": "SUBSCRIBE",
    "event": "ACK",
    "channel": "ORDER_BOOK_PUBLIC"
}
Data Update
{
    "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
        },
        ...
    ]
}
Trade Book

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.

Subscribe Request
{
    "command": "SUBSCRIBE",
    "channel": "TRADE_PUBLIC",
    "channelArgs": [
        {
            "name": "instrument",
            "value": "[USD/ADA,ETH/BTC]"
        }
    ]
}
Acknowledgment
{
    "command": "SUBSCRIBE",
    "event": "ACK",
    "channel": "TRADE_PUBLIC"
}
Data Update
{
    "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.

Authentication Steps
  1. Login with username and password to obtain a session cookie
  2. Use the session cookie to obtain a JWT token
  3. 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.

Login Endpoints
// 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
Important! The username and password keys MUST be in lowercase. After successful login, you will receive a JSESSIONID cookie that you need for the next step.

Step 2: Obtain JWT Token

Use the JSESSIONID cookie from Step 1 to obtain your JWT token.

Token Endpoints
// 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 Example
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 ""
Success! The response will contain your JWT token. Use this token as the "signature" parameter in all private channel requests.

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.

Example with Token
{
    "command": "SUBSCRIBE",
    "signature": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "channel": "BALANCE",
    "channelArgs": [
        {
            "name": "currency",
            "value": "[BTC,USD]"
        }
    ]
}
Token Management Tips:
  • 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
Next Steps For information on Private Channels, Order Management, and Trading operations, please see the Private API documentation (Part 2).