Потоки 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}КопіяПриклад реалізації
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 Копія