Потоки WebSocket
Тайм-аут соединения
- Сервер закрывает соединение WebSocket после 60 секунд бездействия (Connection Keep-Alive)
- Бездействие определяется как отсутствие запросов, отправленных клиентом.
Поддержание соединения
Чтобы сохранить соединение WebSocket активным, вам необходимо
- Отправлять периодические запросы каждые 50 секунд
- Правильно обрабатывайте потенциальные разрывы связи в логике вашего приложения.
Авторизация
Введение
Перед подписанием любых запросов WebSocket необходимо создать API-ключ в личном кабинете Cryptomus.
Подробные инструкции по созданию API-ключа доступны здесь
Получение одноразового токена для подключения
Перед подключением к серверу WebSocket вам необходимо получить одноразовый токен аутентификации.
Вы можете получить токен, отправив соответствующий запрос
Токен действителен в течение 5 минут или до первого успешного подключения.
Подключение к серверу WebSocket
Для подключения к серверу WebSocket
1. Получите одноразовый токен аутентификации
2. Укажите токен в параметре запроса token при установлении соединения.
Пример URL-адреса подключения: wss://api-ws.cryptomus.com/ws?token=b0b1cacd26993392ecf072155bd1686c96e380ad12cefa564aa6665c85c77334
Токен можно использовать только один раз. Для каждого нового подключения необходимо запрашивать новый токен.
После успешной проверки токена соединение будет установлено, и вы сможете подписаться на доступные каналы.
Получение одноразового токена аутентификации для WebSocket-подключения
Позволяет сгенерировать одноразовый токен аутентификации для подключения к серверу WebSocket. Токен действителен до первого успешного подключения или до истечения срока его действия (5 минут).
Заголовки авторизации
Доступна полная информация о необходимых заголовках авторизации. здесь
Ответ
{ "token": "168b34a3a12370740ff1654f0d0c4726ff1bba8c4675edc0d7553f15e5a2a094" }
СкопироватьВозможные коды
200: Заказ успешно создан.
404: Пользователь или ресурс не найден.
500: Внутренняя ошибка сервера.
Символы шкалы глубины
Запрос
Ответ
1{
2 "status": "success",
3 "message": "success",
4 "data": [
5 {
6 "scale": "0.01",
7 "index": 0 // index
8 },
9 ...
10 ]
11}
СкопироватьСписок рынков
Запрос
Ответ
1{
2 "result": [
3 {
4 "id": "01HSBPVS17CT2GN2FV34K3AMP9",
5 "symbol": "BTC_USDT",
6 "baseCurrency": "BTC",
7 "quoteCurrency": "USDT",
8 "baseMinSize": "0.0000100000000000",
9 "quoteMinSize": "0.1000000000000000",
10 "baseMaxSize": "10000000000.0000000000000000",
11 "quoteMaxSize": "99999999.0000000000000000",
12 "basePrec": "8",
13 "quotePrec": "6",
14 "baseCurrencyFullName": "Bitcoin",
15 "quoteCurrencyFullName": "Tether USD"
16 },
17 ...
18 ]
19}
СкопироватьПример реализации
Node.js
1const WebSocket = require('ws');
2
3class CryptomusWebSocket {
4 constructor(token) {
5 this.token = token;
6 this.socket = new WebSocket('wss://api-ws.cryptomus.com/ws?token=${this.token}');
7 this.setupConnection();
8 }
9
10 setupConnection() {
11 this.socket.on('open', () => {
12 console.log('Connected to Cryptomus WebSocket');
13 this.startPing();
14 });
15
16 this.socket.on('message', (data) => {
17 console.log('Received:', data.toString());
18 });
19 }
20
21 ping() {
22 if (this.socket.readyState === WebSocket.OPEN) {
23 this.socket.send(JSON.stringify({
24 id: 0,
25 method: "ping",
26 params: []
27 }));
28 }
29 }
30
31 startPing() {
32 setInterval(() => {
33 this.ping();
34 }, 50 * 1000); // Every 50 seconds
35 }
36}
37
38// Usage
39const token = "your_auth_token_here";
40const client = new CryptomusWebSocket(token);
41
СкопироватьPython
1import asyncio
2import websockets
3import json
4
5class CryptomusWebSocket:
6 def __init__(self, token):
7 self.token = token
8 self.socket = None
9
10 async def connect(self):
11 self.socket = await websockets.connect(f"wss://api-ws.cryptomus.com/ws?token={self.token}")
12 print('Connected to Cryptomus WebSocket')
13
14 async def ping(self):
15 await self.socket.send(json.dumps({
16 "id": 0,
17 "method": "ping",
18 "params": []
19 }))
20
21 async def start_ping(self):
22 while True:
23 await asyncio.sleep(50) # Every 50 seconds
24 await self.ping()
25
26 async def listen(self):
27 async for message in self.socket:
28 print(f"Received: {message}")
29
30 async def run(self):
31 await self.connect()
32
33 # Start ping task
34 ping_task = asyncio.create_task(self.start_ping())
35
36 # Listen for messages
37 await self.listen()
38
39# Usage
40token = "your_auth_token_here"
41client = CryptomusWebSocket(token)
42asyncio.run(client.run())
43
СкопироватьВсе конечные точки возвращают время в формате временной метки Unix.
Структура запроса сообщения
Имя | Тип параметра | Описание |
---|---|---|
id | Integer | Должен быть уникальным для обработки ответа на ваш запрос. |
method | String | Имя запроса |
params | Array | Передайте параметры метода здесь. |
Тип параметра
IntegerОписание
Должен быть уникальным для обработки ответа на ваш запрос.Тип параметра
StringОписание
Имя запросаТип параметра
ArrayОписание
Передайте параметры метода здесь.
Соединение WebSocket будет разорвано, если отправлен недопустимый JSON.
Типы сообщений и запросов
- Запрос (`ping`, `candles_request` и т. д.)
- Подписка (`candles_subscribe`, `lastprice_subscribe` и т. д.). Повторная подписка на тот же тип данных будет отменена.
Ответное сообщение
Имя | Тип параметра | Описание |
---|---|---|
id | Integer | Запрос идентификатора |
data | Null | Если запрос не удался. В случае успеха структура ответа для каждого метода показана ниже. |
error | Null | Если всё прошло успешно. Если возникла ошибка |
message | String | |
code | Integer | Код ошибки |
Тип параметра
IntegerОписание
Запрос идентификатораТип параметра
NullОписание
Если запрос не удался. В случае успеха структура ответа для каждого метода показана ниже.Тип параметра
NullОписание
Если всё прошло успешно. Если возникла ошибкаТип параметра
IntegerОписание
Код ошибки
Код: 1. Сообщение: Неверный формат сообщения.
Код: 2. Сообщение: Другие ошибки
Типы ответных сообщений
- Результат запроса
- Статус подписки (успех/неудача)
- Обновление событий
Пинг-понг
Пинг
1{
2 "id": 0,
3 "method": "ping",
4 "params": []
5}
6
СкопироватьОтветный понг
1{
2 "id": 0,
3 "method": "pong",
4 "data": null,
5 "error": null
6}
7
СкопироватьПримеры подписок
Запрос
1{
2 "id": 0,
3 "method": "trade_subscribe",
4 "params": [
5 "BTC_USDT"
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "method": "trade_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
СкопироватьОбновление события
1{
2 "id": 0,
3 "method": "trade_update",
4 "data": [], // See structure for each method below
5 "error": null
6}
7
СкопироватьПоследняя цена
Подписка
1{
2 "id": 0,
3 "method": "lastprice_subscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "BTC_USDT",
7 "ETH_USDT",
8 ...
9 ]
10}
11
СкопироватьПодписаться на все события lastprice_subscribe
1{
2 "id": 0,
3 "method": "lastprice_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "method": "lastprice_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
СкопироватьСобытие
1{
2 "id": 0,
3 "method": "lastprice_update",
4 "data": {
5 "symbol": "BTC_USDT",
6 "timestamp": 1750953362,
7 "price": "107152.55"
8 },
9 "error": null
10}
11
СкопироватьОтмена подписки
Запрос
1{
2 "id": 0,
3 "method": "lastprice_unsubscribe",
4 "params": [
5 "BTC_USDT",
6 "ETH_USDT",
7 ...
8 ]
9}
10
СкопироватьОтписаться от всех событий lastprice_unsubscribe
1{
2 "id": 0,
3 "method": "lastprice_unsubscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
СкопироватьГлубина
Подписка
Сначала вам нужно получить индекс масштаба рынка. как добраться
1{
2 "id": 0,
3 "method": "depth_subscribe",
4 "params": [
5 "BTC_USDT:0", // market:scale_index
6 "BTC_USDT:1",
7 "ETH_USDT:1",
8 ...
9 ]
10}
11
СкопироватьПодписаться на все события depth_subscribe
1{
2 "id": 0,
3 "method": "depth_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "method": "depth_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
СкопироватьСобытие
1{
2 "id": 0,
3 "method": "depth_update",
4 "data": {
5 "symbol": "BTC_USDT",
6 "timestamp": 1750952911,
7 "full_reload": false, // If false, it is a partial update, if true, it is a fully updated orderbook.
8 "scale_index": 0,
9 "asks": [
10 [
11 "107043.93", // price
12 "0.304313" // value
13 ]
14 ],
15 "bids": [
16 [
17 "106976.11",
18 "0" // for partial update - finished orders will be 0
19 ]
20 ]
21 },
22 "error": null
23}
24
СкопироватьОтмена подписки
Запрос
1{
2 "id": 0,
3 "method": "depth_unsubscribe",
4 "params": [
5 "BTC_USDT:0", // market:scale_index
6 "ETH_USDT:1",
7 ...
8 ]
9}
10
СкопироватьОтписаться от всех событий depth_unsubscribe
1{
2 "id": 0,
3 "method": "depth_unsubscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
СкопироватьТикер
Подписка
1{
2 "id": 0,
3 "method": "ticker_subscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "BTC_USDT",
7 "ETH_USDT",
8 ...
9 ]
10}
11
СкопироватьПодписаться на все события ticker_subscribe
1{
2 "id": 0,
3 "method": "ticker_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "method": "ticker_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
СкопироватьСобытие
1{
2 "id": 0,
3 "method": "ticker_update",
4 "data": {
5 "symbol": "BTC_USDT",
6 "timestamp": 1750953144,
7 "price": "107090.35",
8 "open": "107042.21",
9 "high": "108248.15",
10 "low": "106573.19",
11 "volume": "1531.027982",
12 "quote_volume": "164564314.80174687",
13 "price_change": "0.04"
14 },
15 "error": null
16}
17
СкопироватьОтмена подписки
Запрос
1{
2 "id": 0,
3 "method": "ticker_unsubscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "ETH_USDT",
7 ...
8 ]
9}
10
СкопироватьОтписаться от всех событий ticker_unsubscribe
1{
2 "id": 0,
3 "method": "ticker_unsubscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
СкопироватьТорговля
Подписка
1{
2 "id": 0,
3 "method": "trade_subscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "BTC_USDT",
7 "ETH_USDT",
8 ...
9 ]
10}
11
СкопироватьПодписаться на все события trade_subscribe
1{
2 "id": 0,
3 "method": "trade_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "method": "trade_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
СкопироватьСобытие
1{
2 "id": 0,
3 "method": "trade_update",
4 "data": {
5 "symbol": "BTC_USDT",
6 "timestamp": 1750953177,
7 "trades": [
8 {
9 "price": 107100.01,
10 "quantity": 0.000254,
11 "timestamp": 1750953177,
12 "direction": "buy"
13 },
14 ...
15 ]
16 },
17 "error": null
18}
19
СкопироватьОтмена подписки
Запрос
1{
2 "id": 0,
3 "method": "trade_unsubscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "ETH_USDT",
7 ...
8 ]
9}
10
СкопироватьОтписаться от всех событий trade_unsubscribe
1{
2 "id": 0,
3 "method": "trade_unsubscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
СкопироватьЗаказы
Подписка
1{
2 "id": 0,
3 "method": "order_subscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "TRX_USDT",
7 "ETH_USDT",
8 ...
9 ]
10}
11
СкопироватьПодписаться на все события order_subscribe
1{
2 "id": 0,
3 "method": "order_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "method": "order_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
СкопироватьСобытия
Заказ создан
1{
2 "id": "1",
3 "method": "order_update",
4 "data": {
5 "type": "created",
6 "info": {
7 "id": "01JYET5DQ772MPYHHE417FQF1J",
8 "symbol": "TRX_USDT",
9 "orderType": "limit",
10 "direction": "sell",
11 "price": "0.2200000000000000",
12 "quantity": "50.0000000000000000",
13 "value": "11.0000000000000000",
14 "filledQuantity": "0.0000000000000000",
15 "filledValue": "0.0000000000000000",
16 "clientOid": null,
17 "createTs": 1750696376
18 }
19 },
20 "error": null
21}
22
СкопироватьЗаказ обновлен
1{
2 "id": "3",
3 "method": "order_update",
4 "data": {
5 "type": "updated",
6 "info": {
7 "id": "01JYET5DQ772MPYHHE417FQF1J",
8 "symbol": "TRX_USDT",
9 "orderType": "limit",
10 "direction": "sell",
11 "price": "0.2200000000000000",
12 "quantity": "50.0000000000000000",
13 "value": "11.0000000000000000",
14 "filledQuantity": "20.0000000000000000",
15 "filledValue": "4.4000000000000000",
16 "clientOid": null,
17 "createTs": 1750696376,
18 "updateTs": 1750696487,
19 }
20 },
21 "error": null
22}
23
СкопироватьЗаказ выполнен
1{
2 "id": "3",
3 "method": "order_update",
4 "data": {
5 "type": "finished",
6 "info": {
7 "id": "01JYET5DQ772MPYHHE417FQF1J",
8 "symbol": "TRX_USDT",
9 "orderType": "limit",
10 "direction": "sell",
11 "price": "0.2200000000000000",
12 "quantity": "50.0000000000000000",
13 "value": "11.0000000000000000",
14 "filledQuantity": "50.0000000000000000",
15 "filledValue": "11.0000000000000000",
16 "clientOid": null,
17 "createTs": 1750696376,
18 "finishTs": 1750696417,
19 "state": "completed""internalState": "filled"
20 }
21 },
22 "error": null
23}
24
СкопироватьОтписаться от обновлений
Из конкретных рынков
1{
2 "id": 0,
3 "method": "order_unsubscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "ETH_USDT",
7 ...
8 ]
9}
10
СкопироватьСо всех рынков
1{
2 "id": 0,
3 "method": "order_unsubscribe",
4 "params": [
5 "all" // Optional, will also work if an empty array is passed in
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
СкопироватьБалансы
Подписка
Базовая валюта от рыночный список
1{
2 "id": 0,
3 "method": "balance_subscribe",
4 "params": [
5 "BTC", // BaseCurrency from market list
6 "TRX,
7 "ETH",
8 ...
9 ]
10}
11
СкопироватьПодписаться на все события balance_subscribe
1{
2 "id": 0,
3 "method": "balance_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "method": "balance_subscribe",
4 "data": {
5 "status": "success"
6 },
7 "error": null
8}
9
СкопироватьСобытия
1{
2 "id": "4",
3 "method": "balance_update",
4 "data": {
5 "info": {
6 "walletId": "01J7E836F6K5KCX5DP2W0F6FAG",
7 "currencyCode": "USDT",
8 "amount": "50.0000000000000000",
9 "oldBalance": "40000.0000000000000000",
10 "newBalance": "39950.00000000"
11 }
12 },
13 "error": null
14}
15
СкопироватьОтписаться от событий
Из определенных валют
Базовая валюта от market-list
1{
2 "id": 0,
3 "method": "balance_unsubscribe",
4 "params": [
5 "BTC", // BaseCurrency from market list
6 "ETH",
7 ...
8 ]
9}
10
СкопироватьИз всех валют
1{
2 "id": 0,
3 "method": "balance_unsubscribe",
4 "params": [
5 "all" // Optional, will also work if an empty array is passed in
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
СкопироватьСделки
Подписка
1{
2 "id": 0,
3 "method": "deal_subscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "TRX_USDT,
7 "ETH_USDT",
8 ...
9 ]
10}
11
СкопироватьПодписаться на все события deal_subscribe
1{
2 "id": 0,
3 "method": "deal_subscribe",
4 "params": [
5 "all" // This also works for other events
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
СкопироватьСобытия
1{
2 "id": "4",
3 "method": "deal_update",
4 "data": {
5 "info": {
6 "dealId": "01JYH50V5VWPP3QTYGM6CPZ0AR",
7 "symbol": "TRX_USDT",
8 "dealState": "completed",
9 "transactionId": "01JYH50V5YM8M3943KJ9HY2VXM",
10 "filledPrice": "0.2726960000000000",
11 "filledQuantity": "100.0000000000000000",
12 "filledValue": "27.2696000000000000",
13 "fee": "1.0907840000000000",
14 "feeCurrency": "USDT",
15 "tradeRole": "taker",
16 "committedAt": 1750774869
17 }
18 },
19 "error": null
20}
21
СкопироватьОтписаться от обновлений
Из конкретных рынков
1{
2 "id": 0,
3 "method": "deal_unsubscribe",
4 "params": [
5 "BTC_USDT", // Market
6 "TRX_USDT,
7 ...
8 ]
9}
10
СкопироватьСо всех рынков
1{
2 "id": 0,
3 "method": "deal_unsubscribe",
4 "params": [
5 "all" // Optional, will also work if an empty array is passed in
6 ]
7}
8
СкопироватьОтвет
1{
2 "id": 0,
3 "data": {
4 "status": "success"
5 },
6 "error": null
7}
8
Скопировать