Потоки WebSocket
Час очікування підключення
- Сервер закриває з’єднання WebSocket через 60 секунд бездіяльності (Connection Keep-Alive)
- Бездіяльність визначається як відсутність запитів, надісланих клієнтом
Підключення 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
Копія