Cryptowatch offers a Websocket API that supports real-time data streaming and trading.

The API consists of two separate back ends. Although they are separate services, both share the same connection and authentication logic, and are considered to be part of the same API. You can use one API key pair for both streaming and trading.

The streaming and trading services are hosted at wss://stream.cryptowat.ch and wss://broker.cryptowat.ch respectively.

Beta Invitation

This API is currently in an invite-only beta testing phase. Please inquire here if you are interested in getting access to it.

Messaging (protobuf)

All messages sent over the Websocket API are encoded using Protocol Buffers (protobuf). protobuf was chosen over JSON mainly for its high efficiency, although there are many other benefits.

Our protobuf definitions are available at github.com/cryptowatch/proto.

Strings Vs Floats

All price, ID, and subscription data are represented as string. This is to prevent loss of significant digits from using float, as well as to provide a consistent and simple API.

Deprecation Warning

Most protobuf message fields that use float are deprecated in favor of a string replacement. It is recommended you use the latest version of our client libraries which properly handle this deprecation.

Client Libraries

The best way to connect to the API is with one of the official client libraries. They properly handle authentication, and provide a useful abstraction from our messaging layer. We have libraries written for Golang and Node.js:

Writing Your Own Library

You can write a client library in any language using the documentation on this page, our protobuf definitions, and one of our official libraries as a reference implementation. If you write a client, send us a link and we'll share it here!


Unlike our REST API, each connection to the Websocket API must be authenticated with an API key and secret key. When establishing a connection, the client must send an APIAuthenticationMessage containing their public key, a nonce, and a token which is an HMAC-SHA-512 created with the corresponding secret key.

An example implementation of generating the token can be found in ws-client-go.


To stream data, clients should connect to wss://stream.cryptowat.ch and provide a list of data subscriptions.

The client will receive live updates for each subscription until the connection is closed.


Data subscriptions are strings formatted as a colon-separated scope, resource ID, and subject. For example, the subscription exchanges:4:trades is a feed of all trades in the scope exchanges where the resource ID is 4 (Kraken) and the subject is trades. A client that subscribes to exchanges:4:trades will receive all trade updates for the Kraken exchange.

A client can subscribe to a feed by supplying subscriptions with the APIAuthenticationMessage, or dynamically using ClientSubscribeMessage. Similarly, it can unsubscribe using ClientUnsubscribeMessage.

It is possible to have up to 100 subscriptions per connection.


  • markets: a single market; e.g. kraken btc/eur
  • exchanges: all markets on an exchange; e.g. kraken
  • pairs: all markets for a given pair; e.g. btc/eur
  • assets: all markets for a given asset; e.g. btc

Resource IDs

Use the REST API to obtain resource IDs for the various scopes:

For example,


For some subjects, you can also use a wildcard * scope the subscription to all markets or pairs.

  • markets:*: all markets in the system
  • pairs:*: all pairs in the system

Below we enumerate all possible subscription types, and the scopes they support.

Trade Feed

Proto message type: TradesUpdate

markets:68:tradesA feed of trades for a single market
markets:*:tradesA feed of trades for all markets
exchanges:4:tradesA feed of all trades on a given exchange
pairs:232:tradesA feed of all trades for a given pair
assets:60:tradesA feed of all trades for a given asset

See our example code for consuming a trade feed.

24 Hour Market Summary

Periodic messages summarizing a given market over the last 24 hours, including last price, total volume, total quote volume, and price change.

Proto message type: SummaryUpdate

markets:68:summaryMarket summary updates for a single market
markets:*:summaryMarket summary updates for all markets
markets:*:summary-low-volumeMarket summary updates for all markets throttled to one every 2 minutes
exchanges:4:summaryMarket summary updates for a given exchange
pairs:232:summaryMarket summary updates for a given pair
assets:60:summaryMarket summary updates for a given asset

OHLC (Candlesticks)

Also known as "candlestick" data, an OHLC subscription publishes updates to the latest candlestick for each time period. See also REST API OHLC data for reference.

Proto message type: IntervalsUpdate

markets:68:ohlcOHLC (candlestick) updates for a single market

Order Book

We publish real-time updates to the spread (best bid & ask) for the order book.

Proto message type: OrderBookSpreadUpdate

markets:68:book:spreadOrder book spread updates for a given market
markets:*:book:spreadOrder book spread updates for all markets
exchanges:4:book:spreadOrder book spread updates for a given exchange
pairs:232:book:spreadOrder book spread updates for a given pair
assets:60:book:spreadOrder book spread updates for a given asset

The structure of our orderbook data is going through some changes. We will document full order book feeds soon! Let us know if you are interested in this data.

Example Code

some example code showing how to connect, authenticate, subscribe to feeds, and consume the messages received:

  • kraken-trades - prints a real-time feed of all trades on a single exchange
  • print-quotes - prints real-time quotes for a given pair across all supported exchanges


To trade over websockets, clients should connect to wss://broker.cryptowat.ch and provide a list of market IDs to trade on. Once authenticated, the client will receive live updates for orders, trades, balances, and positions, and can place or cancel orders on any of the subscribed markets.


For the trade client, subscriptions are just a list of string market IDs you intend to trade on and receive updates for. For example, to trade on both Kraken btc/usd and Bitfinex btc/usd, you would provide 1 and 87 in subscriptions sent with the APIAuthenticationMessage. You can find the market IDs you need using our API: https://api.cryptowat.ch/markets.

Just like data streaming subscriptions, you can enable or disable markets dynamically using ClientSubscribeMessage and ClientUnsubscribeMessage.


Once authenticated, the trading back end will send a SessionStatusUpdate where initialized is true for each of the subscribed markets, after which point it can place and cancel orders on the initialized markets.


The trading back end keeps track of the following trading properties for each of the subscribed markets, and sends updates as they occur: orders, trades, balances, and positions. The official client libraries handle the following updates and keep an internal cache for convenience.

Orders (proto: OrdersUpdate)

OrdersUpdate is sent for each new order and any subsequent change to that order. For example, if an order is partially filled, a new OrdersUpdate will be sent. OrdersUpdate always contains all active orders for the given market.

Trades (proto: TradesUpdate)

Initially, the last 1000 trades for the subscribed market are sent to the client in a TradesUpdate. Then any subsequent trade updates are sent in the same manner. The clients will maintain a cache of 1000 trades per market, removing the oldest as new updates occur.

Balances (proto: BalancesUpdate)

Balance updates contain a list of balances for each funding type (spot or margin) available on the exchange. BalancesUpdate is sent every time one of your balances changes on an exchange where you are subscribed to one of its markets.

Positions (proto: PositionsUpdate)

Position updates contain a list of positions. A position consists of a list of orders and trades, average price, amount open and closed, and the order side. PositionsUpdate is sent whenever your positions update on an exchange where you have a subscribed market.

Placing Orders

Once a market is initialized, the client can place orders with PlaceOrderRequest, by supplying a PrivateOrder. Internally, order requests and updates are both represented by PrivateOrder, but the client libraries properly abstract this logic and make a distinction between the two.

After an order has been placed, a RequestResolutionUpdate will be sent to the client containing the resulting PrivateOrder, as well as an error code. If the error code is 0, the order was placed successfully.

Subsequent updates to your orders will be sent with OrdersUpdate.

Cancelling Orders

The client can cancel orders by sending a CancelOrderRequest with the order ID to cancel. Similar to PlaceOrderRequest, a RequestResolutionUpdate will also be received to confirm the order was cancelled. To verify a cancelled order, it is sufficient to simply check if the error code is 0.


Sending a SyncRequest forces an update by polling the exchange on behalf of the user. This is done automatically by the client libraries upon initialization.

Sync should not normally be called explicitly; it is only useful in two scenarios:

  • an order is placed or cancelled outside of this client
  • there is something preventing our trading back end from actively polling for updates. This happens rarely, and for various reasons. For example, an exchange may rate limit one of our servers.