Skip to the content.

Coincabin Websockets API

To use the API, you may connect your program to the following endpoint:

wss://wss.coincabin.io

Testnet endpoint:

wss://wss.testnet.coincabin.io

Once connected, you can subscribe to a specific trading pair (such as the BTC perpetual future).

Then you’ll receive all updates about that trading pair automatically.

Optionally, you may also supply an API key. Then you’ll receive all personal updates about your account as well (such as orders, trades and withdrawals).

Here’s an example in Python:

  python3.6 -m pip install "websockets"
#!/usr/bin/env python
import asyncio
import websockets
import json

API_KEY = "YOUR_API_KEY" # Leave this out if you just want public data

async def hello():
    uri = "wss://wss.coincabin.io"
    async with websockets.connect(uri) as websocket:

        # Let's receive updates about the BTC/USD perpetual future!
        await websocket.send(json.dumps({"op": "sub_pair", "content": "USD_BTC_PERP"}))

        #  OPTIONAL: Let's also authenticate, so we can receive personal updates about our trades and orders
        await websocket.send(json.dumps({"op": "auth_api", "content": API_KEY}))

        async for message in websocket:
            parsed_message = json.loads(message) # Yay, we got a message! Let's parse it!
            category = parsed_message['category'] # Can be one of the categories listed at the bottom of this document
            result = parsed_message['pair'] # Is the message related to a specific trading pair?
            msg = parsed_message['msg'] # In case there is an error, this will contain the error message
            print(parsed_message)

asyncio.get_event_loop().run_until_complete(hello())

Using Javascript? Check out the Javascript example instead.

Contents

Subscribing

Receiving messages

Authenticating

Sending messages

Keeping the connection alive

Rate Limits

Trading Pairs

Usage examples

Message examples

Handling a message

Categories

Subscribing

To subscribe to a trading pair, you must send a JSON message in the following format:

   {
     op: "sub_pair",
     content: "USD_BTC_PERP"
   }

This message subscribes to all updates about the BTC/USD perpetual future (USD_BTC_PERP).

Once you have subscribed to a specific trading pair, you will automatically receive all updates about that pair (including order book changes, ticker changes, candlestick changes, trades and liquidations).

To subscribe only to ticker updates:

   {
     op: "sub",
     content: "USD_BTC_PERP:ticker"
   }

To unsubscribe from ticker updates:

   {
     op: "unsub",
     content: "USD_BTC_PERP:ticker"
   }

To unsubscribe from order book updates:

   {
     op: "unsub",
     content: "USD_BTC_PERP:depth"
   }

You may replace USD_BTC_PERP with a trading pair of your interest. For a list of valid trading pairs, see Trading Pairs.

You may also replace ticker with a category of your interest. For a list of valid categories, see Categories.

Getting the list of current subscriptions:

   {
     op: "subscriptions",
     content: "empty"
   }

Example result:

{
  code: 200,
  msg: 'subscriptions',
  result: [
    'USD_BTC_PERP:liquidation',
    'USD_BTC_PERP:index',
    'USD_BTC_PERP:ohlcv',
    'USD_BTC_PERP:match',
    'USD_BTC_PERP:trades',
    'USD_BTC_PERP:depth',
    'USD_BTC_PERP:ticker'
  ],
  pair: null,
  category: 'subscriptions'
}

Receiving messages

Once you are subscribed to a trading pair, you will start receiving messages.

Messages are returned in JSON format. Example:

   {
     code: 200,
     msg: "Order book changed!",
     category: "depth",
     pair: "USD_BTC_PERP",
     result: {
       bids: [{qty: 20, price: 90}],
       asks: [{qty: 10, price: 100}]
     }
   }

The category and result properties are essential here.

The category can be any of the following:

The result property contains a JSON object with the data of the message. This may be your position (in the case of position_updated), or a bunch of prices (in the case of ticker).

Authenticating

To authenticate, you must send a JSON message in the following format, replacing ** with your own API key:

   {
     op: "auth_api",
     content: "<YOUR_API_KEY>"
   }

Once you are authenticated, you will automatically receive updates about the following categories:

Sending messages

When sending a message, you must use the following format:

   {
     op: "sub",
     content: "USD_BTC_PERP:ticker"
   }

op can be any of the following:

When op is sub_pair, content must contain a valid trading pair, such as USD_BTC_PERP. For a list of valid trading pairs, see Trading Pairs.

When op is auth_api, content must contain a valid API key.

When op is sub, content must contain a valid trading pair, concatenated by a category. Example: USD_BTC_PERP:ticker.

When op is something else, content can be anything, as long as it’s not empty.

Keeping the connection alive

To keep the connection alive, it is good practice to periodically ping the server.

You can do so by sending a status message:

   {
     op: "status",
     content: "empty"
   }

If you send this once every 5 seconds, you should be good.

Note: You*must always be either subscribed to something, or authenticated. If you are not subscribed to anything, and you have not authenticated, your connection is considered inactive, and you will be disconnected after 30 seconds.

Rate Limits

You can be subscribed to a maximum of 10 public categories per client, and an unlimited amount of private categories.

If you must subscribe to more than 10 public categories, it is recommended that you use multiple connections.

You can maintain a maximum of 20 concurrent connections per account and per IP.

You can send a maximum of 15 messages per seconds per account and per IP.

Trading pairs

Trading pairs must be specified with their programmatic name.

For the BTC/USD perpetual future, that is USD_BTC_PERP.

For the ETH/USD perpetual future, that is USD_ETH_PERP.

The programmatic name can be retrieved from the contract specification on Coincabin.io, or through https://api.coincabin.io/pairs.

Examples:

USD_BTC_PERP, USD_ETH_PERP, USD_ADA_PERP, USD_BTC_PERP,

Message Examples

Subscribing to trade updates for the Ethereum perpetual future:

   {
     op: "sub",
     content: "USD_ETH_PERP:trades"
   }

Unsubscribing from liquidation updates for the ETH/USD perpetual future:

   {
     op: "unsub",
     content: "USD_ETH_PERP:liquidation"
   }

Unsubscribing from everything:

   {
     op: "unsub_all",
     content: "empty"
   }

Getting the list of current subscriptions:

   {
     op: "subscriptions",
     content: "empty"
   }

Unsubscribing from everything related to the BTC/USD perpetual future:

   {
     op: "unsub_pair",
     content: "USD_BTC_PERP"
   }

Usage Examples

Javascript:

  npm install --save ws
const ws = require('ws');
const socket = new ws('wss://wss.coincabin.io'); 
const API_KEY = 'YOUR_API_KEY';

socket.on('open', () => {
    console.info('Yay, we are connected!');
    // Lets' receive updates about the BTC/USD perpetual!
    socket.send(JSON.stringify({op: 'sub_pair', content: 'USD_BTC_PERP'}));
    // OPTIONAL: Let's also receive personal updates about our account, orders and trades!
    socket.send(JSON.stringify({op: 'auth_api', content: API_KEY}));
    // Let's also send a ping every 5 seconds (helps keep the connection open)!
    setInterval(() => socket.send(JSON.stringify({op: 'status', content: 'ok'})), 5000);
    socket.on('message', function(json){
      var message = JSON.parse(json); // Yay, we got a message! Let's parse it!
      var pair = message.pair; // Is the message related to a specific trading pair?
      var category = message.category; // Can be one of the categories listed at the bottom of this document
      var msg = message.msg; // In case there is an error, this will contain the error message
      console.info("Received message: ", message);
    });
});

setInterval(() => true, 10e6); // Keep the program running for a long time...

Python (3.6):

  python3.6 -m pip install "websockets"
#!/usr/bin/env python
import asyncio
import websockets
import json

API_KEY = "YOUR_API_KEY" # Leave this out if you just want public data

async def hello():
    uri = "wss://wss.coincabin.io"
    async with websockets.connect(uri) as websocket:

        # Let's receive updates about the BTC/USD perpetual future!
        await websocket.send(json.dumps({"op": "sub_pair", "content": "USD_BTC_PERP"}))

        #  OPTIONAL: Let's also authenticate, so we can receive personal updates about our trades and orders
        await websocket.send(json.dumps({"op": "auth_api", "content": API_KEY}))

        async for message in websocket:
            parsed_message = json.loads(message) # Yay, we got a message! Let's parse it!
            category = parsed_message['category'] # Can be one of the categories listed at the bottom of this document
            result = parsed_message['pair'] # Is the message related to a specific trading pair?
            msg = parsed_message['msg'] # In case there is an error, this will contain the error message
            print(parsed_message)

asyncio.get_event_loop().run_until_complete(hello())

Handling a message

When receiving a message, you would usually want to do something.

This is usually based on the category of the message.

Here is an example in Javascript of simply pretty printing the message, based on the category it contains:


socket.on('message', function(json){
  var message = JSON.parse(json);
  return handle_message(message);
});

function handle_message(message) {
  var pair = message.pair;
  switch(message.category) {
    case 'error': return console.error("An error occured: ", message.msg);
    case 'subscribed': return console.info("Subscribed to: ", message.result);
    case 'unsubscribed': return console.info("Unsubscribed from: ", message.result);
    case 'authenticated': return console.info("Succesfully authenticated!");
    case 'ticker': return console.info("New ticker: ", message.result);
    case 'depth': return console.info("Order book changed: ", message.result);
    case 'ohlcv': return console.info("New candle: ", message.result.ohlcv);
    case 'liquidation': return console.info("New liquidation: ", message.result);
    case 'match': return console.info("Orders were matched: ", message.result);
    case 'trades': return console.info("New trades: ", message.result);
    case 'index': return console.info("New mark price: ", message.result.mark);
    case 'order_added': return console.info("Your order was accepted: ", message.result);
    case 'order_cancelled': return console.info("Your order was cancelled: ", message.result);
    case 'order_triggered': return console.info("Your stop was triggered: ", message.result);
    case 'order_partially_completed': return console.info("Your order was filled partially: ", message.result);
    case 'order_completed': return console.info("Your order was filled completely: ", message.result);
    case 'trigger_added': return console.info("Your stop was accepted: ", message.result);
    case 'trigger_cancelled': return console.info("Your stop was cancelled: ", message.result);
    case 'trigger_failed': return console.info("Your stop failed: ", message.result);
    case 'deposit_added': return console.info("Your deposit was detected: ", message.result);
    case 'deposit_completed': return console.info("Your deposit was credited: ", message.result);
    case 'withdrawal_completed': return console.info("Your withdrawal was completed: ", message.result);
    case 'ok': return true;
    default: return console.info("Unknown category: ", message);
  }
}

Categories