NAV Navbar
shell python java

BitMax Pro API Documentation

BitMax Pro API is the latest release of APIs allowing our users to access the exchange programmatically. It is a major revision of the older releases. The BitMax team re-implemented the entire backend system in support for the BitMax Pro API. It is designed to be fast, flexible, stable, and comprehensive.

What's New

Demo codes

We provide comprehensive demos (currently available in python). We provide two types of demo codes:

See https://github.com/bitmax-exchange/bitmax-pro-api-demo for more details.

Release Note

2020-08-10

2020-08-06

2020-07-17

2019-12-26

REST APIs

We always respond with json include code field to indicate request result. 0 usually means success response, and you could find data in json format in field data; any code other than 0 indicate failure during the request process. For failure response, usually you could find detailed error in fields message, reason, and possibly extra info.

For private data, such as open order, balance, we usually include accountId, and accountCategory value in top level of response.

Authenticate a RESTful Request

Create Request

To access private data via RESTful APIs, you must include the following headers:

The timestamp in the header will be checked against server time. If the difference is greater than 30 seconds, the request will be rejected.

Sign a Request

Signing a RESTful Request

# bash 
APIPATH=user/info
APIKEY=CEcrjGyipqt0OflgdQQSRGdrDXdDUY2x
SECRET=hV8FgjyJtpvVeAcMAgzgAFQCN36wmbWuN7o3WPcYcYhFd8qvE43gzFGVsFcCqMNk
TIMESTAMP=`date +%s%N | cut -c -13` # 1562952827927
MESSAGE=$TIMESTAMP+$APIPATH
SIGNATURE=`echo -n $MESSAGE | openssl dgst -sha256 -hmac $SECRET -binary | base64`
echo $SIGNATURE  # vBZf8OQuiTJIVbNpNHGY3zcUsK5gJpwb5lgCgarpxYI=

curl -X GET -i \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "x-auth-key: $APIKEY" \
  -H "x-auth-signature: $SIGNATURE" \
  -H "x-auth-timestamp: $TIMESTAMP" \
  https://bitmax.io/api/pro/v1/info
# python 3.6+
import time, hmac, hashlib, base64

api_path  = "user/info"
api_key   = "CEcrjGyipqt0OflgdQQSRGdrDXdDUY2x"
sec_key   = "hV8FgjyJtpvVeAcMAgzgAFQCN36wmbWuN7o3WPcYcYhFd8qvE43gzFGVsFcCqMNk"
timestamp = int(round(time.time() * 1e3)) # 1562952827927

message = bytes(f"{timestamp}+{api_path}", 'utf-8')
secret = bytes(sec_key, 'utf-8')

signature = base64.b64encode(hmac.new(secret, message, digestmod=hashlib.sha256).digest())

header = {
  "x-auth-key": api_key,
  "x-auth-signature": signature, 
  "x-auth-timestamp": timestamp,
}
print(signature)  # b'vBZf8OQuiTJIVbNpNHGY3zcUsK5gJpwb5lgCgarpxYI='
// java 1.8+
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

public class SignatureExample {

  public static void main(String[] args) {
    try {
      long timestamp = System.currentTimeMillis(); // 1562952827927
      String api_path = "user/info";
      String secret = "hV8FgjyJtpvVeAcMAgzgAFQCN36wmbWuN7o3WPcYcYhFd8qvE43gzFGVsFcCqMNk";
      String message = timestamp + "+" + api_path;

      Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
      SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
      sha256_HMAC.init(secret_key);

      String hash = Base64.encodeBase64String(sha256_HMAC.doFinal(message.getBytes()));
      System.out.println(hash); // vBZf8OQuiTJIVbNpNHGY3zcUsK5gJpwb5lgCgarpxYI=
    }
    catch (Exception e) {
      System.out.println("Error");
    }
  }
}

To query APIs with private data, you must include a signature using base64 encoded HMAC sha256 algorithm. The prehash string is <timestamp>+<api-path>. The timestamp is the UTC timestamp in milliseconds.

See the code demos in (bash/python/java) on the right.

Market Data (Public)

You don't need to sign the request to access public market data.

List all Assets

List all Assets

curl -X GET https://bitmax.io/api/pro/v1/assets

Sample Response

{
    "code": 0,
    "data": [
        {   
        "assetCode" : "BTC",
            "assetName" : "Bitcoin",
            "precisionScale" : 9,
            "nativeScale" : 8,
            "withdrawalFee" : "5.0E-4",
            "minWithdrawalAmt" : "0.01",
            "status" : "Normal"
        }
    ]
}

HTTP Request

GET /api/pro/v1/assets

You can obtain a list of all assets listed on the exchange through this API.

Response Content

Name Type Description
assetCode String asset code. e.g. "BTC"
assetname String full name of the asset, e.g. "Bitcoin"
minWithdrawalAmt String minimum amount required for the withdrawal request e.g. "5.0E-4"
nativeScale Int scale used in deposit/withdraw transaction from/to chain.
positionScale Int scale used in internal position keeping.
withdrawFee String fee charged for each withdrawal request. e.g. "0.01"
status String values: Normal, NoDeposit, NoWithdraw, NoTransaction

List all Products

List all Products

curl -X GET https://bitmax.io/api/pro/v1/products

Sample Response

{
    "code": 0,
    "data": [
        {
            "symbol":                "BTMX/USDT",
            "baseAsset":             "BTMX",
            "quoteAsset":            "USDT",
            "status":                "Normal",
            "minNotional":           "5",
            "maxNotional":           "100000",
            "marginTradable":         true,
            "commissionType":        "Quote",
            "commissionReserveRate": "0.001",
            "tickSize":              "0.000001",
            "lotSize":               "0.001"
        }
    ]
}

HTTP Request

GET /api/pro/v1/products

Response Content

You can obtain a list of all products traded on the exchange through this API.

The response contains the following general fields:

Name Type Description
symbol String e.g. "BTMX/USDT"
baseAsset String e.g. "BTMX"
quoteAsset String e.g. "USDT"
status String "Normal"

The response also contains criteria for new order request.

Name Type Description
minNotional String minimum notional of an order
maxNotional String maximum notional of an order
tickSize String tick size of order price
lotSize String lot size of order quantity
marginTradable Boolean true if the product is tradable in the margin account; false otherwise.
commissionType String "Base", "Quote", "Received"
commissionReserveRate String e.g. "0.001", see below.

When placing orders, you should comply with all criteria above. More details can be found in the Order Request Criteria section.

Ticker

Ticker for one product

// curl -X GET 'https://bitmax.io/api/pro/v1/ticker?symbol=BTMX/USDT'
{
    "code": 0,
    "data": {
        "symbol": "BTMX/USDT",
        "open":   "0.06777",
        "close":  "0.06809",
        "high":   "0.06899",
        "low":    "0.06708",
        "volume": "19823722",
        "ask": [
            "0.0681",
            "43641"
        ],
        "bid": [
            "0.0676",
            "443"
        ]
    }
}

List of Tickers for one or multiple products

// curl -X GET "https://bitmax.io/api/pro/v1/ticker?symbol=BTMX/USDT,"
{
    "code": 0,
    "data": [
        {
            "symbol": "BTMX/USDT",
            "open":   "0.06777",
            "close":  "0.06809",
            "high":   "0.06809",
            "low":    "0.06809",
            "volume": "19825870",
            "ask": [
                "0.0681",
                "43641"
            ],
            "bid": [
                "0.0676",
                "443"
            ]
        }
    ]
}

HTTP Request

GET api/pro/v1/ticker

You can get summary statistics of one or multiple symbols with this API.

Request Parameters

Name Type Required Value Range Description
symbol String No you may specify one, multiple, or all symbols of interest. See below.

This API endpoint accepts one optional string field symbol:

Respond Content

The API will respond with a ticker object or a list of ticker objects, depending on how you set the symbol parameter.

Each ticker object contains the following fields:

Field Type Description
symbol String
open String the traded price 24 hour ago
close String the last traded price
high String the highest price over the past 24 hours
low String the lowest price over the past 24 hours
volume String the total traded volume in quote asset over the paste 24 hours
ask [String, String] the price and size at the current best ask level
bid [String, String] the price and size at the current best bid level

Code Sample

Please refer to python code to [query ticker info]{https://github.com/bitmax-exchange/bitmax-pro-api-demo/blob/master/python/query_pub_ticker.py}

Bar Info

Request

curl -X GET https://bitmax.io/api/pro/v1/barhist/info

Sample response

{
    "code": 0,
    "data": [
        {
            "name": "1",
            "intervalInMillis": 60000
        },
        {
            "name": "5",
            "intervalInMillis": 300000
        },
        {
            "name": "15",
            "intervalInMillis": 900000
        },
        {
            "name": "30",
            "intervalInMillis": 1800000
        },
        {
            "name": "60",
            "intervalInMillis": 3600000
        },
        {
            "name": "120",
            "intervalInMillis": 7200000
        },
        {
            "name": "240",
            "intervalInMillis": 14400000
        },
        {
            "name": "360",
            "intervalInMillis": 21600000
        },
        {
            "name": "720",
            "intervalInMillis": 43200000
        },
        {
            "name": "1d",
            "intervalInMillis": 86400000
        },
        {
            "name": "1w",
            "intervalInMillis": 604800000
        },
        {
            "name": "1m",
            "intervalInMillis": 2592000000
        }
    ]
}

HTTP Request

GET /api/pro/v1/barhist/info

This API returns a list of all bar intervals supported by the server.

Request Parameters

This API endpoint does not take any parameters.

Resposne

Name Type Description
name String name of the interval
intervalInMillis Long length of the interval

Plesae note that the one-month bar (1m) always resets at the month start. The intervalInMillis value for the one-month bar is only indicative.

The value in the name field should be your input to the Historical Bar Data API.

Historical Bar Data

Request

curl -X GET https://bitmax.io/api/pro/v1/barhist?symbol=BTMX/USDT&interval=1

Sample response

{
    "code": 0,
    "data": [
        {
            "data": {
                "c": "0.05019",
                "h": "0.05019",
                "i": "1",
                "l": "0.05019",
                "o": "0.05019",
                "ts": 1575409260000,
                "v": "1612"},
           "m": "bar",
           "s": "BTMX/USDT"},
        {
            "data": {
                "c": "0.05019",
                "h": "0.05027",
                "i": "1",
                "l": "0.05017",
                "o": "0.05017",
                "ts": 1575409200000,
                "v": "57242"
                },
           "m": "bar",
           "s": "BTMX/USDT"},
    ]
}

HTTP Request

GET /api/pro/v1/barhist

This API returns a list of bars, with each contains the open/close/high/low prices of a symbol for a specific time range.

Request Parameters

Name Type Required Description
symbol String Yes e.g. "BTMX/USDT"
interval String Yes a string representing the interval type.
to Long No UTC timestamp in milliseconds. If not provided, this field will be set to the current time.
from Long No UTC timestamp in milliseconds.
n Int No default 10, number of bars to be returned, this number will be capped at 500

The requested time range is determined by three parameters - to, from, and n - according to rules below:

Response

Name Type value Description
m String bar message type
s String symbol
data:ts Long bar start time in milliseconds
i String interval
o String open price
c String close price
h String high price
l String low price
v String volume in quote asset

Code Sample

Please refer python code to [get bar history]{https://github.com/bitmax-exchange/bitmax-pro-api-demo/blob/master/python/query_pub_barhist.py}

Order Book (Depth)

Request for Order Book (Depth) Data

curl -X GET https://bitmax.io/api/pro/v1/depth?symbol=BTMX/USDT

Order Book (Depth) Data - Sample response

{
    "code": 0,
    "data": {
        "m":      "depth-snapshot",
        "symbol": "BTMX/USDT",
        "data": {
            "seqnum":  5068757,
            "ts":      1573165838976,
            "asks": [
                [
                    "0.06848",
                    "4084.2"
                ],
                [
                    "0.0696",
                    "15890.6"
                ]
            ],
            "bids": [
                [
                    "0.06703",
                    "13500"
                ],
                [
                    "0.06615",
                    "24036.9"
                ]
            ]
        }
    }
}

HTTP Request

GET /api/pro/v1/depth

Request Parameters

Name Type Required Value Range Description
symbol String Yes Valid symbol supported by exchange

Response Content

data field in response contains depth data and meta info.

Name Type Description
m String "depth-snapshot"
symbol String e.g. "BTMX/USDT"
data Json actual bid and ask info. See below for detail.

Actual depth data in data section:

Name Type Description
seqnum Long a sequence number that is guaranteed to increase for each symbol.
ts Long UTC timestamp in milliseconds when the message is generated by the server
asks [String, String] pair of price and size of ask levels
bids [String, String] pair of price and size of bid levels

Demo Sample

Pleas refer to python code to take depth snapshot

Market Trades

Request

curl -X GET /api/pro/v1/trades?symbol=BTMX/USDT

Sample response

{
    "code": 0,
    "data": {
        "m": "trades",
        "symbol": "BTMX/USDT",
        "data": [
            {
                "seqnum": 144115191800016553,
                "p": "0.06762",            
                "q": "400",
                "ts": 1573165890854,
                "bm": false               // is buyer maker?
            },
            {
                "seqnum": 144115191800070421,
                "p": "0.06797",
                "q": "341",
                "ts": 1573166037845,
                "bm": true
            }
        ]
    }
}

HTTP Request

GET /api/pro/v1/trades

Request Parameters

Name Type Required Value Range Description
symbol String Yes Valid symbol supported by exchange
n Int No any positive integer, capped at 100 number of trades to return.

Response Content

data field in response contains trade data and meta info.

Name | Type | Description m | String | trades symbol | String | trade symbol data | Json | A list of trade record; see below for detail.

Trade record information in data:

Name Type Description
seqnum Long the sequence number of the trade record. seqnum is always increasing for each symbol, but may not be consecutive
p String trade price in string format
q String trade size in string format
ts Long UTC timestamp in milliseconds
bm Boolean If true, the maker of the trade is the buyer.

Code Sample

Please refer to python code to [query trades]{https://github.com/bitmax-exchange/bitmax-pro-api-demo/blob/master/python/query_pub_trades.py}

Account

Account Info

Account Info - Sample response:

{
    "code": 0,
    "data": {
        "accountGroup": 0,
        "email": "yyzzxxz@gmail.com",
        "expireTime": 1604620800000,         // expire time, UTC timestamp in milliseconds. If -1, the api key will not expire
        "allowedIps": ["123.123.123.123"],
        "cashAccount": [
            "dadFNEYEJIJ93CRxdafd3LTCIDIJPCFNIX"
        ],
        "marginAccount": [
            "mar2z3CMIEQx4UadasbtQ9JcxWJYgHmcb"
        ],
        "userUID":            "U0866943712",
        "tradePermission":     True,
        "transferPermission":  True,
        "viewPermission":      True
    }
}

HTTP Request

GET /api/pro/v1/info

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

prehash string

<timestamp>+info

Obtain the account information.

You can obtain your accountGroup from this API, which you will need to include in the URL for all your private RESTful requests.

Response Content

Name Type Description
accountGroup Int non-negative integer
email String
expireTime Long the time when the API key will be expired (UTC timestamp in milliseconds). If -1, the api key will not expire
allowedIps List[String] list of IPs allowed for the api key
cashAccount List[String]
marginAccount List[String]
tradePermission Boolean
transferPermission Boolean
viewPermission Boolean
userUID String an unique id associated with user

See a demo at query private account info.

Fee Schedule

@ToDo

Balance

Cash Account Balance

Cash Account Balance - Sample response

{
    "code": 0,
    "data": [
        {
            "asset":            "USDT",
            "totalBalance":    "1285.366663467",
            "availableBalance": "1285.366663467"
        },
        {
            "asset":            "BTC",
            "totalBalance":    "22.1308675",
            "availableBalance": "16.1308675"
        },
        {
            "asset":            "ETH",
            "totalBalance":     "0.6",
            "availableBalance": "0.6"
        }
    ]
}

HTTP Request

GET <account-group>/api/pro/v1/cash/balance

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+balance

Request Parameters

Name Type Required Value Range Description
asset String No valid asset code this allow you query single asset balance, e.g. BTC
showAll Boolean No true / false by default, the API will only respond with assets with non-zero balances. Set showAll=true to include all assets in the response.

Response Content

Name Type Description Sample Response
asset String asset code "USDT"
totalBalance String total balance in string format "1234.56"
availableBalance String available balance in string format "234.56"

Code Sample

Please refer to python code to query balance

Margin Account Balance

Margin Account Balance - Sample response

{
    "code": 0,
    "data": [
        {
            "asset":            "USDT",
            "totalBalance":     "11200",
            "availableBalance": "11200",
            "borrowed":         "0",
            "interest":         "0"
        },
        {
            "asset":            "ETH",
            "totalBalance":     "20",
            "availableBalance": "20",
            "borrowed":         "0",
            "interest":         "0"
        }
    ]
}

HTTP Request

GET <account-group>/api/pro/v1/margin/balance

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+balance

Request Parameters

Name Type Required Value Range Description
asset String No valid asset code this allow you query single asset balance, e.g. BTC
showAll Boolean No true / false by default, the API will only respond with assets with non-zero balances. Set showAll=true to include all assets in the response.

Response Content

Name Type Description Sample Response
asset String asset code "USDT"
totalBalance String total balance "1234.56"
availableBalance String available balance "234.56"
borrowed String borrowed amount "0"
interest String interest owed "0"

Margin Risk Profile

Margin Account Risk Profile - Sample response

{
    "code": 0,
    "data": {
        "accountMaxLeverage":     "10",
        "availableBalanceInUSDT": "17715.8175",
        "totalBalanceInUSDT":     "17715.8175",
        "totalBorrowedInUSDT":    "0",
        "totalInterestInUSDT":    "0",
        "netBalanceInUSDT":       "17715.8175",
        "pointsBalance":          "0",
        "currentLeverage":        "1",
        "cushion":                "-1"
    }
}

HTTP Request

POST <account-group>/api/pro/v1/margin/risk

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+margin/risk

Code Sample

Please refer to python code to[query margin risk]{https://github.com/bitmax-exchange/bitmax-pro-api-demo/blob/master/python/query_prv_margin_risk.py}

Balance Transfer

Transfer from Cash To Margin - Sample request and response

Request

{
    "amount": "11.0",
    "asset": "USDT",
    "fromAccount": "cash",
    "toAccount": "margin"
}

Response

{
    "code": 0,
}

This api allows balance transfer between different accounts of the same user.

HTTP Request

GET <account-group>/api/pro/v1/transfer

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+transfer

Request Parameters

Name Type Required Value Range Description
amount String Yes Positive numerical string Asset amount to transfer.
asset String Yes Valid asset code
fromAccount String Yes cash/margin/futures
toAccount String Yes cash/margin/futures

Please note, we only support direct balance transfer between cash and margin, cash and futures.

Response Content

Response code value 0 indicate successful transfer.

Code Sample

Please refer to python code to transfer token amount different accounts

Wallet

Query Deposit Addresses

Query Deposit Addresses - Sample Response

{
    "code": 0,
    "data": {
        "asset": "USDT",
        "assetName": "Tether",
        "address": [{
                "address": "1P67...TnG3",
                "blockchain": "Omni",
                "destTag": ""
            },
            {
                "address": "0xd3...c466",
                "blockchain": "ERC20",
                "destTag": ""
            },
            {
                "address": "TPpK...ovJk",
                "blockchain": "TRC20",
                "destTag": ""
            }
        ]
    }
}

HTTP Request

GET /api/pro/v1/wallet/deposit/address

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+wallet/deposit/address

Request Parameters

Name Type Required Value Range Description
asset String Yes valid asset code this allow you query single asset balance, e.g. BTC
blockchain Boolean No blockchain name the (optional) blockchain filter

Response Content

Name Type Description Sample Response
asset String asset code "USDT"
assetName String asset name "Tether"
address List list of address objects

Content of elements in the address field:

Name Type Description Sample Response
address String wallet address
blockchain String blockchain name "ERC20"
destTag String the destination tag (or memo for some tokens) attached to the address. This field could be an empty string.

Code Sample

Please refer to python code to query deposit addresses

Query Wallet Transaction History

Query Wallet Transaction History - Sample Response

{
    "code": 0,
    "data": {
        "data": [{
                "asset": "USDT",
                "amount": "400",
                "commission": "0",
                "destAddress": {
                    "address": "1wX8...iHih"
                },
                "networkTransactionId": "Slc8...xo2d",
                "numConfirmations": 3,
                "numConfirmed": 0,
                "requestId": "ZgO7...cctn",
                "status": "confirmed",
                "time": 1595001735000,
                "transactionType": "withdrawal"
            }
        ],
        "hasNext": true,
        "page": 1,
        "pageSize": 2
    }
}

HTTP Request

GET /api/pro/v1/wallet/transactions

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+wallet/transactions

Request Parameters

Name Type Required Value Range Description
asset String No valid asset code this allow you query single asset balance, e.g. BTC
txType String No deposit / withdrwal add the (optional) transaction type filter
page Int No a positive interger the page number, starting at 1
pageSize Int No a positive interger the page size, must be positive

Response Content

Name Type Description Sample Response
asset String asset code "USDT"
amount String the transaction amount "400"
commission String the commission charged by the exchange "0"
destAddress Object the destination address, see below for details
networkTransactionId String the transaction hash ID
numConfirmations Int the minimun number of confirmations for the transaction to be viewed as confirmed.
numConfirmed Int current number of confirmations
requestId String the requestId of the request
status String pending / reviewing / confirmed / rejected / canceled / failed
time Long UTC timestamp in milliseconds, timestamp of the transaction.
transactionType String deposit / withdrawal

Content of elements in the destAddress field:

Name Type Description
address String wallet address
destTag Optional[String] the destination tag (or memo for some tokens) attached to the address. This field could be an empty string.

Code Sample

Please refer to python code to query wallet transactions

Order

Trading and Order related APIs. API path usually depend on account-group and account-category:

For all order related ack or data, there is orderId field to identify the order.

Generate Order Id

We use the following method to generate an unique id for each order place/cancel request. (You could get userUID from Account Info API.)

Method

Extra info on id

Code Sample

Please refer to python code to gen server order id

Place Order

Place Order - Successful ACK Response (Status 200, code 0)

{
    "code": 0,
    "data": {
        "ac": "MARGIN",
        "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
        "action": "place-order",
        "info": {
            "id":        "16e607e2b83a8bXHbAwwoqDo55c166fa",
            "orderId":   "16e85b4d9b9a8bXHbAwwoqDoc3d66830",
            "orderType": "Market",
            "symbol":    "BTC/USDT",
            "timestamp":  1573576916201
        },
        "status": "Ack"
    }
}

Place Order with ACCEPT respInst

{
    "id": "iGwzbzWxxcHwno4b8VCvh8aaYCJaPALm", 
    "time": 1575403713964, 
    "symbol": "BTC/USDT", 
    "orderPrice": "7289.0", 
    "orderQty": "0.00082", 
    "orderType": "limit", 
    "side": "sell", 
    "respInst": "ACCEPT"
}

Successful ACCEPT Response (Status 200, code 0)

{
    "code": 0,
    "data": {
        "ac": "CASH",
        "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
        "action": "place-order",          
        "info": {            
            "avgPx":        "0",
            "cumFee":       "0",
            "cumFilledQty": "0",
            "errorCode":    "",
            "feeAsset":     "USDT",
            "lastExecTime": 1575573998500,
            "orderId":      "a16ed787462fU9490877774N4KBHIVN0",
            "orderQty":     "0.00081",
            "orderType":    "Limit",
            "price":        "7019",
            "seqNum":       2323407894,
            "side":         "Buy",
            "status":       "New",
            "stopPrice":    "",
            "symbol":       "BTC/USDT",
            "execInst":     "NULL_VAL"
        },
        "status": "ACCEPT"
    }
}   

Place Order with DONE respInst

{
    "id":        "UHTe3uVB0KhNGatoRS10YgABwHW0fCYn", 
    "time":      1575348906131, 
    "symbol":    "BTC/USDT",
    "orderQty":  "0.00082", 
    "orderType": "market", 
    "side":      "buy", 
    "respInst":  "DONE"
}

Successful DONE Response (Status 200, code 0)

{"code": 0,
 "data": {
    "ac": "CASH",
    "accountId": "MPXFNEYEJIJ93CREXT3LTCIDIJPCFNIX",
    "action": "place-order",
    "info": {
        "avgPx": "7399.99",
        "cumFee": "0.003296696",
        "cumFilledQty": "0.00081",
        "errorCode": "",
        "feeAsset": "USDT",
        "id": "ROunD0hpprO2KEgkVK30FOIpPK3zuGGh",
        "lastExecTime": 1575646514077,
        "orderId": "a16edbd9aefaU9490877774pPK3zuGGh",
        "orderQty": "0.00081",
        "orderType": "Market",
        "price": "",
        "seqNum": 2348421435,
        "side": "Sell",
        "status": "Filled",
        "stopPrice": "",
        "symbol": "BTC/USDT",
        "execInst": "NULL_VAL"
    },
    "status": "DONE"}}

Place Order - Error Response (Status 200, code 300011)

{
    "code": 300011,
    "ac": "CASH",
    "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
    "action": "place-order",
    "info": {
        "id": "JkpnjJRuBtFpW7F7PWDB7uwBEJtUOISZ", 
        "symbol": "BTC/USDT"
    },
    "message": "Not Enough Account Balance",
    "reason": "INVALID_BALANCE",
    "status": "Err"
}

Place a new order.

HTTP Request

POST <account-group>/api/pro/v1/{account-category}/order

Set account-category tocash for cash account and margin for margin account.

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+order

Request Parameters

Name Type Required Value Range Description
symbol String Yes
time Long Yes milliseconds since UNIX epoch in UTC We do not process request placed more than 30 seconds ago.
orderQty String Yes Order size. Please set scale properly for each symbol.
orderType String Yes ["market", "limit", "stop_market", "stop_limit"] Order type
side String Yes ["buy", "sell"]
id String No >=9 chars(letter and digit number only) Optional but recommended. We echo it back to help you match response with request.
orderPrice String No The limit price for limit order. Please set price scale properly.
stopPrice String No Trigger price of stop limit order
postOnly Boolean No [true, false]
timeInForce String No ["GTC", "IOC"] GTC: good-till-canceled; IOC: immediate-or-cancel. GTC by default.
respInst String No ["ACK", "ACCEPT", "DONE"] Response instruction. Refer to "Response" below. "ACK" by default.

The table below shows how to correctly configure order of different types: (o - required, x - optional)

Name market limit stop_market stop_limit
id x x x x
time o o o o
symbol o o o o
orderPrice o o
orderQty o o o o
orderType o o o o
side o o o o
postOnly x
stopPrice o o
timeInForce x

Order Request Criteria

When placing a new limit order, the request parameters must meet all criteria defined in the Products API:

Response

In "Err" response, id is the id provided by user when placing order; for other responses, orderId is the id generated by server following "Order id generation method" above, and this is the id you should provide for future order query or cancel.

In case you want to cancel an order before response from server, you could figure out the orderId following Order id generation method above.

ACK

Response with 0 code and status Ack to indicate new order request received by our server and passed some basic order field check. This is the default response type. If awaiting async order (ACCEPT or DONE) numbers exceeds capacity 1000, then the rest async order will be ACK automatically.

data schema:

Name Type Description
avgPx String average fill price
cumFee String cumulated filled comission
cumFilledQty String cumulated filled qty
errorCode String Could be empty
feeAsset String Fee asset, e.g, USDT
id String id from request
lastExecTime String latest execution timestamp
orderId String order id, this is what you should provide for future order query or cancel.
orderQty String order quantity
orderType String order type
price String order price
seqNum Long sequence number
side String order side
status String order status
stopPrice String stop price(could be empty)
symbol String symbol
execInst String execution instruction, POST for Post-Only orders, Liquidation for forced-liquidation orders, and NULL_VAL otherwise.

ACCEPT

Response with 0 code and status ACCEPT to indicate new order request is accepted by our match engine. Return normal 'Ack' response if no 'New' status update within 5 seconds. Order status in data could be New, or PendingNew.

DONE

Response with 0 code and status Done to indicate the order request is partially filled, fully filled, or rejected by matching engine. Return normal 'Ack' response if no order status update within 5 seconds. Order status in data could be Filled, PartiallyFilled, Cancelled, or Reject, and so on.

ERR

Response with code other than 0 and status Err to provide detailed error information on the order request.

Name Type Description
code Long none 0 to indicate error
ac String CASH, MARGIN
accountId String account id
action String place-order
message String detail error message
reason String error info code, e.g. "INVALID_ORDER_ID"
status String "Err"
info Json See below for detail

info schema:

Name Type Description
symbol String symbol
id String id from request if provided

Error Response Messages (TODO: verify HTTP Status Code)

HTTP Status Code Error Code Reason Example
400 xxx Parameter Error

Code Sample

Refer to sample python code to place order

Cancel Order

Cancel Order - Successful ACK Response (Status 200, code 0)

{
    "code": 0,
    "data": {
        "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
        "ac": "CASH",
        "action": "cancel-order",
        "status": "Ack",
        "info": {
            "id":        "wv8QGquoeamhssvQBeHOHGQCGlcBjj23",
            "orderId":   "16e6198afb4s8bXHbAwwoqDo2ebc19dc",
            "orderType": "", // could be empty
            "symbol":    "ETH/USDT",
            "timestamp":  1573594877822
        }
    }
}

Cancel Order - Error Response (Status 200, code 0)

{
    "code": 300006,
    "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
    "ac": "CASH",
    "action": "cancel-order",
    "status": "Err",
    "message": "Invalid Client Order Id: jHAfoOqZmRv3GP1URJ5624moJ9RCG2@3",
    "reason":  "INVALID_ORDER_ID",
    "info": {
        "id": "jHAfoOqZmRv3GP1URJ5624moJ9RCG2@3",
        "symbol":  "ETH/USDT"
    }
}

Cancel an existing open order.

HTTP Request

DELETE <account-group>/api/pro/v1/{account-category}/order

Set account-category to cash for cash account and margin for margin account.

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+order

Request Parameters

Name Type Required Value Range Description
id String No 32 chars(letter and digit number only) We echo it back to help you identify the response if provided. This field is optional
orderId String Yes 32 chars order id responded by server when place order You should set the value to be the orderId of the target order you want to cancel.
symbol String Yes Symbol of the order to cancel
time Long Yes milliseconds since UNIX epoch in UTC We do not process request placed more than 30 seconds ago.

Response

ACK

Response with status "Ack" to indicate the cancel order request is received by server. And you should use provided "orderId" to check cancel status in the future; we also echo back id from your request for reference purpose.

ERR

Response with status "Err" to indicate there is something wrong with the cancel order request. We echo back the coid field in your request.

Code Sample

Refer to sample python code to cancel order

Cancel All Orders

Cancel All Orders - Successful ACK Response (Status 200, code 0)

{
    "code": 0,
    "data": {
        "ac": "CASH",
        "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
        "action": "cancel-all",
        "info": {
            "id":  "2bmYvi7lyTrneMzpcJcf2D7Pe9V1P9wy",
            "orderId":   "",
            "orderType": "NULL_VAL",
            "symbol":    "",
            "timestamp":  1574118495462
        },
        "status": "Ack"
    }
}

Cancel all current open orders for the account specified, and optional symbol.

HTTP Request

DELETE <account-group>/api/pro/v1/{account-category}/order/all

Set account-category tocash for cash account and margin for margin account.

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+order/all

Request Parameters

Name Type Required Value Range Description
symbol String No Valid symbol supported by exchange If provided, only cancel all orders on this symbol; otherwise, cancel all open orders under this account.

Response

Response include code and data, and status Ack (in field data) to indicate cancel all order request is received by server.

data schema:

Name Type Description
ac String CASH, MARGIN
accountId String account Id
action String cancel-all,
info Json See below for detail

info schema:

Name Type Description
id String echo back the id in request
orderId String empty
orderType String empty
symbol String symbol in request
timestamp Long server received timestamp

Code Sample

Refer to sample python code to cancel all order

Caveat

The server will process the cancel all request with best effort. Orders sent but un-acked will not be canceled. You should rely on websocket order update messages or the RESTful api to obtain the latest status of each order.

Place Batch Orders

Place Batch Orders - Successful ACK Response (Status 200, code 0)

{
    "code": 0,
    "data": {
        "ac": "CASH",
        "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",        
        "action": "batch-place-order",
        "info": [
            {
                "id":        "0r9LFylwSF3Pj6vOQC4j33Nv2pQnuFD9",
                "orderId":   "16e80b75cbda8bXHbAwwoqDoa5be7384",
                "orderType": "Limit",
                "symbol":    "BTC/USDT",
                "timestamp":  1573596819185
            },
            {
                "id":        "mYnbq6xcTLdAs9qzq1tY57lUZ1iWWIac",
                "orderId":   "16e61adeee5a8bXHbAwwoqDo100e364e",
                "orderType": "Limit",
                "symbol":    "BTC/USDT",
                "timestamp":  1573596819185
            }
        ],
        "status": "Ack"
    }
}

Place Batch Orders - Error Response (Status 200, code 0)

{
    "ac": "CASH",
    "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
    "action": "batch-place-order",
    "code": 300013,
    "info": [
        {
            "code": 300004,
            "id": "nGFdep927xsqSaL2B4R3jDSm1IGwcfmr",
            "message": "Notional is too small.",
            "reason": "INVALID_NOTIONAL",
            "symbol": "BTC/USDT"},
            {"code": 300013,
            "id": "PGEcSVsoQWythsYTs2hWfogLoRs6hhi8",
            "message": "Some invalid order in this batch.",
            "reason": "INVALID_BATCH_ORDER",
            "symbol": "ETH/USDT"}],
    "message": "Batch Order failed, please check each order info for detail.",
    "reason": "INVALID_BATCH_ORDER",
    "status": "Err"
}

Place multiple orders in a batch. If some order in the batch failed our basic check, then the whole batch request fail.

You may submit up to 10 orders at a time. Server will respond with error if you submit more than 10 orders.

HTTP Request

POST <account-group>/api/pro/v1/{account-category}/order/batch

Set account-category tocash for cash account and margin for margin account.

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+order/batch

Response

ACK

0 for code and status Ack to indicate the batch order request is accepted by server. Field "info" includes server generated "coid" for each order in the batch request, and this is the id you should use for future status query.

data schema:

Name Type Description
ac String CASH, MARGIN
accountId String account Id
action String cancel-all
status String Ack
info List See below for detail

info schema:

Name Type Description
id String echo back the id in request
orderId String server assigned order Id for this single order
orderType String order type
symbol String symbol in request
timestamp Long server received timestamp

ERR

Non 0 code and status ERR to indicate the batch order request is accepted by server. Field info includes detailed order information to explain why the batch request fail for each individual order. "coid" is original order id provided by user for each order.

Error schema

Name Type Description
code Long 0
ac String CASH, MARGIN
accountId String account Id
action String batch-cancel-order
message String error message detail
reason String short error message
status String Err
info List See below for detail

info schema:

Name Type Description
code Long 0
id String echo id in request
orderId String empty
message String error message detail
reason String short error message
symbol String symbol in order

Code Sample

Please refer to python code to place batch order

Cancel Batch Orders

Cancel Batch Orders - Successful ACK Response (Status 200, code 0)

{
    "code": 0,
    "data": {
        "ac": "CASH",
        "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
        "action": "batch-cancel-order",
        "status": "Ack",
        "info": [
            {
                "id":        "0a8bXHbAwwoqDo3b485d7ea0b09c2cd8",
                "orderId":   "16e61d5ff43s8bXHbAwwoqDo9d817339",
                "orderType": "NULL_VAL",
                "symbol":    "BTC/USDT",
                "timestamp":  1573619097746
            },
            {
                "id":        "0a8bXHbAwwoqDo7d303e2edf6c26d1be",
                "orderId":   "16e61adeee5a8bXHbAwwoqDo100e364e",
                "orderType": "NULL_VAL",
                "symbol":    "ETH/USDT",
                "timestamp":  1573619098342
            }
        ]
    }
}

Cancel Batch Orders - Error Response (Status 200, code 0)

{
    "code": 300013,
    "ac": "CASH",
    "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
    "action": "batch-place-order", 
    "message": "Batch Order failed, please check each order info for detail.",
    "reason": "INVALID_BATCH_ORDER",
    "status": "Err", 
    "info": [
        {
            "code":     300006,
            "id":      "NUty15oXcNt9JAngZ1D6q6jY15LOpKPC",
            "orderId": "16e61d5ff43s8bXHbAwwoqDo9d817339",
            "message": "The order is already filled or canceled.",
            "reason":  "INVALID_ORDER_ID",
            "symbol":   ""
        },
        {
            "code":     300006,
            "id":      "mpoL0q8cheL8PL2UstJFRzp6yuPk1sGc",
            "orderId": "16e61adeee5a8bXHbAwwoqDo100e364e",
            "message": "The order is already filled or canceled.",
            "reason":  "INVALID_ORDER_ID",
            "symbol":   ""
        }
    ]
}

Cancel multiple orders in a batch. If some order in the batch failed our basic check, then the whole batch request failed.

HTTP Request

DELETE <account-group>/api/pro/v1/{account-category}/order/batch

Set account-category tocash for cash account and margin for margin account.

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+order/batch

Response

ACK

Response with code as 0 to indicate batch is successfuly received by server and pass some basic check. data field explains order ack detail. Order detail for each order is in info field list.

data schema:

Name Type Description
ac String CASH, MARGIN
accountId String account Id
action String cancel-all
status String Ack
info List See below for detail

info schema:

Name Type Description
id String echo back the id in request
orderId String orderId in request to cancel
orderType String empty
symbol String symbol in request
timestamp Long server received timestamp

ERR

Response with non 0 code and status "Err" to explain detailed failure reason for each order in the batch request. Error detail for each order is in info field.

Error schema

Name Type Description
code Long 0
ac String CASH, MARGIN
accountId String account Id
action String batch-cancel-order
message String error message detail
reason String short error message
status String Err
info List See below for detail

info schema:

Name Type Description
code Long 0
id String echo id in request
orderId String orderId in request to cancel
message String error message detail
reason String short error message
symbol String symbol in order

Code Sample

please refer to python code to cancel batch order

Query Order

Query Order - Successful Response (Status 200, code 0)

{
    "code": 0,
    "accountCategory": "CASH",
    "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
    "data": [
        {
            "symbol":       "BTC/USDT",
            "price":        "8130.24",
            "orderQty":     "0.00082",
            "orderType":    "Limit",
            "avgPx":        "7391.13",
            "cumFee":       "0.005151618",
            "cumFilledQty": "0.00082",
            "errorCode":    "",
            "feeAsset":     "USDT",
            "lastExecTime": 1575953134011,
            "orderId":      "a16eee206d610866943712rPNknIyhH",
            "seqNum":       2622058,
            "side":         "Buy",
            "status":       "Filled",
            "stopPrice":    "",
            "execInst":     "NULL_VAL"
        },
        {
            "symbol":       "BTC/USDT",
            "price":        "8131.22",
            "orderQty":     "0.00082",
            "orderType":    "Market",
            "avgPx":        "7392.02",
            "cumFee":       "0.005152238",
            "cumFilledQty": "0.00082",
            "errorCode":    "",
            "feeAsset":     "USDT",
            "lastExecTime": 1575953151764,
            "orderId":      "a16eee20b6750866943712zWEDdAjt3",
            "seqNum":       2623469,
            "side":         "Buy",
            "status":       "Filled",
            "stopPrice":    "",
            "execInst":     "NULL_VAL"
        }
    ]
}

Query order status, either open or history order.

HTTP Request

GET <account-group>/api/pro/v1/{account-category}/order/status?orderId={orderId}

Set account-category tocash for cash account and margin for margin account.

Request Parameters

Name Type Required Value Range Description
orderId String No one or more order Ids separated by comma

orderId could be a single order Id, or multiple order Ids separated by a comma (,):

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+order/status

Response

Returns a list order information in data field. Please use orderId field to match with your order.

Name Type Description
avgPx String average fill price
cumFee String cumulated filled comission
cumFilledQty String cumulated filled qty
errorCode String Could be empty
feeAsset String Fee asset, e.g, USDT
lastExecTime String latest execution timestamp
orderId String order id
orderQty String order quantity
orderType String order type
price String order price
seqNum Long sequence number
side String order side
status String order status
stopPrice String stop price(could be empty)
symbol String symbol
execInst String execution instruction, POST for Post-Only orders, Liquidation for forced-liquidation orders, and NULL_VAL otherwise.

Code Sample

Please refer to python code to get order status

List Open Orders

Open Orders - Successful Response (Status 200, code 0)

{"ac": "CASH",
 "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
 "code": 0,
 "data": [
   {
     "avgPx": "0",         // Average filled price of the order   
      "cumFee": "0",       // cumulative fee paid for this order
      "cumFilledQty": "0", // cumulative filled quantity
      "errorCode": "",     // error code; could be empty
      "feeAsset": "USDT",  // fee asset
      "lastExecTime": 1576019723550, //  The last execution time of the order
      "orderId": "s16ef21882ea0866943712034f36d83", // server provided orderId
      "orderQty": "0.0083",  // order quantity
      "orderType": "Limit",  // order type
      "price": "7105",       // order price
      "seqNum": 8193258,     // sequence number
      "side": "Buy",         // order side
      "status": "New",       // order status on matching engine
      "stopPrice": "",       // only available for stop market and stop limit orders; otherwise empty 
      "symbol": "BTC/USDT",
      "execInst": "NULL_VAL" // execution instruction
    },
    ...
  ]
}

This API returns all current open orders for the account specified.

HTTP Request

GET <account-group>/api/pro/v1/{account-category}/order/open

Set account-category tocash for cash account and margin for margin account.

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+order/open

Request Parameters

Name Type Required Value Range Description
symbol String No A valid symbol add a symbol filter.

Response

Return a list of order infomation in data field:

Name Type Description
avgPx String average fill price
cumFee String cumulated filled comission
cumFilledQty String cumulated filled qty
errorCode String Could be empty
feeAsset String Fee asset, e.g, USDT
lastExecTime String latest execution timestamp
orderId String order id
orderQty String order quantity
orderType String order type
price String order price
seqNum Long sequence number
side String order side
status String order status
stopPrice String stop price(could be empty)
symbol String symbol
execInst String execution instruction, POST for Post-Only orders, Liquidation for forced-liquidation orders, and NULL_VAL otherwise.

Error Response Messages

HTTP Status Code Error Code Reason Example
400 xxx Parameter Error {"code": xxx, "message": "missing requird parameter \"account\"} "} @TODO

Code Sample

Please refer to python code to get open orders

Change from the previous version:

List Current History Orders

Current History Orders - Successful Response (Status 200, code 0)

{
    "ac": "CASH",
    "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
    "code": 0,
    "data": [
        {
            "avgPx": "7243.34",
            "cumFee": "0.051101764",
            "cumFilledQty": "0.0083",
            "errorCode": "",
            "feeAsset": "USDT",
            "lastExecTime": 1576019215402,
            "orderId": "s16ef210b1a50866943712bfaf1584b",
            "orderQty": "0.0083",
            "orderType": "Market",
            "price": "7967.62",
            "seqNum": 8159713,
            "side": "Buy",
            "status": "Filled",
            "stopPrice": "",
            "symbol": "BTC/USDT",
            "execInst": "NULL_VAL"
        },
        ...
    ]
}

This API returns all current history orders for the account specified. If you need earlier data or more filter, please refer to Order History API.

HTTP Request

GET <account-group>/api/pro/v1/{account-category}/order/hist/current

Set account-category tocash for cash account and margin for margin account.

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+order/hist/current

Request Parameters

Name Type Required Description
n Int No maximum number of orders to be included in the response
symbol String No symbol filter, e.g. "BTMX/USDT"
executedOnly Boolean No if True, include orders with non-zero filled quantities only.

Response

Return a list of history orders in "data" field.

Code Sample

Please refer to python code to get recent hist orders

List History Orders (Deprecated)

This API has been deprecated, please use list order history v2 instead.

If you still want to use the already deprecated api, please refer to List History Orders (Deprecated).

List History Orders (v2)

History Orders - Successful Response (Status 200, code 0)

{
  "code": 0,
  "data": [
    {
      "orderId"     :  "a173ad938fc3U22666567717788c3b66", // orderId
      "seqNum"      :  18777366360,                        // sequence number
      "accountId"   :  "cshwSjbpPjSwHmxPdz2CPQVU9mnbzPpt", // accountId 
      "symbol"      :  "BTC/USDT",                         // symbol
      "orderType"   :  "Limit",                            // order type (Limit/Market/StopMarket/StopLimit)
      "side"        :  "Sell",                             // order side (Buy/Sell)
      "price"       :  "11346.77",                         // order price
      "stopPrice"   :  "0",                                // stop price (0 by default)
      "orderQty"    :  "0.01",                             // order quantity (in base asset)
      "status"      :  "Canceled",                         // order status (Filled/Canceled/Rejected)
      "createTime"  :  1596344995793,                      // order creation time
      "lastExecTime":  1596344996053,                      // last execution time
      "avgFillPrice":  "11346.77",                         // average filled price
      "fillQty"     :  "0.01",                             // filled quantity (in base asset)
      "fee"         :  "-0.004992579",                     // cummulative fee. if negative, this value is the commission charged; if possitive, this value is the rebate received.
      "feeAsset"    :  "USDT"                              // fee asset
    }
  ]
}

This API returns history orders according to specified parameters (up to 500 records). You have access to at least 30 days of order history.

HTTP Request

GET <account-group>/api/pro/v2/order/hist

Signature

You should sign the message in header as specified in Authenticate a RESTful Request section.

Prehash String

<timestamp>+order/hist

Request Parameters

Name Type Required Description
account String Yes account type: cash/margin/futures, or actual accountId
symbol String No symbol filter, e.g. BTMX/USDT
startTime Long No start time in milliseconds.
endTime Long No end time in milliseconds.
seqNum Long No the seqNum to search from. All records in the response have seqNum no less than the input argument.
limit Int No number of records to return. default 500, max 1000.

Please note seqNum increases regirously but not continuously in response.

Rule for combination usage of startTime, endTime, and seqNum:

To retrieve the full history of orders, it is recommended to use seqNum and follow the procedure below:

Response

Return a list of history orders in "data" field.

Name Type Description
orderId String order id
seqNum Long sequence number
accountId String account Id
symbol String symbol
orderType String order type
side String order side
price String order price
stopPrice String stop price (0 by default)
orderQty String order quantity
status String order status
createTime Long order sending time
lastExecTime String latest execution timestamp
avgFillPrice String average fill price
fillQty String cumulated filled qty
fee String cummulative fee. if positive, this value is the commission charged; if negative, this value is the rebate received.
feeAsset String Fee asset, e.g, USDT

Code Sample

Please refer to python code to get hist orders

WebSocket

General Message Request/Handling Logic from Client Side

WebSocket Request

WSS <account-group>/api/pro/v1/stream

In order to authorize the session you must include <account-group> in the URL. Without <account-group>, you can only subscribe to public data.

Code Sample

Please refer to python code for all kinds of [websocket operation]{https://github.com/bitmax-exchange/bitmax-pro-api-demo/blob/master/python/client.py} (e.g. authorization, sub/unsub, place/cancel order, and so on)

Keep the Connection Alive via Ping/Pong

In order to keep the websocket connection alive, you have two options, detailed below.

Method 1: Responding to Server ping messages

Method 1. keep the connection alive by responding to Server pushed ping message

<<< { "m": "ping", "hp": 3 }  # Server pushed ping message
>>> { "op": "pong" }   # Client responds with pong

If the server doesn't receive any client message after a while, it will send a ping message to the client. Once the ping message is received, the client should promptly send a pong message to the server. If you missed two consecutive ping messages, the session will be disconnected.

Server Ping Message Schema

Name Type Description
op String ping
hp Int health point: when this value decreases to 0, the session will be disconnected.

Method 2: Sending ping messages to Server

Method 2. keep the connection alive by sending ping message to the server

>>> { "op": "ping" }                                      # Client initiated ping message (every 30 seconds)
<<< { "m":"pong", "code":0, "ts":1574260701259, "hp": 2 } # Server responds to client ping 

You can also send ping message to the server every 15 seconds to keep the connection alive. The server will stop sending ping message for 30 seconds if a client initiated ping message is received.

Server Pong Message Schema

Name Type Description
m String pong
code Int error code, for the pong mesage, the error code is always 0 (success)
ts Long server time in UTC miliseconds
hp Int health point: when this value decreases to 0, the session will be disconnected.

WebSocket Authentication

You must authenticate the websocket session in order to recieve private data and send account specific requests (e.g. placing new orders).

You have two options to authenticate a websocket session.

Once you successfully connect to the websocket, you will receive a connected message:

If the session is disconnected for some reason, you will receive a disconnected message:

Method 1 - WebSocket Authentication with Request Headers

Authenticate with Headers

# # Install wscat from Node.js if you haven't
# npm install -g wscat  

APIPATH=stream
APIKEY=BclE7dBGbS1AP3VnOuq6s8fJH0fWbH7r
SECRET=fAZcQRUMxj3eX3DreIjFcPiJ9UR3ZTdgIw8mxddvtcDxLoXvdbXJuFQYadUUsF7q
TIMESTAMP=`date +%s%N | cut -c -13`
MESSAGE=$TIMESTAMP+$APIPATH
SIGNATURE=`echo -n $MESSAGE | openssl dgst -sha256 -hmac $SECRET -binary | base64`

wscat -H "x-auth-key: $APIKEY" \
  -H "x-auth-signature: $SIGNATURE" \
  -H "x-auth-timestamp: $TIMESTAMP" \
  -c wss://bitmax.io/1/api/pro/v1/stream -w 1 -x '{"op":"sub", "id": "abc123", "ch": "order:cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo:BTMX/USDT"}'

This is similar to the way you authenticate any RESTful request. You need to add the following header fields to the connection request:

The server will then check if the data is correctly signed before upgrading the connection protocol to WebSocket.

Note that if you specify these header fields, the server will reject the websocket connection request if authentication fails.

Method 2 - WebSocket Authentication by Sending the Auth Message

Authenticate by Sending the auth Message

# # Install wscat from Node.js if you haven't
# npm install -g wscat  

APIPATH=stream
APIKEY=BclE7dBGbS1AP3VnOuq6s8fJH0fWbH7r
SECRET=fAZcQRUMxj3eX3DreIjFcPiJ9UR3ZTdgIw8mxddvtcDxLoXvdbXJuFQYadUUsF7q
TIMESTAMP=`date +%s%N | cut -c -13`
MESSAGE=$TIMESTAMP+$APIPATH
SIGNATURE=`echo -n $MESSAGE | openssl dgst -sha256 -hmac $SECRET -binary | base64`

wscat -c wss://bitmax.io/1/api/v1/pro/stream -w 1 -x "{\"op\":\"auth\", \"id\": \"abc123\", \"t\": $TIMESTAMP, "key": \"$APIKEY\", \"sig\": \"$SIGNATURE\"}"

You can also authenticate a live websocket session by sending an op:auth message to the server.

Name Type Required Description
op String Yes "auth"
id String No optional id field, you may safely skip it
t Long Yes UTC timestamp in milliseconds, use this timestamp to generate signature
key String Yes your api key
sig String Yes the signature is generated by signing "<timestamp>+stream"

More comprehensive examples can be found at:

Authentication Response

Auth success message

{  
  "m": "auth",
  "id": "abc123",
  "code": 0
}

Auth error message

{
  "m":"auth",
  "id": "abc123",
  "code": 200006,
  "err": "Unable to find User Account Data"
}

You will receive a message for authentication result after you send authentication request.

Field Type Description
m String "auth"
id String echo back the id if you provide one in the request
code Long Any code other than 0 indicate an error in authentication
err Optional[String] Provide detailed error message if code is not 0

Subscribe to Data Channels

How to Subscribe

Use wscat from Node.js to connect to websocket data.

# # Install wscat from Node.js if you haven't
# npm install -g wscat  
npm install -g wscat

# Connect to websocket
wscat -c wss://bitmax.io/0/api/pro/v1/stream -x '{"op":"sub", "ch": "depth:BTMX/USDT"}'

You can also setup authorized session

@ToDo

You can subscribe/unsubscribe to one or multiple data channels.

Request Body Schema

The standard messages to subscribe to / unsubscribe from data channels is an JSON object with fields:

Name Type Description
op String sub to subscribe and unsub to unsubscribe
id Optional[String] user specified UUID, if provided, the server will echo back this value in the response message
ch String name of the data channel with optional arguments, see below for details

Subscribe to bbo stream for symbol BTC/USDT

{ "op": "sub", "id": "abcd1234", "ch": "bbo:BTC/USDT" }

Subscribe to ref-px stream for symbol BTC

{ "op": "sub", "id": "abcd1234", "ch": "ref-px:BTC" }

Subscribe to trade stream for a list of symbols

{ "op": "sub", "id": "abcd1234", "ch": "trades:BTC/USDT,ETH/USDT,BTMX/USDT" }

Unsubscribes from the depth stream for all symbols (method 1)

{ "op": "unsub", "id": "abcd1234", "ch": "depth:*" }

Unsubscribes from the depth stream for all symbols (methond 2)

{ "op": "unsub", "id": "abcd1234", "ch": "depth" }

Unsubscribes from the 1 minute bar streams for all symbols (method 1)

{ "op": "unsub", "id": "abcd1234", "ch": "bar:1:*" }

Unsubscribes from the 1 minute bar streams for all symbols (method 2)

{ "op": "unsub", "id": "abcd1234", "ch": "bar:1" }

Unsubscribes from bar streams of all frequencies for BTMX/USDT

{ "op": "unsub", "id": "abcd1234", "ch": "bar:*:BTMX/USDT" }

Response for sub multiple symbols in one single message

{"m":"sub","id":"abc23g","ch":"summary:BTC/USDT,BTMX/USDT","code":0}

Response for unsub multiple symbols in one single message

{ "m": "unsub", "id": "abcd1234", "ch": "bar:*:BTMX/USDT" }

Customize Channel content with ch

You can customize the channel content by setting ch according to the table below:

Type Value Description
public depth:<symbol> Updates to order book levels.
public bbo:<symbol> Price and size at best bid and ask levels on the order book.
public trades:<symbol> Market trade data
public bar:<interval>:<symbol> Bar data containing O/C/H/L prices and volume for specific time intervals
public ref-px:<symbol> Reference prices used by margin risk Calculation.
Private order:<account> Order Update Stream: "cash", "margin", or actual accountId for `account.

Symbol in ref-px is single asset symbol(e.g. BTC), not trading pair symbol (e.g. BTC/USDT), which is different from other channels.

#### Unsubscribe with Wildcard Character *

Using the wildcard character *, you can unsubscribe from multiple channels with the same channel name.

Subscribe to single or multiple symbols

Subscribe to a single symbol (e.g. BTC/USDT), or multiple symbols (up to 10) separated by ",", e.g. "BTC/USDT,ETH/USDT".

Sub/Unsub response with multiple symbols

When sub or unsub from multiple symbols, we may ack symbol by symbol, or ack in one single message.

You can subscribe/unsubscribe one channel per subscription message. You can subscribe to multiple data channels by sending multiple subscription messages. However, the exchange limits the total number of data channels per client (NOT per session) according to the following rules:

@ToDo rule: maximum number of channels

Channel: Level 1 Order Book Data (BBO)

Subscribe to BTMX/USDT quote stream

{ "op": "sub", "id": "abc123", "ch":"bbo:BTMX/USDT" }

Unsubscribe to BTMX/USDT quote stream

{ "op": "unsub", "id": "abc123", "ch":"bbo:BTMX/USDT" }

BBO Message

{
    "m": "bbo",
    "symbol": "BTC/USDT",
    "data": {
        "ts": 1573068442532,
        "bid": [
            "9309.11",
            "0.0197172"
        ],
        "ask": [
            "9309.12",
            "0.8851266"
        ]
    }
}

You can subscribe to updates of best bid/offer data stream only. Once subscribed, you will receive BBO message whenever the price and/or size changes at the top of the order book.

Each BBO message contains price and size data for exactly one bid level and one ask level.

Channel: Level 2 Order Book Updates

Subscribe to BTMX/USDT depth updates stream

{ "op": "sub", "id": "abc123", "ch":"depth:BTMX/USDT" }

Unsubscribe to BTMX/USDT depth updates stream

{ "op": "unsub", "id": "abc123", "ch":"depth:BTMX/USDT" }

The Depth Message

{
    "m": "depth",
    "symbol": "BTMX/USDT",
    "data": {
        "ts": 1573069021376,
        "seqnum": 2097965,
        "asks": [
            [
                "0.06844",
                "10760"
            ]
        ],
        "bids": [
            [
                "0.06777",
                "562.4"
            ],
            [
                "0.05",
                "221760.6"
            ]
        ]
    }
}

If you want to keep track of the most recent order book snapshot in its entirety, the most efficient way is to subscribe to the depth channel.

Each depth message contains a bids list and an asks list in its data field. Each list contains a series of [price, size] pairs that you can use to update the order book snapshot. In the message, price is always positive and size is always non-negative.

See Orderbook Snapshot for code examples.

Channel: Market Trades

Subscribe to BTMX/USDT market trades stream

{ "op": "sub", "id": "abc123", "ch":"trades:BTMX/USDT" }

Unsubscribe to BTMX/USDT market trades stream

{ "op": "unsub", "id": "abc123", "ch":"trades:BTMX/USDT" }

Trade Message

{
    "m": "trades",
    "symbol": "BTMX/USDT",
    "data": [
        {
            "p":      "0.068600",
            "q":      "100.000",
            "ts":      1573069903254,
            "bm":      false,
            "seqnum":  144115188077966308
        }
    ]
}

The data field is a list containing one or more trade objects. The server may combine consecutive trades with the same price and bm value into one aggregated item. Each trade object contains the following fields:

Name Type Description
seqnum Long the sequence number of the trade record. seqnum is always increasing for each symbol, but may not be consecutive
p String the executed price expressed as a string
q String the aggregated traded amount expressed as string
ts Long the UTC timestamp in milliseconds of the first trade
bm Boolean if true, the buyer of the trade is the maker.

Channel: Bar Data

Subscribe to BTMX/USDT 1 minute bar stream

{ "op": "sub", "id": "abc123", "ch":"bar:1:BTMX/USDT" }

Unsubscribe to BTMX/USDT 1 minute bar stream

{ "op": "unsub", "id": "abc123", "ch":"bar:1:BTMX/USDT" }

//  Alternatively, you can unsubscribe all bar streams for BTMX/USDT
{ "op": "unsub", "id": "abc123", "ch":"bar:*:BTMX/USDT" }

// Or unsubscribe all 1 minute bar stream
{ "op": "unsub", "id": "abc123", "ch":"bar:1" }

// Or unsubscribe all bar stream
{ "op": "unsub", "id": "abc123", "ch":"bar" }

Bar Data Message

{
    "m": "bar",
    "s": "BTMX/USDT",    
    "data": {
        "i":  "1",
        "ts": 1575398940000,
        "o":  "0.04993",
        "c":  "0.04970",
        "h":  "0.04993",
        "l":  "0.04970",
        "v":  "8052"
    }
}

The data field is a list containing one or more trade objects. The server may combine consecutive trades with the same price and bm value into one aggregated item. Each trade object contains the following fields:

Name Type Description
seqnum Long the sequence number of the trade record. seqnum is always increasing for each symbol, but may not be consecutive
p String the executed price expressed as a string
q String the aggregated traded amount expressed as string
ts Long the UTC timestamp in milliseconds of the first trade
bm Boolean if true, the buyer of the trade is the maker.

Channel: Order (and Balance)

Subscribe to cash account order update stream

{ "op": "sub", "id": "abc123", "ch":"order:cash" }

Subscribe to specific account id cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo account for order update stream

{ "op": "sub", "id": "abc123", "ch":"order:cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo" }

Unsubscribe from cash account order update stream

{ "op": "unsub", "id": "abc123", "ch":"order:cash" }

Order update message

{
    "m": "order", 
    "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo", 
    "ac": "CASH", 
    "data": {
        "s":       "BTC/USDT", 
        "sn":       8159711, 
        "sd":      "Buy", 
        "ap":      "0", 
        "bab":     "2006.5974027", 
        "btb":     "2006.5974027",
        "cf":      "0", 
        "cfq":     "0", 
        "err":     "", 
        "fa":      "USDT",
        "orderId": "s16ef210b1a50866943712bfaf1584b", 
        "ot":      "Market", 
        "p":       "7967.62", 
        "q":       "0.0083", 
        "qab":     "793.23", 
        "qtb":     "860.23", 
        "sp":      "", 
        "st":      "New", 
        "t":        1576019215402,
        "ei":      "NULL_VAL"
    }
}

Balance Update Message (Cash Account)

{
    "m": "balance",
    "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
    "ac": "CASH",
    "data": {
        "a" : "USDT",
        "sn": 8159798,
        "tb": "600",
        "ab": "600"
    }
}

Balance Update Message (Margin Account)

{
    "m": "balance",
    "accountId": "marOxpKJV83dxTRx0Eyxpa0gxc4Txt0P",
    "ac": "MARGIN",
    "data": {
        "a"  : "USDT",
        "sn" : 8159802,
        "tb" : "400",
        "ab" : "400",
        "brw": "0",
        "int": "0"
    }
}

Note: once you subscribe to the order channel, you will start receiving messages from the balance channel automatically. If you unsubscribe from the order channel, you will simultaneously unsubscribe from the balance channel.

You need to specify the account when subscribing to the order channel. You could specify account category cash, margin, or specific account id.

Order Messages

You can track the state change of each order thoughout its life cycle with the order update message (m=order). The data field is a single order udpate object. Each order update object contains the following fields:

Name Type Description
s String symbol
sn long sequence number
ap String average fill price
bab String base asset available balance
btb String base asset total balance
cf String cumulated commission
cfq String cumulated filled qty
err String error code; could be empty
fa String fee asset
orderId String order id
ot String order type
p String order price
q String order quantity
qab String quote asset available balance
qtb String quote asset total balance
sd String order side
sp String stop price; could be empty
st String order status
t Long latest execution timestamp
ei String execution instruction

Balance Messages

You will also receive balance update message (m=balance) for the asset balance updates not caused by orders. For instance, when you make wallet deposits/withdrawals, or when you transfer asset from the cash account to the margin account, you will receive balance update message.

For Cash Account Balance Update, the data field contains:

Name Type Description
a String asset
sn long sequence number
tb String total balance
ab String available balance

For Margin Account Balance Update, the data field contains:

Name Type Description
a String asset
sn long sequence number
tb String total balance
ab String available balance
brw String borrowed amount
int String interest amount

Data Query / Order Request

Besides subscript mesages, you could also send request message via websocket. You will receive exactly one message regarding each request message. Here are some use cases:

WebSocket Request Schema

All operation or data request follow the same uniform format:

Name Type Required Value Description
op String Yes req
id String No digits and numbers if provided, the server will echo back this value in the response message
action String Yes See below name of the request action with optional arguments
account String NO cash, margin the account of the interest, this field is not required for public data request
args {key:value} No each action has different args, please see each action for detail.

Supported action

Name Description
place-order Place new order
cancel-order Cancel exisitng open order
cancel-all Cancel all open orders on account level
depth-snapshot Get market depth for symbol up to 500 level
depth-snapshot-top100 Get top 100 depth
market-trades Get market trades for a symbol
balance Request balance
open-order Query open order
margin-risk Get margin risk

WebSocket Response Schema

We try to provide all data in uniform format.

Ack or Data

Response follow the following schema

Name Type Description
m String message topic related with request action
id Optional[String] user specified UUID, if provided, the server will echo back this value in the response message
action String echo action field in request
data or info Json detailed data for data request, or info for operation result(e.g. order place/cancel)

Error

Name Type Description
m String "error"
id String Echo back the error
code Long
reason String simple error message
info String detailed error message

Example error response

{
    "m":      "error",
    "id":     "ab123",
    "code":   100005,
    "reason": "INVALID_WS_REQUEST_DATA",
    "info":   "Invalid request action: trade-snapshot"
}

WS: Orderbook Snapshot

Requesting the current order book snapshot

{ "op": "req", "id": "abcdefg", "action": "depth-snapshot", "args": { "symbol": "BTMX/USDT" } }

Depth snapshot message

{
    "m": "depth-snapshot",
    "symbol": "BTMX/USDT",
    "data": {
        "seqnum": 3167819629,
        "ts": 1573142900389,
        "asks": [
            [
                "0.06758",
                "585"
            ],
            [
                "0.06773",
                "8732"
            ]
        ],
        "bids": [
            [
                "0.06733",
                "667"
            ],
            [
                "0.06732",
                "750"
            ]
        ]
    }
}

You can request the current order book via websocket by an depth-snapshot request.

The args schema:

Name Data Type Description
op String req
action String depth-snapshot
id String echo back in case of error
args:symbol String Symbol, e.g. BTMX/USDT

The response schema:

Name Data Type Description
m String depth-snapshot
symbol String Symbol, e.g. BTMX/USDT
data:seqnum Long
data:ts Long UTC Timestamp in milliseconds
data:asks [[String, String]] List of (price, size) pair
data:bids [[String, String]] List of (price, size) pair

You can following the steps below to keep track of the the most recent order book:

Please note that field seqnum should strictly increase by 1 for each new depth update (each symbol maintain its own seqnum). If you see a larger than 1 gap from previous seqnum (for the same symbol), then there might be data loss, you need to repeat above steps to maintain a new order book.

The depth-snapshot message is constructed in a consistent way with all depth message.

Please note that the depth-snapshot API has higher latency. The response time is usually between 1000 - 2000 milliseconds. It is intended to help you initialize the orderbook, not to be used to obtain the timely order book data.

More comprehensive examples can be found at:

WS: Place Order

Request to place new order

{
    "op": "req",
    "action": "place-Order",
    "account": "cash",
    "args": {
        "time":       1573772908483,
        "id":         "11eb9a8355fc41bd9bf5b08bc0d18f6b",
        "symbol":     "EOS/USDT",
        "orderPrice": "3.27255",
        "orderQty":   "30.557210737803853",
        "orderType":  "limit",
        "side":       "buy",
        "postOnly":    false,
        "respInst":   "ACK"
    }
}

Successful ACK message

{
    "m": "order", 
    "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo", 
    "ac": "CASH", 
    "action": "place-order", 
    "status": "Ack", 
    "info": {
        "symbol": "BTC/USDT", 
        "orderType": "Limit", 
        "timestamp": 1576015701441, 
        "id": "17e1f6809122469589ffc991523b505d", 
        "orderId": "s16ef1daefbe08669437121523b505d"
    }
}

Error response message

{
    "m": "order",
    "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
    "ac": "CASH", 
    "action": "place-order",
    "status": "Err",
    "info": {
        "id":      "69c482a3f29540a0b0d83e00551bb623",
        "symbol":  "ETH/USDT",
        "code":     300011,
        "message": "Not Enough Account Balance",
        "reason":  "INVALID_BALANCE"
    }
}

Place order via websocket

Request

Make new order request follow the general websocket request rule, with proper place new order parameters as specified in rest api for args field.

see placing order via RESTful API.

Response

Respond with m field as order, and action field as place-order; status field to indicate if this is a successful Ack or failed Err.

ACK

With status field as Ack to indicate this new order request pass some basic sanity check, and has been sent to matching engine.

info field provide some detail: if you provide id in your request, it will be echoed back as id to help you identify; we also provide server side generated orderId, which is the id you should use for future track or action on the order.

ERR

With status field as Err to indicate there is some obvisous errors in your order.

info field provide some detail: if you provide id in your request, it will be echoed back as id to help you identify; we also provide error code, reason, and message detail.

WS: Cancel Order

Request to cancel existing open order

{
  "op": "req",
  "action": "cancel-Order",
  "account": "cash",
  "args": {
    "time":    1574165050128,
    "id":      "2d4c3fa1e5c249e49f990ce86aebb607",
    "orderId": "16e83845dcdsimtrader00008c645f67",
    "symbol":  "ETH/USDT"
  }
}

Successful ACK message

{
  "m": "order",
  "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
  "ac": "CASH",
  "action": "cancel-order",
  "status": "Ack",
  "info": {
    "symbol":    "ETH/USDT",
    "orderType": "NULL_VAL",
    "timestamp":  1574165050147,
    "id":        "7b73dcd8e8c847d5a99df5ef5ae5088b",
    "orderId":   "16e83845dcdsimtrader00008c645f67"
  }
}

Error response message

{
  "m": "order",
  "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
  "ac": "CASH",
  "action": "cancel-order",
  "status": "Ack",
  "info": {
    "code":     300006,
    "id":      "x@fabs",
    "message": "Invalid Client Order Id: x@fabs",
    "symbol":  "ETH/USDT",
    "reason":  "INVALID_ORDER_ID"
  }
}

Cancel an existing open order via websocket

Request

Make order cancelling request follow the general websocket request rule by setting action to be cancel-orde, with proper cancel order parameters as specified in rest api for args field.

Response

ACK

With status field as Ack to indicate this cancel order request pass some basic sanity check, and has been sent to matching engine.

info field provide some detail: if you provide id in your request, it will be echoed back as id to help you idintify; we also echo back target orderId to be cancelled.

Err

With status field as Err to indicate there is some obvisous errors in your cancel order request.

info field provide some detail: if you provide id in your request, it will be echoed back as id to help you identify; we also provide error code, reason, and message detail.

WS: Cancel All Orders

Request to cancel all existing open orders

{
    "op": "req",
    "action": "cancel-All",
    "args": {}
}

Request to cancel existing open order related to symbol "BTC/USDT"

{
    "op": "req",
    "action": "cancel-All",
    "account": "cash",
    "args": {
        "symbol": "BTC/USDT"
    }
}

Successful ACK message

{
    "m": "order",
    "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
    "ac": "CASH",
    "action": "cancel-all",
    "status": "Ack",
    "info": {
        "symbol":    "",
        "orderType": "NULL_VAL",
        "timestamp":  1574165159732,
        "id":        "69c482a3f29540a0b0d83e00551bb623",
        "orderId":   ""
    }
}

Cancel all open orders on account level via websocket with optional symbol.

Request

Make general websocket request with action field as cancel-All and set proper account value(cash, or margin), and provide time value in args.

Response

With status field as Ack to indicate this cancel all order request has been received by server and sent to matching engine.

info field provide some detail: if you provide id in your request, it will be echoed back as id to help you match ack with request.

WS: Query Open Orders on Symbol

Requesting open orders on symbol BTC/USDT

{
    "op": "req", 
    "action": "open-order", 
    "id": "abdad113", 
    "account": "cash", 
    "args": {
        "symbols": "BTC/USDT"
    }
}

Open orders response

{
    "m": "open-order", 
    "id": "abdad113", 
    "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo", 
    "ac": "CASH", 
    "data": [
        {
            "sn": 103, 
            "orderId": "a16edce82c6e0866943712UKrJP1HCA", 
            "s": "BTC/USDT", 
            "ot": "Limit", 
            "t": 1575664233699, 
            "p": "9000", 
            "q": "0.01", 
            "sd": "Buy", 
            "st": "New", 
            "ap": "0", 
            "cfq": "0", 
            "sp": "0", 
            "err": "NULL_VAL", 
            "btb": "0", 
            "bab": "0", 
            "qtb": "0", 
            "qab": "0", 
            "cf": "0", 
            "fa": "USDT"
        }, 
        ...
    ]
}

You can request the open order via websocket by an open-order request.

The request schema:

Name Data Type Description
op String req
action String open-order
id String for result match purpose
account String cash, margin
args:symbols Optional[String] add the (optional) symbol filter, see below for details.

The symbols key in the args map allows you to customize the symbol filter in a flexible way:

The response schema:

Name Data Type Description
m String open-order
accountId String account
ac String cash, margin
id String echo id in request
data Order Json Array A list of open order json objects

WS: Recent Market Trades

Requesting the most recent 12 trades for symbol BTMX/USDT

{ "op": "req", "action": "market-trades", "args": { "symbol": "BTMX/USDT", "level": 12} }

Trades snapshot message

{
    "m": "market-trades",
    "id": "abcd1334",
    "symbol": "BTMX/USDT",
    "data": [
        {
            "p":      "0.068600",
            "q":      "100.000",
            "ts":      1573069903254,
            "bm":      false,
            "seqnum":  144115188077966308
        }
    ]
}

You can request the current order book via websocket by an market-trades request.

The request schema:

Name Data Type Description
op String req
action String market-trades
args {key:value} see args below for detail

The args schema:

symbol | String | Symbol, e.g. BTMX/USDT
level | Int | Number of trades to request

The response schema:

Name Data Type Description
m String market-trades
symbol String Symbol, e.g. BTMX/USDT
data Json Array A list of trade json objects

The data field is a list containing one or more trade objects. The server may combine consecutive trades with the same price and bm value into one aggregated item. Each trade object contains the following fields:

Name Type Description
seqnum Long the sequence number of the trade record. seqnum is always increasing for each symbol, but may not be consecutive
p String the executed price expressed as a string
q String the aggregated traded amount expressed as string
ts Long the UTC timestamp in milliseconds of the first trade
bm Boolean if true, the buyer of the trade is the maker.

WS: Margin Risk for Symbol

Request margin risk for symbol BTC/USDT

{
    "op": "req", 
    "action": "margin-risk", 
    "id": "abcefg", 
    "account": "margin", 
    "args": {
        "symbol": "BTC/USDT"
    }
}

Margin Risk Response

{
    "m":"margin-risk", 
    "accountId":"marGad02EnGqSo6P2SMBoNUX4lGyxjsy",
    "ac":"MARGIN", 
    "id":"abcefg", 
    "data": {
        "tb":"14058.242182715",
        "ab":"14058.242182715",
        "nb":"14058.242182715",
        "eim":"0",
        "emm":"0",
        "clv":"1",
        "ilv":"3",
        "alv":"10",
        "cus":"-1",
        "pts":"0"
    }
}

You can request margin risk for a symbol via websocket by an margin-risk request.

The args schema:

Name Data Type Description
op String req
action String margin-risk
id String for result match purpose
args:symbol String Symbol, e.g. BTMX/USDT

The response schema:

Name Data Type Description
m String margin-risk
accountId String margin accountId
ac String MARGIN
symbol String Symbol, e.g. BTMX/USDT
id String echo back id in request
data Json See data detail below

data field detail

Name Data Type Description
tb String total balance
ab String available balance
nb String net balance
eim String effective initial margin
emm String effective maintaince margin
clv String current leverage
ilv String initial leverage
alv String account max leverage
cus String cushion
pts String points balance

Experimental APIs

Real Time Level 2 Orderbook Updates

WebSocket messages from the default depth channel are throttled with 300 milliseconds throttling intervals. If you want to subscribe to realtime orderbook updates, please refer to this article.

Subscribe to Order Channel with Ready Ack Mode

By default, when you subscribe to the order channel via WebSocket, you automatically enter the New Ack Mode. In this mode, when the order is accepted by the matching engine, you will receive an order message with status st=New. This is true even when the order will immediately change status. For instance, when you place a Post-only order that crosses the book, it will immediately be rejected. However, in the New Ack Mode, you will first receive an order message with st=New, then immediately receive another message with st=Canceled. However, if your order successfully enters the orderbook without crossing with order on the opposite side, you will only receive one message with st=New. This makes it hard for trading bots to decide when to take actions.

To address this issue, we introduced the Ready Ack mode. Follow this link for more details.

Error Message

We structure our error message in three levels: * Error Group provide a broad error category (Error group id = error code / 10000) * Error Reason provide some intuitive information on the error * Error Message explains error detail.

In most situation, we provide simple error in this way: {"code": XYABCDE, "reason": XXXXXXXX}; for complicated scenatio (such as order place/cancel request, websocket request, and so on), we provide rich format error: {"code": XYZBCDE, "reason":XXXXXXXX, "message":YYYYYYYY}.

Rich format error is derived from simple error, so you could get error message with same error code and reason, but different message content.

Error Base Group

We summary the major error group below.

group name group code derived code description
GeneralError 10 10XXXX Errors applied to general scenario
FormatError 15 15XXXX Format related error
AuthError 20 20XXXX Auth related error
OrderError 30 30XXXX Order action and information related error
MarginError 31 31XXXX Margin account and trading related error
SystemError 50 50XXXX System related error
BehaviorError 90 90XXXX Behavior error

10XXXX - General Error

code reason descripion
100001 INVALID_HTTP_INPUT Http request is invalid
100002 DATA_NOT_AVAILABLE Some required data is missing
100003 KEY_CONFLICT The same key exists already
100004 INVALID_REQUEST_DATA The HTTP request contains invalid field or argument
100005 INVALID_WS_REQUEST_DATA Websocket request contains invalid field or argument
100006 INVALID_ARGUMENT The arugment is invalid
100007 ENCRYPTION_ERROR Something wrong with data encryption
100008 SYMBOL_ERROR Symbol does not exist or not valid for the request
100009 AUTHORIZATION_NEEDED Authorization is require for the API access or request
100010 INVALID_OPERATION The action is invalid or not allowed for the account
100011 INVALID_TIMESTAMP Not a valid timestamp
100012 INVALID_STR_FORMAT String format does not
100013 INVALID_NUM_FORMAT Invalid number input
100101 UNKNOWN_ERROR Some unknown error

15XXXX - Format Error

code reason descripion
150001 INVALID_JSON_FORMAT Require a valid json object

20XXXX - Auth Error

Auth related errors.

code reason descripion
200001 AUTHENTICATION_FAILED Authorization failed
200002 TOO_MANY_ATTEMPTS Tried and failed too many times
200003 ACCOUNT_NOT_FOUND Account not exist
200004 ACCOUNT_NOT_SETUP Account not setup properly
200005 ACCOUNT_ALREADY_EXIST Account already exist
200006 ACCOUNT_ERROR Some error related with error
200007 CODE_NOT_FOUND
200008 CODE_EXPIRED Code expired
200009 CODE_MISMATCH Code does not match
200010 PASSWORD_ERROR Wrong assword
200011 CODE_GEN_FAILED Do not generate required code promptly
200012 FAKE_COKE_VERIFY
200013 SECURITY_ALERT Provide security alert message
200014 RESTRICTED_ACCOUNT Account is restricted for certain activity, such as trading, or withdraw.
200015 PERMISSION_DENIED No enough permission for the operation

30XXXX - Order Error

Order place/cancel/query related errors. We usually provide rich format errors based on these simple ones.

code reason descripion
300001 INVALID_PRICE Order price is invalid
300002 INVALID_QTY Order size is invalid
300003 INVALID_SIDE Order side is invalid
300004 INVALID_NOTIONAL Notional is too small or too large
300005 INVALID_TYPE Order typs is invalid
300006 INVALID_ORDER_ID Order id is invalid
300007 INVALID_TIME_IN_FORCE Time In Force in order request is invalid
300008 INVALID_ORDER_PARAMETER Some order parameter is invalid
300009 TRADING_VIOLATION Trading violation on account or asset
300011 INVALID_BALANCE No enough account or asset balance for the trading
300012 INVALID_PRODUCT Not a valid product supported by exchange
300013 INVALID_BATCH_ORDER Some or all orders are invalid in batch order request
300020 TRADING_RESTRICTED There is some trading restriction on account or asset
300021 TRADING_DISABLED Trading is disabled on account or asset
300031 NO_MARKET_PRICE No market price for market type order trading

31XXXX - Margin Error

Margin trading related errors.

code reason descripion
310001 INVALID_MARGIN_BALANCE No enough margin balance
310002 INVALID_MARGIN_ACCOUNT Not a valid account for margin trading
310003 MARGIN_TOO_RISKY Leverage is too high
310004 INVALID_MARGIN_ASSET This asset does not support margin trading
310005 INVALID_REFERENCE_PRICE There is no valid reference price

50XXXX - System Error

code reason descripion
510001 SERVER_ERROR Something wrong with server.

90XXXX - Behavior Error

code reason descripion
900001 HUMAN_CHALLENGE Human change do not pass