Skip to content

Developers

WebSocket client library

@cloud9trader/websocket-api-client is the JavaScript client for the WebSocket API. It runs in Node.js and in the browser, signs private connections, matches answers to requests, and reconnects with every subscription restored. Source: Cloud9Trader/websocket-api-client.

Terminal window
npm install @cloud9trader/websocket-api-client

In a web page without a bundler:

<script src="https://unpkg.com/@cloud9trader/websocket-api-client@0.0.25/dist/global.js"></script>
<script>
const client = new Cloud9Trader.Client({ key: "YOUR_API_KEY" })
</script>

Public market data, from Node.js or a browser:

import Client from "@cloud9trader/websocket-api-client"
const client = new Client({ key: process.env.C9T_API_KEY! })
client.on("connected", () => console.log("connected"))
client.on("error", (error) => console.error(error))
client.subscribe("price.EUR_USD:OANDA", (price) => console.log(price))
client.start()

Your account and orders, from Node.js only:

import Client from "@cloud9trader/websocket-api-client"
const client = new Client({ key: process.env.C9T_API_KEY!, secret: process.env.C9T_API_SECRET! })
client.subscribe("positions", (positions) => console.log(positions))
client.start()
client.on("connected", () => {
client.submit("order", { broker: "Bitfinex", symbol: "BTCUSD", side: "BUY", type: "LIMIT", quantity: 0.01, limitPrice: 60000 }, (error, order) => {
if (error) return console.error("Refused:", error)
console.log("Accepted:", order)
})
})

The library refuses to start with a secret in a browser, so a secret never ends up in a web page.

Option Meaning
key Your API key. Required, even for public data.
secret Your API secret. Add it for the private socket. Node.js only.
host The socket address. Defaults to wss://sockets.cloud9trader.com.
Method What it does
start() Opens the socket. Call it once.
isConnected() true while the socket is open.
on(event, handler) Listens for connected, disconnected, status or error.
subscribe(topic, listener) Calls listener with each snapshot and update. Subscribing before start() or while disconnected is fine: it waits for the connection.
unsubscribe(topic, listener) Removes a listener. The last one removed unsubscribes on the server. Pass the same function you subscribed with.
request(topic, (error, data) => {}) Asks for a topic once. Gives up after 3 seconds with error set to "timeout".
submit("order", order, (error, order) => {}) Sends an order. See Submit an order. Gives up after 5 seconds with "timeout", and answers "Socket is not connected" straight away when disconnected.

Avoid fetchInstruments() and fetchHistoricalPrice() for now: they do not send your key. Call the REST API directly instead.

Event Arguments When
connected none The socket opened.
disconnected none The socket closed. The library reconnects by itself.
status Connected, Disconnected, Waiting for reconnect or Error The connection changed state.
error the error The socket failed. A refused private connection gives “401 Authentication rejected by server. Check that your key and secret are correct”.

When the socket closes, the library waits and reconnects: 1, 1, 2, 2, 4, 4, 8 and 8 seconds, then every 15 seconds until it connects. It signs each new private connection afresh and subscribes to every topic again. Keep your own order book or position list ready to be replaced by the new snapshot.

The library does not send ["ping"], so a connection that dies silently is only noticed when the network reports it. If that matters to you, check that updates keep arriving.