WebSocket API beta


WebSocket API allows getting real-time notifications without sending extra requests, making it a faster way to obtain data from the exchange.

For better experience of running functions connected with archived data, please use REST API.


Version

WebSocket URL

Message Encoding

Authentication

Connectivity & Protocol Special Messages

Public Channels

Private Channels

Asynchronous messages

Standalone responses

Examples of error responses

Version

Please note that CEX.IO WebSocket API is currently in beta and, therefore, is not versioned yet. Some functions are presented in legacy format, because they are used in implementation of CEX.IO Web Client, and will be refactored eventually.


WebSocket URL

    wss://ws.cex.io/ws/

Message encoding

  • All messages are encoded in JSON format.
  • Prices and amounts are presented as strings to avoid rounding errors at JSON parsing on client side
  • Some depricated functions present amount and prices as numbers
  • Depricated functions often present prices and amounts as 'not formatted' - as integer number
  • Compression of WebSocket frames is not supported by server. Thus, REST API might be a better option for 'long' requests
  • Time is presented as integer UNIX timestamp in seconds in new functions and as integer java timestamp in miliseconds in older functions; further, reffered as 'timestamp' and 'timestamp-ms' correspondently

Authentication

To get access to CEX.IO WebSocket data, you should be authorized.

To authorize your account with CEX.IO, please get required keys using the following instructions:

  1. Log in to CEX.IO account.
  2. Go to https://cex.io/trade/profile#/api page.
  3. Select type of required permissions.
  4. Click "Generate Key" button and save your secret key, as it will become inaccessible after activation.
  5. Activate your key.

image

image

Authentication Request Parameters:

Parameter Name Type Description
key string API key
signature string Client signature (digest of HMAC-rsa256 with client's API Secret Key, applied to the string, which is concatenation timestamp and API Key)
timestamp timestamp timestimp in seconds, used for signature

Request example:

{
    "e": "auth",
    "auth": {
        "key": "1WZbtMTbMbo2NsW12vOz9IuPM.",
        "signature": "02483c01efc26fac843dd34d0342d269bacf4daa906a32cb71806eb7467dcf58",
        "timestamp": 1448034533
    }
}

Response example:

{
    "e": "auth",
    "data": {
        "ok": "ok"
    },
    "ok": "ok"
}

NodeJS implementation reference:

var crypto = require('crypto');
function createSignature(timestamp, apiKey, apiSecret){
    var hmac = crypto.createHmac('sha256', apiSecret );
    hmac.update( timestamp + apiKey );
    return hmac.digest('hex');
}

function createAuthRequest(apiKey, apiSecret ){
    var timestamp = Math.floor(Date.now() / 1000);  // Note: java and javascript timestamp presented in miliseconds
    var args = { e: 'auth', auth: { key: apiKey, 
        signature: createSignature(timestamp, apiKey, apiSecret), timestamp: timestamp } };
    var authMessage = JSON.stringify( args );
    return authMessage;
}

Python implementation reference:

import hmac
import hashlib
import datetime
import json

# Python 2.7
#
def create_signature_Py27(key, secret):  # (string key, string secret) 
    timestamp = int(datetime.datetime.now().timestamp())  # UNIX timestamp in seconds
    string = "{}{}".format(timestamp, key)
    return hmac.new(secret, string, hashlib.sha256).hexdigest()

# Python 2.7 - 3.5+ 
# Note: latest versions of hmac lib requires 'secret' and 'string' as byte strings but not unicode
#
def create_signature(key, secret):  # (string key, string secret) 
    timestamp = int(datetime.datetime.now().timestamp())  # UNIX timestamp in seconds
    string = "{}{}".format(timestamp, key)
    return timestamp, hmac.new(secret.encode(), string.encode(), hashlib.sha256).hexdigest()

def auth_request(key, secret):
    timestamp, signature = create_signature(key, secret)
    return json.dumps({'e': 'auth',
        'auth': {'key': key, 'signature': signature, 'timestamp': timestamp,}, 'oid': 'auth', })

auth_request = auth_request('1WZbtMTbMbo2NsW12vOz9IuPM', '1IuUeW4IEWatK87zBTENHj1T17s')

Test case 1 for createSignature:

Parameter Value
apiSecret 1IuUeW4IEWatK87zBTENHj1T17s
timestamp 1448034533
apiKey 1WZbtMTbMbo2NsW12vOz9IuPM
signature 7d581adb01ad22f1ed38e1159a7f08ac5d83906ae1a42fe17e7d977786fe9694

Note: timestamp 1448034533 means Fri Nov 20 2015 17:48:53 GMT+0200 (EET)

Test case 2 for createSignature:

Parameter Value
apiSecret 1IuUeW4IEWatK87zBTENHj1T17s
timestamp 1448035135
apiKey 1WZbtMTbMbo2NsW12vOz9IuPM
signature 9a84b70f51ea2b149e71ef2436752a1a7c514f521e886700bcadd88f1767b7db

Note: timestamp 1448035135 means Fri Nov 20 2015 17:58:55 GMT+0200 (EET)


Connectivity & Protocol Special Messages

Connected message

Server sends 'Connected' message just after WebSocket handshake

{
    "e": "connected"
}
  • can be received in case WebSocket client has reconnected, which means that client needs to send 'authenticate' request and subscribe for notifications, like by first connection

Heartbeat (Ping - Pong) message

Some clarifications to Heartbeat messages:

  • If a connected Socket is inactive for 15 seconds, CEX.IO server will send a PING message.
  • Only server can be an Initiator of PING request.
  • Server sends ping only to authenticated user.
  • The user has to respond with a PONG message. Otherwise, the WebSocket will be DISCONNECTED.
  • The PING message contains a 'time' property as timestamp-ms.
  • Client can send another request, instead of pong. It will have the same effect.
  • For authenticated user, in case there is no notification or ping from server within 15 seconds, it would be safer to send a request like 'ticker' or 'get-balance' and receive response, in order to ensure connectivity and authentication.

Example of PING request:

{
    "e": "ping",
    "time": 1435927943922
}

Example of PONG response:

{
    "e": "pong"
}

Disconnecting message

In case Server is disconnecting, it sends a 'disconnecting' message prior to actual disconnection.

'Disconnecting' message:

{
        'e': 'disconnecting',
        'reason': 'no pong response',
        'time': 1456946866378
    }
  • currently, the message is sent only if there is no pong response on time.

Dropping connection by server

  • From time to time (0.5-1 hour), server drops connection without sending 'disconnecting' message. This is a technical issue that is not going to be solved within CEX.IO v1.0. Therefore, user apps should implement kind of proxy connector to ensure that connection is alive and re-connect when not.
  • Server may also drop connection intentially, for example due to unexpected requests.

Rate Limit

  • Server limits WebSocket client to 600 requests per 10 minutes.
  • If client exceeds the limit, all responses to further requests will have an error, like shown in this example:

Error: 'Rate limit exceeded':

{
        'e': 'ticker'
        'data': {
            'time': 1457092944426,
            'error': 'Rate limit exceeded'},
        }
    }
    
  • server will continue to process requests within 10 minutes

Public Channels

  • Ticker feed with only price of transaction made on all pairs (deprecated)
  • OHLCV chart feeds with Open, High, Low, Close, Volume numbers (deprecated)
  • Market Depth feed (deprecated)
  • Order Book feed (deprecated)

Ticker subscription

  • Ticker subscription allows you to subscribe to real-time updates of executed trades.
  • Notification does not include information like lowest and highest prices, volume, but indicates that trading is happening.

Request:

{
    "e": "subscribe",
    "rooms": [
        "tickers"
    ]    
}

Notification example:

This notification represents the currency pair and price of last submitted trade. The message is sent any time when trade transaction on any pair is executed.

{
    "e": "tick",
    "data": {
        "symbol1": "BTC",
        "symbol2": "USD",
        "price": "428.0123"
    }
}

OHLCV charts subscriptions

  • OHLCV initial chart (snapshot): 1m 3m 5m 15m 30m 1h 2h 4h 6h 12h 1d 3d 1w
  • OHLCV requested chart updates
  • 1m OHLCV chart update is sent regardless of which initial chart has been requested
  • 1d OHLCV chart update is sent regardless of which one has been requested

Web page, visualizing all data the subscription gives:

https://cex.io/ohlcv/btc/usd
  • Note: In WebSocket notifications, volumes are presented as not formatted integers; WebClient formats them appropriately, using functions given by server. Thus, presentation approach to a given currency may change at any time.
  • Note: 'new' means subscription instead of the older one, which is also available.

Request Example:

{
    "e": "init-ohlcv-new",
    "i": "1m",
    "rooms": [
       "pair-BTC-USD"
    ]
}

Results in following Notification Examples:

1d OHLCV chart update

{
    'e': 'ohlcv24',
    'pair': 'BTC:USD',
    'data': [
        '418.2936',
        '420.277',
        '412.09',
        '416.9778',
        '201451078368'
    ]
}

Array of data for the last 120 minutes

{
    "e": "ohlcv-init-new",
    "data": [ [
        [
            1457512080,
            '417.0058',
            '417.0058',
            '416.7174',
            '416.9364',
            '122379919'
        ], [
            1457512140,
            '416.848',
            '417.15',
            '416.8423',
            '416.8423',
            '826080001'
        ], 
        ...
    ],
    "pair": "BTC:USD"
}
  • Please note that data in array doesn't include the last element of array.
  • There can also be less than 120 elements in response array in case they are not available.

Array with data about latest block (may include a few blocks next to the latest)

{
    'e': 'ohlcv-new', 
    'data': [
        [
            1457519400,
            '414.64',
            '417.5',
            '414.64',
            '416.9778',
            '880702380'
         ],
         ...
     ]
    'pair': 'BTC:USD'
 },

Data with changes happened during the last period (1M in this case)

{
    'e': 'ohlcv1m',
    'data': {
        'c': '417.1519',
        'd': 28570000,
        'l': '417.1519',
        'o': '417.1519',
        'h': '417.1519',
        'v': 28570000
        'pair': 'BTC:USD',
        'time': '1457519460',
    }
}

Old Pair-Room Subscription

  • This is the oldest subscription, on which Server is sending almost all public data to WebClient. The data, in fact, represents Order Book, Market Depth, Trade History and History Updates, 1d OHLCV updates. Therefore, the subscription is overlapping with new OHLCV subscriptions, Order Book subscription for authenticated user. Authenticated user can use either new, old or both.

Request:

{
    "e": "subscribe",
    "rooms": ["pair-BTC-USD"]
}

Results in following Notification Examples:

1d OHLCV updates

{
    'e': 'ohlcv24', 
    'pair': 'BTC:USD',
    'data': [
        '415.5804',
        '418.94',
        '413.0568',
        '416.8241', 
        239567198169
    ]
}

Order Book snapshot

{
    'e': 'md', 
    'data': {
        'pair': 'BTC:USD',
        'buy_total': 63221099,
        'sell_total': 112430315118,
        'id': 11296131,
        'sell': [
            [426.45, 10000000],
            [426.5, 66088429300],
            [427, 1000000],
            ... 50 pairs overaall
        ],
        'buy': [
            [423.3, 4130702],
            [423.2701, 10641168],
            [423.2671, 1000000],
            ... 50 pairs overaall
        ]
    }
}
  • presents Order Book snapshot with depth 50
  • amounts presented as unformated integers - in given sample BTC in 'Satoshi'

Market Depth

{
    'e': 'md_groupped', 
    'data': {
        'pair': 'BTC:USD',
        'id': 11296131,
        'sell': {
            '427.5000': 1000000,
            '480.0000': 263544334,
            ...
        },
        'buy': {
            '385.0000': 3630000,
            '390.0000': 1452458642,
            ... 400+ pairs togather with 'sell' pairs
        }
    }
}
  • presents aggregated price / amount chart
  • counted on the snapshot of full Order Book with the same ID
  • id is incremental id of Order Book at the time of counting
  • price/amount pairs are presented as key-value dictionary, thus they are unordered
  • amounts are presented as unformatted integers - in given sample BTC in 'Satoshi'
  • each amount presents the sum for given price interval

History snapshot

{
    'e': 'history', 
    'data': {
        'buy:1457703205200:46860000:423.7125:735479',
        'sell:1457703191363:35430000:423.7125:735478',
        ... 201 items
    }
}
  • presents trade history of 201 records
  • is sent once after subscription
  • does not indicate requested pair
  • format: 'sell/buy:timestamp_ms:amount:price:transaction_id'
  • amounts presented as unformatted integers - in given sample BTC in 'Satoshi'

History update

{
    'e': 'history-update',
    'data': [
        ['sell', '1457703218519', '41140000', '423.7125', '735480'],
        ... 0 to n records
    ]
}
  • presents history update, is being sent regulary
  • does not indicate requested pair
  • doesn't have incremental id
  • format: ['sell'/'buy', timestamp_ms, amount, price, transaction_id]
  • amounts presented as unformatted integers - in given sample BTC in 'Satoshi'

Private Channels

In addition to public channels, an authorized user has access to:

  • Private account information, like balances, placed orders, executed orders
  • Trading functionality
  • Order Book feed (new)
  • Trade feeds

Common format

All new API functionality is implemented in uniformat:

Mandatory blocks/parameters of request:

Parameter/block name Description
e message(event) name
data data block in request
oid string object identifier, needed for client to associate response with sent request. It's up to client how to generate oid, unique in required skope. In any case, server simply sends it back in response. It may be, for example, concatenation of timestamp, incremental number and request name.

Response correspondently has:

Parameter/block name Description
e event name - the same as in request
data data block of the response
oid object identifier, the same as in request
ok status code: 'ok' or 'error'
data[error] in case of 'error' result, the error message is added to the data block as 'error'

Note: All requests sent via PUSH method HAVE NO OID parameters at all

Note: All newly created functions use this format of request / response


'Ticker' request

  • This is the simplest request to ensure that client is connected and authenticated.
  • Returns the response with the lowest ask price and highest bid price for the pair.
  • The request might be descoped, because it's not very informative and it is not a subscription for ticker.

Request example:

Parameter Name Value Description
ccy1 ISO 4217 Currency 1
ccy2 ISO 4217 Currency 2
oid string OID identifier (number / text)
{
    "e": "ticker",
    "data": [
        "BTC",
           "USD"
    ],
    "oid": "1435927928274_1_ticker"
}

Response example:

Parameter Name Value Description
pair list Requested currency pair. Consists of ccy1 and ccy2 parameters
bid decimal Bid price value
ask decimal Ask price value
oid string OID identifier (number / text)
low string Last 24 hours price low
high string Last 24 hours price high
last string Last BTC price
volume string Last 24 hours volume
volume30d string Last 30 days volume
{
    "e": "ticker",
    "data": {
        "timestamp": "1471427037",
        "low": "290",
        "high": "290",
        "last": "290",
        "volume": "0.02062068",
        "volume30d": "14.38062068",
        "bid": 240,
        "ask": 290,
        "pair": [
            "BTC",
            "USD"
        ]
    },
    "oid": "1471427036908_1_ticker",
    "ok": "ok"
}

'not authenticated' response example:

{
    'ok': 'error', 
    'e': 'ticker', 
    'oid': '1457513058865_1_ticker', 
    'data': {'error': 'Please Login'}
}

Get balance request

Request example:

Parameter Name Value Description
oid ISO 4217 Currency 1
{
    "e": "get-balance",
    "data": {},
    "oid": "1435927928274_2_get-balance"
}

Response example:

Parameter Name Value Description
balance array Returns list of all currencies in wallet with current balances
obalance array Balance of user's orders
time timestamp-ms Time identifier
oid string OID identifier (number / text)
{
    "e": "get-balance",
    "data": {
           "balance": {
            'LTC': '10.00000000', 
            'USD': '1024.00',
            'RUB': '35087.98', 
            'EUR': '217.53', 
            'GHS': '10.00000000',
            'BTC': '9.00000000'
        },
           "obalance": {
              'BTC': '0.12000000',
              'USD': "512.00",
           },
       },
       "time": 1435927928597
    "oid": "1435927928274_2_get-balance",
    "ok": "ok"
}

Order Book subscription

Request example:

Parameter Name Value Description
pair ----- Requested currency pair. Consists of ccy1 and ccy2 parameters
ccy1 ISO 4217 Currency 1
ccy2 ISO 4217 Currency 2
subscribe boolean subscribe mode
depth -1, 0, N Depth of data in response
oid string OID identifier (number / text)
  • -1: empty data in response
  • 0: unlimited data in response
  • N: depth of data mentioned in request

      {
      "e": "order-book-subscribe",
      "data": {
      "pair": [
            "BTC",
            "USD"
            ],
            "subscribe": false,
            "depth": -1
      },
      "oid": "1435927928274_3_order-book-subscribe"
      }
    

Response example:

Parameter Name Value Description
timestamp timestamp Time identifier
bids array List of bid rates
asks array List of ask rates
pair ----- Requested currency pair. Consists of ccy1 and ccy2 parameters.
id integer incremental version
oid string OID identifier (number / text)

Incremental version id:

  • is to be used to build client presentation of order book
  • firstly, id is returned in the response with a snapshot of order book
  • then, server is sending incremental updates (Market data update), id is incremeted by 1 with each update
  • suggested approach to build order-book locally is following:
    • request snapshot with subscription and start collecting updates;
    • when snapshot received, increment collected updates, starting from the id, next to the id in snapshot received;
    • if one update is missed, the client presentation of order-book becomes inconsistent

Empty order book:

{
"e": "order-book-subscibe",
"data": {
   "timestamp": 1435927929,
   "bids": [],
   "asks": [],
   "pair": "BTC:USD",
   "id": 67809
},
"oid": "1435927928274_3_order-book-subscribe",
"ok": "ok"
}

Order book with subscription data & depth = 10

{
"e": "order-book-subscibe",
"data": {
   "timestamp": 1435927929,
   "bids": [
      [
         241.947,
         155.91626
      ],
      [
         241,
         981.1255
      ],
   ],
   "asks": [
      [
         241.95,
         15.4613
      ],
      [
         241.99,
         17.3303
      ],
   ],
   "pair": "BTC:USD",
   "id": 67809
},
"oid": "1435927928274_5_order-book-subscribe",
"ok": "ok"
}

Unsubscribe from order book

Request example:

Parameter Name Value Description
pair ----- Requested currency pair. Consists of ccy1 and ccy2 parameters.
ccy1 ISO 4217 Currency 1
ccy2 ISO 4217 Currency 2
oid string OID identifier (number / text)
{
"e": "order-book-unsubscribe",
"data": {
   "pair": [
      "BTC",
      "USD"
   ]
},
"oid": "1435927928274_4_order-book-unsubscribe"
}

Response example:

Parameter Name Value Description
pair ----- Requested currency pair. Consists of ccy1 and ccy2 parameters.
oid string OID identifier (number / text)
{
"e": "order-book-unsubscribe",
"data": {
   "pair": "BTC:USD"
},
"oid": "1435927928274_4_order-book-unsubscribe",
"ok": "ok"
}

List of open orders

Request example:

Parameter Name Value Description
pair ----- Requested currency pair. Consists of ccy1 and ccy2 parameters.
oid string OID identifier (number / text)
{
"e": "open-orders",
"data": {
   "pair": [
      "BTC",
      "USD"
   ]
},
"oid": "1435927928274_6_open-orders"
}

Response example:

Parameter Name Value Description
id integer Order identifier
time timestamp-ms Time identifier
type Buy / Sell Order direction
price decimal Order price (rate of ccy pair for order)
amount decimal Order amount
pending decimal Order pending amount
oid string OID identifier (number / text)

There are no open orders at the moment:

{
"e": "open-orders",
"data": [],
"oid": "1435927928274_6_open-orders",
"ok": "ok"
}

There are some open orders at the moment:

{
"e": "open-orders",
"data": [
   {
      "id": "2477098",
      "time": "1435927928618",
      "type": "buy",
      "price": "241.9477",
      "amount": "0.02000000",
      "pending": "0.02000000"
   },
   {
      "id": "2477101",
      "time": "1435927928634",
      "type": "sell",
      "price": "241.9493",
      "amount": "0.02000000",
      "pending": "0.02000000"
   }
],
"oid": "1435927928274_9_open-orders",
"ok": "ok"
}

Order placement request

Request Example:

Parameter Name Value Description
pair ----- Requested currency pair. Consists of ccy1 and ccy2 parameters.
ccy1 ISO 4217 Currency 1
ccy2 ISO 4217 Currency 2
amount decimal Order amount
price decimal Order price
type Buy / Sell Order direction
oid string OID identifier (number / text)
{
"e": "place-order",
"data": {
   "pair": [
      "BTC",
      "USD"
   ],
   "amount": 0.02,
   "price": "241.9477",
   "type": "buy"
},
"oid": "1435927928274_7_place-order"
}

Response Example:

Parameter Name Value Description
complete boolean Order completion status
id integer Order ID
time timestamp-ms Time identifier
pending decimal Order pending amount
amount decimal Order amount
type Buy / Sell Order direction
price decimal Order price
oid string OID identifier (number / text)
{
"e": "place-order",
"data": {
   "complete": false,
   "id": "2477098",
   "time": 1435927928618,
   "pending": "0.02000000",
   "amount": "0.02000000",
   "type": "buy",
   "price": "241.9477"
},
"oid": "1435927928274_7_place-order",
"ok": "ok"
}

Order cancel-replace request

Do atomic cancel & place order.

Do nothing if:

  • order with order_id is done/canceled/doesn't exist
  • insufficient funds
  • pair, order type did not match
  • price & amount are out of limits
  • amount = 0
  • apikey does not contain acl: acl_cancel_order

Request Example:

Parameter Name Value Description
pair ----- Requested currency pair. Consists of ccy1 and ccy2 parameters.
ccy1 ISO 4217 Currency 1
ccy2 ISO 4217 Currency 2
amount decimal Order amount
price decimal Order price
type Buy / Sell Order direction
oid string OID identifier (number / text)
order_id string Order id to replace
{
"e": "cancel-replace-order",
"data": {
   "order_id": "2477098",
   "pair": [
      "BTC",
      "USD"
   ],
   "amount": 0.04,
   "price": "243.2500",
   "type": "buy"
},
"oid": "1443464955209_16_cancel-replace-order"
}

Response Example (the same as in place order):

Parameter Name Value Description
complete boolean Order completion status
id integer Order ID
time timestamp-ms Time identifier
pending decimal Order pending amount
amount decimal Order amount
type Buy / Sell Order direction
price decimal Order price
oid string OID identifier (number / text)
{
"e": "cancel-replace-order",
"data": {
   "complete": false,
   "id": "2689009",
   "time": 1443464955904,
   "pending": "0.04000000",
   "amount": "0.04000000",
   "type": "buy",
   "price": "243.25"
},
"oid": "1443464955209_16_cancel-replace-order",
"ok": "ok"
}

Get order request

In CEX.IO system, orders can be present in trade engine or in archive database. There can be time periods (~2 seconds or more), when order is done/canceled, but still not moved to archive database. That means, you cannot see it using calls: archived-orders/open-orders. This call allows to get order information in any case. Responses can have different format depending on orders location.

Request Example:

Parameter Name Value Description
order_id integer Order identifier
oid string OID identifier (number / text)
{
"e": "get-order",
"data": {
   "order_id": "2689652"
},
"oid": "1443468122384_14_get-order"
}

Fields:

Parameter Name Value Optional Description
orderId integer Mandatory Order identifier
time timestamp-ms Mandatory Time identifier
oid string Mandatory OID identifier (number / text)
type string Mandatory Order type (buy/sell)
symbol1 ISO 4217 Mandatory
symbol2 ISO 4217 Mandatory
amount string/float Mandatory Amount in symbol1
remains string/float Mandatory Remains in symbol1
amount2 string/float Present for Instant buy orders Amount in symbol2, for this order types amount == 0, remains == 0
price string/float Present only for limit orders Price for limit order
tradingFeeStrategy string Can be absent Technical field telling how system calculates fee for this order
tradingFeeBuy string/float Can be absent Fee for Buy orders
tradingFeeSell string/float Can be absent Fee for Sell orders
tradingFeeUserVolumeAmount string/float Can be absent or nil User volume amount in BTC in satoshi
a:${symbol1}:c, a:${symbol2}:c string/float Can be absent Credit (total amount transferred to order)
a:${symbol1}:d, a:${symbol2}:d string/float Can be absent Debit (total amount transferred from order)
a:${symbol1}:s, a:${symbol2}:s string/float Can be absent Saldo for one symbol in case of cancelling a non-matching order
a:${symbol1}:cds, a:${symbol2}:cds string/float If a:${symbol}:s == 0 and a:${symbol}:d == a:${symbol}:c Total turnover for symbol
status string Order status: "d" — done (fully executed), "c" — canceled (not executed), "cd" — cancel-done (partially executed)
ta:${symbol2} string/float Present if order matched with another order Total amount transferred between matched orders in symbol 2. Used for fee calculation.
fa:${symbol2} string/float Present if order matched with another order Fee amount charged for this order in symbol 2.

Response Example (from archive database (active order)):

{
"e": "get-order",
"data": {
   "user": "XXX",
   "type": "buy",
   "symbol1": "BTC",
   "symbol2": "USD",
   "amount": "0.02000000",
   "remains": "0.02000000",
   "price": "50.75",
   "time": 1450214742160,
   "tradingFeeStrategy": "fixedFee",
   "tradingFeeBuy": "5",
   "tradingFeeSell": "5",
   "tradingFeeUserVolumeAmount": "nil",
   "a:USD:c": "1.08",
   "a:USD:s": "1.08",
   "a:USD:d": "0.00",
   "status": "a",
   "orderId": "5582060"
},
"oid": "1450214742135_10_get-order",
"ok": "ok"
}

Response Example (from archive database (canceled order)):

{
"e": "get-order",
"data": {
   "type": "buy",
   "time": 1443468122895,
   "user": "XXX",
   "status": "c",
   "symbol1": "BTC",
   "symbol2": "USD",
   "amount": "0.04000000",
   "price": "243.25",
   "remains": "0.04000000",
   "a:USD:cds": "10.22",
   "tradingFeeBuy": "5",
   "tradingFeeSell": "5",
   "tradingFeeStrategy": "fixedFee"
},
"oid": "1443468122384_21_get-order",
"ok": "ok"
}

Response example (from archive database (completed order)):

{
"e": "get-order",
"data": {
   "user": "XXX",
   "type": "sell",
   "symbol1": "BTC",
   "symbol2": "USD",
   "amount": "0.01000000",
   "remains": "0.00000000",
   "price": "447.63",
   "time": 1450341292623,
   "tradingFeeStrategy": "fixedFee",
   "tradingFeeBuy": "5",
   "tradingFeeSell": "5",
   "tradingFeeUserVolumeAmount": "nil",
   "ta:USD": "4.47",
   "fa:USD": "0.22",
   "status": "d",
   "orderId": "5668906",
   "a:BTC:cds": "0.01000000",
   "a:USD:cds": "4.47",
   "f:USD:cds": "0.22"
},
"oid": "1450341292568_14_get-order",
"ok": "ok"
}

Order cancel request

Request Example:

Parameter Name Value Description
order_id integer Order identifier
oid string OID identifier (number / text)
{
"e": "cancel-order",
"data": {
   "order_id": "2477098"
},
"oid": "1435927928274_12_cancel-order"
}

Response Example:

Parameter Name Value Description
order_id integer Order identifier
time timestam-ms Time identifier
oid string OID identifier (number / text)
{
"e": "cancel-order",
"data": {
   "order_id": "2477098"
   "time": 1443468122895
},
"oid": "1435927928274_12_cancel-order",
"ok": "ok"
}

List of archived orders

Request Example:

Parameter Name Value Description
pair ----- Requested currency pair. Consists of ccy1 and ccy2 parameters.
ccy1 ISO 4217 Currency 1
ccy2 ISO 4217 Currency 2
limit integer Number of orders in response (100 orders in response is a maximum)
dateFrom unix time Starting date for search
dateTo unix time Ending date for search
oid string OID identifier (number / text)
{
"e": "archived-orders",
"data": {
   "pair": [
      "BTC",
      "USD"
   ],
   "limit": 6
},
"oid": "1435927928274_15_archived-orders"
}

Response Example:

Parameter Name Value Description
type Buy / Sell Order direction
symbol1 ISO 4217 Currency 1
symbol2 ISO 4217 Currency 2
amount integer Amount of currency 1
amount2 integer Amount of currency 2
remains integer Remaining amount
time datetime Archived orders request datetime
tradingFeeBuy integer Buy Trading Fee size
tradingFeeSell integer Buy Trading Fee size
ta integer Total amount
fa integer Fee amount (always relates to 2nd currency )
orderId integer Order identifier
status dictionary Order status
a::cds integer Account turnover for currency 1
a::cds integer Account turnover for currency 2
oid string OID identifier (number / text)
{
"e": "archived-orders",
"data": [
   {
       "type": "buy",
       "symbol1": "BTC",
       "symbol2": "USD",
       "amount": 0,
       "amount2": 5000,
       "remains": 0,
       "time": "2015-04-17T10:46:27.971Z",
       "tradingFeeBuy": "2",
       "tradingFeeSell": "2",
       "ta:USD": "49.00",
       "fa:USD": "0.98",
       "orderId": "2340298",
       "status": "d",
       "a:BTC:cds": "0.18151851",
       "a:USD:cds": "50.00",
       "f:USD:cds": "0.98"
   },
   {
       "type": "buy",
       "symbol1": "BTC",
       "symbol2": "USD",
       "amount": 0,
       "amount2": 10000,
       "remains": 0,
       "time": "2015-04-08T15:46:04.651Z",
       "tradingFeeBuy": "2.99",
       "tradingFeeSell": "2.99",
       "ta:USD": "97.08",
       "fa:USD": "2.91",
       "orderId": "2265315",
       "status": "d",
       "a:BTC:cds": "0.39869578",
       "a:USD:cds": "100.00",
       "f:USD:cds": "2.91"
    }
],
"oid": "1435927928274    15_archived-orders",
"ok": "ok"
}

Open position

Does nothing if:

  • key does not provide permission for margin trading
  • pair or 'symbol' in params is invalid
  • leverage is invalid
  • amount is higher or less than allowed
  • stop-loss price is higher or less than valid (warrantable)
  • anySlippage is false and market data changed in a way that position can not be opened as requested

Request Example:

{
    "e": "open-position",
    "oid": "1435927928274_7_open-position",
    "data": {   
        'amount': '1',
        'symbol': 'BTC',
        "pair": [
            "BTC",
            "USD"
        ],
        'leverage': '2',
        'ptype': 'long',
        'anySlippage': 'true',
        'eoprice': '650.3232',
        'stopLossPrice': '600.3232'
    }
}

Request Parameters:

Parameter Name Value Description
symbol ISO 4217 currency to buy (product)
pair ----- requested currency pair. Consists of ccy1 and ccy2 parameters.
ccy1 ISO 4217 currency 1
ccy2 ISO 4217 currency 2
msymbol ISO 4217 currency of user funds used, may be one of cirrencies in the pair, default is second currency in the pair
amount string/float total amount of 'product' to buy using borrowed funds and user's funds
leverage string leverage ratio of total funds (user's and borrowed) to user's funds; for example: leverage=3 means: ratio total/user's=3:1, margin=33.(3)%, 1/3 is user's, 2/3 are borrowed; Note that in UI it will be presented as '1:3'
ptype string position type: 'long' - buying 'product', profitable if product price grows; 'short' - selling 'product', profitable if product price falls;
anySlippage string/boolean allows to open position at changed price
eoprice string/float estimated price at which your position will be opened
stopLossPrice string/float price near which your position will be closed automatically in case of unfavorable market conditions

Request Example:

{
    "e": "open-position",
    "oid": "1435927928274_7_open-position",
    "data": {   
        'amount': '1',
        'symbol': 'BTC',
        "pair": [
            "BTC",
            "USD"
        ],
        'leverage': '2',
        'ptype': 'long',
        'anySlippage': 'true',
        'eoprice': '650.3232',
        'stopLossPrice': '600.3232'
    }
}

Stop-loss Price:

  • Stop-loss price is bound to the minimum amount of the funds in the position you would like to get back in case of loss. Thus, if R is minimum amount in percents of user's funds to remain the stop-loss price may be computed as:
    • Long position (symbol='BTC', msymbol: 'EUR'):
      stoploss = (leverage - 1 + R% / 100%) / leverage * eoprice
    • Short position (symbol='BTC', msymbol: 'EUR'):
      stoploss = (leverage - R% / 100%) / (leverage - 1) * eoprice
    • Long position (symbol='BTC', msymbol: 'BTC'):
      stoploss = (leverage - 1 + R% / 100%) / leverage * eoprice
    • Short position (symbol='BTC', msymbol: 'BTC'):
      stoploss = leverage / (leverage - 1 + R% / 100%) * eoprice

Response Parameters:

Parameter Name Value Description
id integer the position id
otime timestamp-ms the position was opened at
psymbol ISO 4217 currency in wich the position was opened (product)
msymbol ISO 4217 currency in which user is going to gain profit, can be one of currencies, presented in the pair
lsymbol ISO 4217 currency of borrowed funds, can be one of currencies, presented in the pair
pair dictionary trading pair as a list of two symbols, presents the pair according to requested URL
pamount string/float total position amount, presented in 'psymbol'
omamount string/float ('open money amount') user's amount used in the position, presented in 'msymbol'
lamount string/float borrowed amount in the position, presented in 'lsymbol'
oprice string/float price the position was opened at, calculated as average of underlying executed orders
ptype string position type: 'long' or 'short'
stopLossPrice string/float price near which your position will be closed automatically in case of unfavorable market conditions
pfee string/float estimated fee (in %) from user's amount, that will be charged for position rollover for the next 4 hours
cfee string/float fee (in %) from user's amount, that will be charged for position closing
tfeeAmount string/float total fees paid by user, it is equal to opening fee amount, when position has been just opened

Note: the response does not contain all info on the position - use open-positions call to get complete information on open positions


Open positions

Does nothing if:

  • key does not provide permission for margin trading
  • pair in URL is invalid

Request Example:

{
    "e": "open-positions",
    "oid": "1435927928256_7_open-positions",
    "data": {   
        "pair": [
            "BTC",
            "USD"
        ]
    }
}

Request Parameters:

Parameter Name Value Description
pair ----- requested currency pair. Consists of ccy1 and ccy2 parameters.
ccy1 ISO 4217 currency 1
ccy2 ISO 4217 currency 2

Response Example:

{
    'e': 'open_positions',
    "oid": "1435927928256_7_open-positions",
    'ok': 'ok',
    'data': [
        {
            'user': 'ud100036721',
            'id': '104102',
            'otime': 1475602208467,
            'symbol': 'BTC',
            'amount': '1.00000000',
            'leverage': '2',
            'ptype': 'long',
            'psymbol': 'BTC',
            'msymbol': 'USD',
            'lsymbol': 'USD',
            'pair': 'BTC:USD',
            'oprice': '607.5000'
            'stopLossPrice': '520.3232',

            'ofee': '1',
            'pfee': '3',
            'cfee': '4',
            'tfeeAmount': '3.04',

            'pamount': '1.00000000',
            'omamount': '303.75',
            'lamount': '303.75',

            'oorder': '34106774',            
            'rinterval': '14400000',

            'dfl': '520.32320000',
            'slamount': '520.33',
            'slremains': '520.33',
            'lremains': '303.75',
            'flPrice': '303.75000000',
            'a:BTC:c': '1.00000000',
            'a:BTC:s': '1.00000000',
            'a:USD:cds': '610.54',
        },
        ...
    ]
}

Response Parameters:

Parameter Name Value Description
user string user id
id integer position id
otime timestamp-ms timestamp at which the position was opened
symbol ISO 4217 position currency (product)
amount string/float total amount used at opening position
leverage string/int leverage, the position was created with
ptype string position type: 'short' or 'long'
psymbol ISO 4217 currency, in which the position was opened (product)
msymbol ISO 4217 currency, in which user is going to gain profit, can be one of currencies, presented in the pair
lsymbol ISO 4217 currency of borrowed funds, can be one of currencies, presented in the pair
pair string trading pair as string like 'XXX:XXX'
oprice string/float price, at which the position was opened, calculated as average of underlying executed orders
stopLossPrice string/float price, near which your position will be closed automatically in case of unfavorable market conditions
ofee string/float fee (in %) from user's amount, that was charged for position opening
pfee string/float estimated fee (in %) from user's amount, that will be charged for position rollover for the next 4 hours
cfee string/float fee (in %) from user's amount, that will be charged for position closing
tfeeAmount string/float total fees paid by user, it is equal to opening fee amount, when position has been just opened
pamount string/float total position amount, presented in 'psymbol'
omamount string/float ('open money amount') user's amount used in the position, presented in 'msymbol'
lamount string/float borrowed amount in the position, presented in 'lsymbol'
oorder integer underlying order id for position opening
corder list list of underlying orders for position closing
rinterval integer rollover interval in millisecond
Tech fields
dfl string/float 'desired fast liquidation' price
slamount string/float ('stop-loss amount') amount that will be returned, including user's and borrowed funds
slremains string/float remains of slamount to return
lremains string/float amount of borrowed funds to be returned by user
flPrice string/float estimated price of total loss
a:BTC:c string/float credit in psymbol
a:BTC:d string/float debit in psymbol
a:BTC:s string/float saldo in psymbol
a:USD:cds string/float aquation c==d, s==0

Close position

Does nothing if:

  • key does not provide permission for margin trading
  • position with 'id' does not exist, cancelled or done

Request Example:

{
    "e": close-position",
    "oid": "1435927928364_7_close-position",
    "data": {   
        "pair": [
            "BTC",
            "USD"
        ]
        'id': '10245'
    }
}

Request Parameters:

Parameter Name Value Description
pair ----- requested currency pair. Consists of ccy1 and ccy2 parameters.
ccy1 ISO 4217 currency 1
ccy2 ISO 4217 currency 2
id integer position id

Response Example:

{   
    'e': 'close_position',
    "oid": "1435927928364_7_close-position",
    'ok': 'ok',
    'data': {
        'id': 104034,
        'ctime': 1475484981063,
        'ptype': 'long',
        'msymbol': 'USD'
        'pair': {
            'symbol1': 'BTC',
            'symbol2': 'USD'
        }
        'price': '607.1700',
        'profit': '-12.48',
    }
}

Response Parameters:

Parameter Name Value Description
id integer position id
ctime timestamp-ms timestamp, at which the position was closed
ptype string position type: 'long' or'short'
msymbol ISO 4217 currency, in which user gained or lost
price string/float price, at which the position was closed, calculated as average of underlying executed orders
pair dictionary trading pair
profit string/float positive if user gained, negative - if lost, presented in currency 'msymbol'

Asynchronous messages

Asynchronous messages are those that can be received in asynchronous way. Usually, these messages are obtained after order book changes (order submission, cancelation, market data update, etc.).

Transaction created (Order successfully completed)

Message example:

Parameter Name Value Description
order integer Order ID
a ISO 4217 Purchase currency
user string User ID
symbol ISO 4217 Currency1
symbol2 ISO 4217 Currency2
amount integer Trade amount
buy integer Order ID for BUY transaction
sell integer Order ID for SELL transaction
price decimal Order price
type Buy / Sell Order direction
time timestamp-ms Time identifier
balance integer User balance in Purchase currency
fee_amount integer Trade Fee size
_id integer Identifier
{
"e": "tx",
"data": {
   "d": "order:3346263232:a:USD",
   "c": "user:lukianie:a:USD",
   "a": 260,
   "user": "lukianie",
   "symbol": "USD",
   "symbol2": "BTC",
   "amount": 260,
   "buy": 3346261766,
   "sell": 3346263232,
   "price": 261.2994,
   "type": "sell",
   "time": 1439460482708,
   "balance": 286,
   "fee_amount": 1,
   "_id": "c773ecc60000000000000000"
}
}

Balance message

Message example:

Parameter Name Value Description Precision
symbol ISO 4217 Currency
balance integer Current balance per currency 1 USD = 100 units, 1 BTC = 100000000 units, 1 ETH = 1000000 units
{
"e": "balance",
"data": {
   "symbol": "BTC",
   "balance": "292012361221"
}
}

OBalance message

Balance of user orders.

Message example:

Parameter Name Value Description Precision
symbol ISO 4217 Currency
balance integer Current balance per currency 1.00 USD = 100 units
{
"e": "obalance",
"data": {
   "symbol": "BTC",
   "balance": "0"
}
}

Market data update

Parameter Name Value Description
id integer MD request identifier
pair ----- Requested currency pair. Consists of ccy1 and ccy2 parameters.
ccy1 ISO 4217 Currency 1
ccy2 ISO 4217 Currency 2
time timestamp-ms Time identifier
bids array Bid values
asks array Ask values
{
"e": "md_update",
"data": {
   "id": 67814,
   "pair": "BTC:USD",
   "time": 1435927928879,
   "bids": [
      [
         241.9477,
         0
      ],
      ...
   ],
   "asks": []
}
}

Standalone responses

Standalone responses are responses providing up-to-date information about the order in WebSocket API. You will get constant updates about remains of the order till it is fully executed, and its remains are equal to zero. Note that amount of remains is shown in Satoshi. Here’s an example showing partial execution of the order:

{
"e": "order",
"data": {
   "id": "2413792",
   "remains": "16000000",
   "pair": {
      "symbol1": "BTC",
      "symbol2": "USD"
   }
}
}

This is an example of cancel order:

{
"e": "order",
"data": {
    "id": "6310857",
    "remains": "200000000"
    "fremains" :"2.00000000"
    "cancel": true,
    "pair":
        { "symbol1": "BTC", "symbol2": "USD" }
    }
}

Examples of error responses

Authenticate

Request:

{
    "e": "auth",
    "auth": {
       "key": "1WZbtMTbMbo2NsW12vOz9IuPM.",
       "signature": "02483c01efc26fac843dd34d0342d269bacf4daa906a32cb71806eb7467dcf58",
       "timestamp": 1448034533
    }
}

Response:

{
    "e": "auth",
    "data": {
        "error": "Invalid Key" / "Key not activated" / "Invalid Signatue" / "Timestamp is not in 20 sec range"
    },
    "ok": "error"
}

Ticker

Request:

{
"e": "ticker",
"data": [
   "undefined",
   "Unknown"
],
"oid": "1435927928274_17_ticker"
}

Response:

{
"e": "ticker",
"data": {
   "error": "Invalid pair:undefined:Unknown."
},
"oid": "1435927928274_17_ticker",
"ok": "error"
}

Order book subscription

Request:

{
"e": "order-book-subscribe",
"data": {
   "pair": [
      "Undefined",
      "Unknown"
   ],
   "subscribe": false,
   "depth": -1
},
"oid": "1435927928274_18_order-book-subscribe"
}

Response:

{
"e": "order-book-subscribe",
"data": {
   "error": "Invalid pair:Undefined:Unknown."
},
"oid": "1435927928274_18_order-book-subscribe",
"ok": "error"
}

Unsubscribe from order book

Request:

{
"e": "order-book-unsubscribe",
"data": {
   "pair": [
      "Undefined",
      "Unknown"
   ]
},
"oid": "1435927928274_19_order-book-unsubscribe"
}

Response:

{
"e": "order-book-unsubscribe",
"data": {
   "error": "Invalid pair:Undefined:Unknown."
},
"oid": "1435927928274_19_order-book-unsubscribe",
"ok": "error"
}

Order placement

Request:

{
"e": "place-order",
"data": {
   "pair": [
      "Undefined",
      "Unknown"
   ],
   "amount": 0.02,
   "price": 241.9485,
   "type": "sell"
},
"oid": "1435927928274_20_place-order"
}

Response:

{
"e": "place-order",
"data": {
   "error": "There was an error while placing your order: Wrong currency pair."
},
"oid": "1435927928274_20_place-order",
"ok": "error"
}

Notice regarding Python 2.7 libraries

During testing of Reconnection phase for WebSockets, some specific issues were found in Python library.

The issue relates to different behaviors for High and Low level parameters in library.

In our case, after system got reconnected to WebSocket, sock parameter was not set to zero.

Below you can see how this issue was resolved inside CEX.IO WebSocket server:

def connect(ws=0):
     url = "wss://ws.cex.com"
     websocket.enableTrace(False)
     if not ws:
          ws = websocket.WebSocketApp(url,
                    header={
                         'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
                         'Accept-Language': 'en-us',
                         'Keep-Alive': '300',
                         'Connection': 'keep-alive',
                         'Cache-Control': 'max-age=0'},
                    cookie="_gat=1; _ga=GA1.2.844654147.1407933481",
                    on_message=on_message, on_error=on_error, on_close=on_close)
          ws.on_open = on_open
ws.sock = None
ws.run_forever(sslopt={"cert_reqs": False})

Python 3.5 library

For your convenience, we have developed a library for Python 3.5 Client.