Потоки WebSocket
Тайм-аут соединения
- Сервер закрывает WebSocket-соединение через 60 секунд бездействия (поддержание соединения).
- Под неактивностью понимается отсутствие запросов, отправленных клиентом.
Поддержание соединения
Для поддержания активности соединения 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}СкопироватьПример реализации
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 Скопировать
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 СкопироватьОтписаться от мероприятий
Из конкретных валют
Базовая валюта из список рынков
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 Скопировать