NAV Navbar
Python Golang

Spot WebSocket v4

Demo WebSocket application

# !/usr/bin/env python
# coding: utf-8

import hashlib
import hmac
import json
import logging
import time

# pip install -U websocket_client
from websocket import WebSocketApp

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class GateWebSocketApp(WebSocketApp):

    def __init__(self, url, api_key, api_secret, **kwargs):
        super(GateWebSocketApp, self).__init__(url, **kwargs)
        self._api_key = api_key
        self._api_secret = api_secret

    def _send_ping(self, interval, event):
        while not event.wait(interval):
            self.last_ping_tm = time.time()
            if self.sock:
                try:
                    self.sock.ping()
                except Exception as ex:
                    logger.warning("send_ping routine terminated: {}".format(ex))
                    break
                try:
                    self._request("spot.ping", auth_required=False)
                except Exception as e:
                    raise e

    def _request(self, channel, event=None, payload=None, auth_required=True):
        current_time = int(time.time())
        data = {
            "time": current_time,
            "channel": channel,
            "event": event,
            "payload": payload,
        }
        if auth_required:
            message = 'channel=%s&event=%s&time=%d' % (channel, event, current_time)
            data['auth'] = {
                "method": "api_key",
                "KEY": self._api_key,
                "SIGN": self.get_sign(message),
            }
        data = json.dumps(data)
        logger.info('request: %s', data)
        self.send(data)

    def get_sign(self, message):
        h = hmac.new(self._api_secret.encode("utf8"), message.encode("utf8"), hashlib.sha512)
        return h.hexdigest()

    def subscribe(self, channel, payload=None, auth_required=True):
        self._request(channel, "subscribe", payload, auth_required)

    def unsubscribe(self, channel, payload=None, auth_required=True):
        self._request(channel, "unsubscribe", payload, auth_required)


def on_message(ws, message):
    # type: (GateWebSocketApp, str) -> None
    # handle whatever message you received
    logger.info("message received from server: {}".format(message))


def on_open(ws):
    # type: (GateWebSocketApp) -> None
    # subscribe to channels interested
    logger.info('websocket connected')
    ws.subscribe("spot.trades", ['BTC_USDT'], False)


if __name__ == "__main__":
    logging.basicConfig(format="%(asctime)s - %(message)s", level=logging.DEBUG)
    app = GateWebSocketApp("wss://api.gateio.ws/ws/v4/",
                           "YOUR_API_KEY",
                           "YOUR_API_SECRET",
                           on_open=on_open,
                           on_message=on_message)
    app.run_forever(ping_interval=5)
package main

import (
    "crypto/hmac"
    "crypto/sha512"
    "crypto/tls"
    "encoding/hex"
    "encoding/json"
    "fmt"
    "io"
    "net/url"
    "time"

    "github.com/gorilla/websocket"
)

type Msg struct {
    Time    int64    `json:"time"`
    Channel string   `json:"channel"`
    Event   string   `json:"event"`
    Payload []string `json:"payload"`
    Auth    *Auth    `json:"auth"`
}

type Auth struct {
    Method string `json:"method"`
    KEY    string `json:"KEY"`
    SIGN   string `json:"SIGN"`
}

const (
    Key    = "YOUR_API_KEY"
    Secret = "YOUR_API_SECRETY"
)

func sign(channel, event string, t int64) string {
    message := fmt.Sprintf("channel=%s&event=%s&time=%d", channel, event, t)
    h2 := hmac.New(sha512.New, []byte(Secret))
    io.WriteString(h2, message)
    return hex.EncodeToString(h2.Sum(nil))
}

func (msg *Msg) sign() {
    signStr := sign(msg.Channel, msg.Event, msg.Time)
    msg.Auth = &Auth{
        Method: "api_key",
        KEY:    Key,
        SIGN:   signStr,
    }
}

func (msg *Msg) send(c *websocket.Conn) error {
    msgByte, err := json.Marshal(msg)
    if err != nil {
        return err
    }
    return c.WriteMessage(websocket.TextMessage, msgByte)
}

func NewMsg(channel, event string, t int64, payload []string) *Msg {
    return &Msg{
        Time:    t,
        Channel: channel,
        Event:   event,
        Payload: payload,
    }
}

func main() {
    u := url.URL{Scheme: "wss", Host: "api.gateio.ws", Path: "/ws/v4/"}
    websocket.DefaultDialer.TLSClientConfig = &tls.Config{RootCAs: nil, InsecureSkipVerify: true}
    c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
    if err != nil {
        panic(err)
    }
    c.SetPingHandler(nil)

    // read msg
    go func() {
        for {
            _, message, err := c.ReadMessage()
            if err != nil {
                c.Close()
                panic(err)
            }
            fmt.Printf("recv: %s\n", message)
        }
    }()

    t := time.Now().Unix()
    pingMsg := NewMsg("spot.ping", "", t, []string{})
    err = pingMsg.send(c)
    if err != nil {
        panic(err)
    }

    // subscribe order book
    orderBookMsg := NewMsg("spot.order_book", "subscribe", t, []string{"BTC_USDT"})
    err = orderBookMsg.send(c)
    if err != nil {
        panic(err)
    }

    // subscribe positions
    ordersMsg := NewMsg("spot.orders", "subscribe", t, []string{"BTC_USDT"})
    ordersMsg.sign()
    err = ordersMsg.send(c)
    if err != nil {
        panic(err)
    }

    select {}
}

Gate.io provides a simple and robust Websocket API to integrate spot trade status into your business or application.

We have language bindings in Python and Golang. You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.

Server URL

Base URLs:

SDK

We provide WebSocket SDK to help developers with service integration.

The SDK's source code are available in gatews GitHub repository.

Changelog

2021-04-27

2021-03-17

2021-01-26

API Overview

WebSocket operations are divided into different channels. Channels are either public or private. While public channels can be subscribed to directly, private channels require authentication using Gate APIv4 key pairs(refer to Authentication down below for details).

All channels support the following events:

Initiated from the client. Client uses this method to tell the server that it is interested in this channel and requires the server to notify the new data if channel related data are changed.

Initiated from the client. Client uses this method to tell the server that it is no longer interested in this channel and stop sending any further channel updates.

Initiated from the sever. Server uses this method to send changed data to all clients subscribed to this channel. Client cannot use this operation event.

Client Request

{
  "time": 1611541000,
  "id": 123456789,
  "channel": "spot.orders",
  "event": "subscribe",
  "payload": [
    "BTC_USDT",
    "GT_USDT"
  ],
  "auth": {
    "method": "api_key",
    "KEY": "xxxx",
    "SIGN": "xxxx"
  }
}

subscribe or unsubscribe requests initiated from the client follow a common JSON format, which contains the following fields:

Field Type Required Description
time Integer Yes Request time in seconds. Gap between request time and server time must not exceed 60 seconds
id Integer No Optional request id which will be sent back by the server to help you identify which request the server responds to
channel String Yes WebSocket channel to subscribe to.
auth Auth No Authentication credentials for private channels. See Authentication section for details
event String Yes Channel operation event, i.e. subscribe, unsubscribe
payload Any No Optional request detail parameters

Note that the type of payload is channel specific, but subscribe and unsubscribe payloads in one channel are in the same format. Take spot.orders for example, the payload format is a list of currency pairs interested. You can specify ["foo", "bar", "etc"] as subscribe payload to receive order updates about them. Then specify ["etc"] in unsubscribe payload later to exclude it from futures order updates.

Channel specific description below only gives the channel specific payload format for simplicity, but you need to send the full request to do channel subscription operations.

Server Response

{
  "time": 1611541000,
  "channel": "spot.orders",
  "event": "subscribe",
  "error": null,
  "result": {
    "status": "success"
  }
}

Server response includes both response to client requests and server-initiated message updates. Similar with request, server responses follow almost the same JSON format with client requests:

Field Type Description
time Integer Response time in seconds.
id Integer Request ID extracted from the client request payload if client request has one
channel String WebSocket channel name
event String Server side channel event(i.e., update) or event used in requests initiated from the client
error Error Null if the server accepts the client request; otherwise, the detailed reason why request is rejected.
result Any New data notification from the server, or response to client requests. Null if error is not null.

Note: type of result is channel specific if it's server-initiated data update notification, but response to client subscription request always set the result to {"status": "success"}. To verify if subscription request is successful or not, you only need to check if error field is null. Parsing result field is not necessary.

Channel specific description below will only give the server-initiated data update notification format for simplicity.

Error

Error object has the following format:

Field Type Description
code Integer Error code
message String Detailed error reason

In case of errors, you receive a message containing the proper error code and message within an error object. Possible errors includes:

code message
1 Invalid request body format
2 Invalid argument provided
3 Server side error happened.

Authentication

Note: the GateAPIv4 key pair you used MUST have at least spot read permission enabled, and your outbound IP address must be in the key's IP whitelist if its whitelist is enabled.

# example WebSocket signature calculation implementation in Python
import hmac, hashlib, json, time


def gen_sign(channel, event, timestamp):
    # GateAPIv4 key pair
    api_key = 'YOUR_API_KEY'
    api_secret = 'YOUR_API_SECRET'

    s = 'channel=%s&event=%s&time=%d' % (channel, event, timestamp)
    sign = hmac.new(api_secret.encode('utf-8'), s.encode('utf-8'), hashlib.sha512).hexdigest()
    return {'method': 'api_key', 'KEY': api_key, 'SIGN': sign}


request = {
    'id': int(time.time() * 1e6),
    'time': int(time.time()),
    'channel': 'spot.orders',
    'event': 'subscribe',
    'payload': ["BTC_USDT", "GT_USDT"]
}
request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
print(json.dumps(request))

Client requests need to carry authentication information if channels are private, e.g. spot.orders channel to retrieve user orders update.

Authentication are sent by auth field in request body with the following format:

Field Type Description
method String Authentication method. Currently only one method api_key is accepted
KEY String Gate APIv4 user key string
SIGN String Authentication signature generated using GateAPIv4 secret and request information

WebSocket authentication uses the same signature calculation method with Gate APIv4 API, i.e., HexEncode(HMAC_SHA512(secret, signature_string)), but has the following differences:

  1. Signature string concatenation method: channel=<channel>&event=<event>&time=<time>, where <channel>, <event>, <time> are corresponding request information
  2. Authentication information are sent in request body in field auth.

You can log into the console to retrieve Gate APIv4 key and secret.

System API

System APIs used to retrieve service meta information. NOT used for subscription.

Application ping pong

spot.ping

Code samples

import time
# pip install websocket_client
from websocket import create_connection

ws = create_connection("wss://api.gateio.ws/ws/v4/")
ws.send('{"time": %d, "channel" : "spot.ping"}' % int(time.time()))
print(ws.recv())

Response example

{
  "time": 1545404023,
  "channel": "spot.pong",
  "event": "",
  "error": null,
  "result": null
}

Check if connection to server is still alive.

This is an additional connection reachability check. The server uses the protocol layer ping/pong message to check if client is still connected. It does NOT force this method to be used. If you use some well-known WebSocket client library, you generally don't need to care about this API.

However, from the client's view, this API can help the client to actively check if the connection to server is still reachable. Additionally, if the server receives the client's spot.ping request, it will also reset the client's timeout timer.

Tickers Channel

spot.tickers

The ticker is a high level overview of the state of the spot trading. It shows you the highest, lowest, last trade price. It also includes information such as daily volume and how much the price has changed over the last day.

Client Subscription

Code samples

import time
import json

# pip install websocket_client
from websocket import create_connection

ws = create_connection("wss://api.gateio.ws/ws/v4/")
ws.send(json.dumps({
    "time": int(time.time()),
    "channel": "spot.tickers",
    "event": "subscribe",  # "unsubscribe" for unsubscription
    "payload": ["BTC_USDT"]
}))
print(ws.recv())

Payload format:

Field Type Required Description
payload Array[String] Yes List of currency pairs

You can subscribe/unsubscribe multiple times. Currency pair subscribed earlier will not be overridden unless explicitly unsubscribed to.

Server Notification

{
  "time": 1606291803,
  "channel": "spot.tickers",
  "event": "update",
  "result": {
    "currency_pair": "BTC_USDT",
    "last": "19106.55",
    "lowest_ask": "19108.71",
    "highest_bid": "19106.55",
    "change_percentage": "3.66",
    "base_volume": "2811.3042155865",
    "quote_volume": "53441606.52411221454674732293",
    "high_24h": "19417.74",
    "low_24h": "18434.21"
  }
}

Result format:

Field Type Description
result Object Ticker object
» currency_pair String Currency pair
» last String Last price
» lowest_ask String Recent best ask price
» highest_bid String Recent best bid price
» change_percentage String Change percentage
» base_volume String Base volume
» quote_volume String Quote volume
» high_24h String Highest price in 24h
» low_24h String Lowest price in 24h

Public Trades Channel

spot.trades

This channel sends a trade message whenever a trade occurs. It includes details of the trade, such as price, amount, time and type.

Only the taker side in notified.

Note this is a public channel. For private trade notifications, refer to section User Trades below.

Client Subscription

Code samples

import time
import json

# pip install websocket_client
from websocket import create_connection

ws = create_connection("wss://api.gateio.ws/ws/v4/")
ws.send(json.dumps({
    "time": int(time.time()),
    "channel": "spot.trades",
    "event": "subscribe",  # "unsubscribe" for unsubscription
    "payload": ["BTC_USDT"]
}))
print(ws.recv())

Payload format:

Field Type Required Description
payload Array[String] Yes List of currency pairs

You can subscribe/unsubscribe multiple times. Currency pair subscribed earlier will not be overridden unless explicitly unsubscribed to.

Server Notification

{
  "time": 1606292218,
  "channel": "spot.trades",
  "event": "update",
  "result": {
    "id": 309143071,
    "create_time": 1606292218,
    "create_time_ms": "1606292218213.4578",
    "side": "sell",
    "currency_pair": "GT_USDT",
    "amount": "16.4700000000",
    "price": "0.4705000000"
  }
}

Note that public trade channel only notify the taker side in a trade. Private user trades channel below will notify all user related trades.

Result format:

Field Type Description
result Object Public trade detail
» id Integer Trade ID
» create_time Integer Trading unix timestamp in seconds
» create_time_ms String Trading unix timestamp in milliseconds. Precision higher than ms will be appended as decimal points
» side String Taker side
» currency_pair String Currency pair
» amount String Trade amount
» price String Trade price

Enumerated Values

Property Value
side buy
side sell

Candlesticks Channel

spot.candlesticks

Provides a way to access charting candlestick info.

Client Subscription

Code samples

import time
import json

# pip install websocket_client
from websocket import create_connection

ws = create_connection("wss://api.gateio.ws/ws/v4/")
ws.send(json.dumps({
    "time": int(time.time()),
    "channel": "spot.candlesticks",
    "event": "subscribe",  # "unsubscribe" for unsubscription
    "payload": ["1m", "BTC_USDT"]
}))
print(ws.recv())

Payload format:

Field Type Required Description
payload Array[String] Yes Subscription parameters. From left to right, interval, cp
» interval String Yes Candlestick data point interval
» cp String Yes Currency pair

Enumerated Values

Property Value
interval 10s
interval 1m
interval 5m
interval 15m
interval 30m
interval 1h
interval 4h
interval 8h
interval 1d
interval 7d

To subscribe to multiple currency pairs or with different intervals, just send multiple subscribe request with different parameters.

Server Notification

{
  "time": 1606292600,
  "channel": "spot.candlesticks",
  "event": "update",
  "result": {
    "t": "1606292580",
    "v": "2362.32035",
    "c": "19128.1",
    "h": "19128.1",
    "l": "19128.1",
    "o": "19128.1",
    "n": "1m_BTC_USDT"
  }
}

Result format:

Field Type Description
result Object One candlestick data point
» t String Unix timestamp in seconds
» v String Total volume
» c String Close price
» h String Highest price
» l String Lowest price
» o String Open price
» n String Name of the subscription, in the format of <interval>_<cp>

Order Book Channel

Order book has three channels for subscription to satisfy different needs. They are:

Pushes any update about the price and amount of best bid or ask price in realtime for subscribed currency pairs.

Periodically notify order book changed levels which can be used to locally manage an order book.

Periodically notify top bids and asks snapshot with limited levels.

Every currency pair's order book update has an internal update ID, which increments 1 on every order book update. The order book update ID corresponds to the id field in response of REST API GET /api/v4/spot/order_book.

How to maintain local order book:

  1. Subscribe spot.order_book_update, e.g. ["BTC_USDT", "1000ms"] pushes update in BTC_USDT order book every 1s
  2. Cache WebSocket notifications. Every notification use U and u to tell the first and last update ID since last notification.
  3. Retrieve base order book using REST API, and make sure the order book ID is recorded(referred as baseID below) e.g. https://api.gateio.ws/api/v4/spot/order_book?currency_pair=BTC_USDT&limit=100&with_id=true retrieves the full base order book of BTC_USDT
  4. Iterate the cached WebSocket notifications, and find the first one which the baseID falls into, i.e. U <= baseId+1 and u >= baseId+1, then start consuming from it. Note that amount in notifications are all absolute values. Use them to replace original value in corresponding price. If amount equals to 0, delete the price from the order book.
  5. Dump all notifications which satisfy u < baseID+1. If baseID+1 < first notification U, it means current base order book falls behind notifications. Start from step 3 to retrieve newer base order book.
  6. If any subsequent notification which satisfy U > baseID+1 is found, it means some updates are lost. Reconstruct local order book from step 3.

You can find example application implementing the methods above in the SDK GitHub repository

Best bid or ask price

spot.book_ticker

Client Subscription

Code samples

import time
import json

# pip install websocket_client
from websocket import create_connection

ws = create_connection("wss://api.gateio.ws/ws/v4/")
ws.send(json.dumps({
    "time": int(time.time()),
    "channel": "spot.book_ticker",
    "event": "subscribe",  # "unsubscribe" for unsubscription
    "payload": ["BTC_USDT"]
}))
print(ws.recv())

Payload format:

Field Type Required Description
payload Array[String] Yes List of currency pairs

You can subscribe/unsubscribe multiple times. Currency pair subscribed earlier will not be overridden unless explicitly unsubscribed to.

Server Notification

{
  "time": 1606293275,
  "channel": "spot.book_ticker",
  "event": "update",
  "result": {
    "t": 1606293275123,
    "u": 48733182,
    "s": "BTC_USDT",
    "b": "19177.79",
    "B": "0.0003341504",
    "a": "19179.38",
    "A": "0.09"
  }
}

Result format:

Field Type Description
result Object Order book ticker object
» t Integer Order book update time in milliseconds
» u Integer Order book update ID
» s String Currency pair
» b String best bid price
» B String best bid amount
» a String best ask price
» A String best ask amount

Changed order book levels

spot.order_book_update

Client Subscription

Code samples

import time
import json

# pip install websocket_client
from websocket import create_connection

ws = create_connection("wss://api.gateio.ws/ws/v4/")
ws.send(json.dumps({
    "time": int(time.time()),
    "channel": "spot.order_book_update",
    "event": "subscribe",  # "unsubscribe" for unsubscription
    "payload": ["BTC_USDT", "100ms"]
}))
print(ws.recv())

Payload format:

Field Type Required Description
payload Array[String] Yes Subscription parameters, from left to right, cp, interval
» cp String Yes Currency pair
» interval String Yes Notification update speed

Enumerated Values

Property Value
interval 100ms
interval 1000ms

Server Notification

{
  "time": 1606294781,
  "channel": "spot.order_book_update",
  "event": "update",
  "result": {
    "t": 1606294781123,
    "e": "depthUpdate",
    "E": 1606294781,
    "s": "BTC_USDT",
    "U": 48776301,
    "u": 48776306,
    "b": [
      [
        "19137.74",
        "0.0001"
      ],
      [
        "19088.37",
        "0"
      ]
    ],
    "a": [
      [
        "19137.75",
        "0.6135"
      ]
    ]
  }
}

Result format:

Field Type Description
result Object Changed order book levels
» t Integer Order book update time in milliseconds
» e String Ignore this field
» E Integer Update unix timestamp in seconds. Deprecated in favour of t
» s String Currency pair
» U Integer First update order book id in this event since last update
» u Integer Last update order book id in this event since last update
» b Array[OrderBookArray] Changed bids since last update, sort by price from high to low
»» OrderBookArray Array[String] [Price, Amount] pair
» a Array[OrderBookArray] Changed asks since last update, sort by price from low to high
»» OrderBookArray Array[String] [Price, Amount] pair

Limited-Level Full Order Book Snapshot

spot.order_book

Client Subscription

Code samples

import time
import json

# pip install websocket_client
from websocket import create_connection

ws = create_connection("wss://api.gateio.ws/ws/v4/")
ws.send(json.dumps({
    "time": int(time.time()),
    "channel": "spot.order_book",
    "event": "subscribe",  # "unsubscribe" for unsubscription
    "payload": ["BTC_USDT", "5", "100ms"]
}))
print(ws.recv())

Payload format:

Field Type Required Description
payload Array[String] Yes Subscription parameters, from left to right, cp, level, interval
» cp String Yes Currency pair
» level String Yes Order book level
» interval String Yes Notification update speed

Enumerated Values

Property Value
level 5
level 10
level 20
interval 100ms
interval 1000ms

Server Notification

{
  "time": 1606295412,
  "channel": "spot.order_book",
  "event": "update",
  "result": {
    "t": 1606295412123,
    "lastUpdateId": 48791820,
    "s": "BTC_USDT",
    "bids": [
      [
        "19079.55",
        "0.0195"
      ],
      [
        "19079.07",
        "0.7341"
      ],
      [
        "19076.23",
        "0.00011808"
      ],
      [
        "19073.9",
        "0.105"
      ],
      [
        "19068.83",
        "0.1009"
      ]
    ],
    "asks": [
      [
        "19080.24",
        "0.1638"
      ],
      [
        "19080.91",
        "0.1366"
      ],
      [
        "19080.92",
        "0.01"
      ],
      [
        "19081.29",
        "0.01"
      ],
      [
        "19083.8",
        "0.097"
      ]
    ]
  }
}

Result format:

Field Type Description
result Object Order book levels
» t Integer Order book update time in milliseconds
» lastUpdateId Integer Order book update ID of this snapshot
» s String Currency Pair
» bids Array[OrderBookArray] Top level bids in current snapshot, sort by price from high to low
»» OrderBookArray Array[String] [Price, Amount] pair
» asks Array[OrderBookArray] Top level asks in current snapshot, sort by price from low to high
»» OrderBookArray Array[String] [Price, Amount] pair

Orders Channel

spot.orders

Notify changes of orders created in subscribed currency pairs. Including order creation, fill, close and cancellation

Client Subscription

Code samples

import time
import json

# pip install websocket_client
from websocket import create_connection

ws = create_connection("wss://api.gateio.ws/ws/v4/")
request = {
    "time": int(time.time()),
    "channel": "spot.orders",
    "event": "subscribe",  # "unsubscribe" for unsubscription
    "payload": ["BTC_USDT"]
}
# refer to Authentication section for gen_sign implementation 
request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
ws.send(json.dumps(request))
print(ws.recv())

Payload format:

Field Type Required Description
payload Array[String] Yes List of currency pairs.

You can subscribe/unsubscribe multiple times. Currency pair subscribed earlier will not be overridden unless explicitly unsubscribed to.

If you want to subscribe to all orders updates in all currency pairs, you can include !all in currency pair list.

Server Notification

{
  "time": 1605175506,
  "channel": "spot.orders",
  "event": "update",
  "result": [
    {
      "id": "30784435",
      "user": 123456,
      "text": "t-abc",
      "create_time": "1605175506",
      "create_time_ms": "1605175506123",
      "update_time": "1605175506",
      "update_time_ms": "1605175506123",
      "event": "put",
      "currency_pair": "BTC_USDT",
      "type": "limit",
      "account": "spot",
      "side": "sell",
      "amount": "1",
      "price": "10001",
      "time_in_force": "gtc",
      "left": "1",
      "filled_total": "0",
      "fee": "0",
      "fee_currency": "USDT",
      "point_fee": "0",
      "gt_fee": "0",
      "gt_discount": true,
      "rebated_fee": "0",
      "rebated_fee_currency": "USDT"
    }
  ]
}

Updated order list. Note it is possible that multiple currency pairs' orders will be updated in one notification.

Result format:

Field Type Description
result Array[Object] Updated order list
» id String Order ID
» user Integer User ID
» text String User defined information
» create_time String Order creation time
» create_time_ms String Order creation time in milliseconds
» update_time String Order last modification time
» update_time_ms String Order last modification time in milliseconds
» event String Order event
- put: order creation
- update: order fill update
- finish: order closed or cancelled
» currency_pair String Currency pair
» type String Order type. limit - limit order
» account String Account type. spot - spot account; margin - margin account
» side String Order side
» amount String Trade amount
» price String Order price
» time_in_force String Time in force

- gtc: GoodTillCancelled
- ioc: ImmediateOrCancelled, taker only
- poc: PendingOrCancelled, makes a post-only order that always enjoys a maker fee
» left String Amount left to fill
» filled_total String Total filled in quote currency
» fee String Fee deducted
» fee_currency String Fee currency unit
» point_fee String Point used to deduct fee
» gt_fee String GT used to deduct fee
» gt_discount Boolean Whether GT fee discount is used
» rebated_fee String Rebated fee
» rebated_fee_currency String Rebated fee currency unit

Enumerated Values

Property Value
type limit
account spot
account margin
side buy
side sell
time_in_force gtc
time_in_force ioc
time_in_force poc

User Trades Channel

spot.usertrades

Notify user's personal trades in specified currency pairs. Unlike spot.trades channel, this is a private channel and notify all trades related to user whatever the trade role(maker/taker) is.

Client Subscription

Code samples

import time
import json

# pip install websocket_client
from websocket import create_connection

ws = create_connection("wss://api.gateio.ws/ws/v4/")
request = {
    "time": int(time.time()),
    "channel": "spot.usertrades",
    "event": "subscribe",  # "unsubscribe" for unsubscription
    "payload": ["BTC_USDT"]
}
# refer to Authentication section for gen_sign implementation 
request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
ws.send(json.dumps(request))
print(ws.recv())

Payload format:

Field Type Required Description
payload Array[String] Yes List of currency pairs.

You can subscribe/unsubscribe multiple times. Currency pair subscribed earlier will not be overridden unless explicitly unsubscribed to.

If you want to subscribe to all user trades updates in all currency pairs, you can include !all in currency pair list.

Server Notification

{
  "time": 1605176741,
  "channel": "spot.usertrades",
  "event": "update",
  "result": [
    {
      "id": 5736713,
      "user_id": 1000001,
      "order_id": "30784428",
      "currency_pair": "BTC_USDT",
      "create_time": 1605176741,
      "create_time_ms": "1605176741123.456",
      "side": "sell",
      "amount": "1.00000000",
      "role": "taker",
      "price": "10000.00000000",
      "fee": "0.00200000000000",
      "point_fee": "0",
      "gt_fee": "0"
    }
  ]
}

Updated user trades list. Note it is possible that multiple currency pairs' trades will be updated in one notification.

Result format:

Field Type Description
result Array[UserTrade] Updated user trades list
» id Integer Trade ID
» user_id Integer User ID
» order_id String Related order ID
» currency_pair String currency pair
» create_time Integer Trading time in seconds
» create_time_ms String Trading time in milliseconds. Precision higher than ms will be appended as decimal points
» side String Order side
» amount String Trade Amount
» role String Trade Role (maker/taker)
» price String Trade price
» fee String Fee deducted
» fee_currency String Fee currency unit
» point_fee String Point used to deduct fee
» gt_fee String GT used to deduct fee

Enumerated Values

Property Value
side buy
side sell
role maker
role taker

Spot Balance Channel

spot.balances

Notify user spot balance updates

Note that open orders will not trigger balance update until being partially or fully filled.

Client Subscription

Code samples

import time
import json

# pip install websocket_client
from websocket import create_connection

ws = create_connection("wss://api.gateio.ws/ws/v4/")
request = {
    "time": int(time.time()),
    "channel": "spot.balances",
    "event": "subscribe",  # "unsubscribe" for unsubscription
}
# refer to Authentication section for gen_sign implementation 
request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
ws.send(json.dumps(request))
print(ws.recv())

No payload is required.

Server Notification

{
  "time": 1605248616,
  "channel": "spot.balances",
  "event": "update",
  "result": [
    {
      "timestamp": "1605248616",
      "timestamp_ms": "1605248616123",
      "user": "1000001",
      "currency": "USDT",
      "change": "100",
      "total": "1032951.325075926",
      "available": "1022943.325075926"
    }
  ]
}

Result format:

Field Type Description
result Array[SpotBalance] New balance update list
» timestamp String Unix timestamp in seconds
» timestamp_ms String Unix timestamp in milliseconds
» user String User id
» currency String Changed currency
» change String Changed amount.
» total String Total spot balance
» available String Balance available to use

Margin Balance Channel

spot.margin_balances

Notify user margin balance updates. Any margin funding, borrowing will generate a new notification.

Client Subscription

Code samples

import time
import json

# pip install websocket_client
from websocket import create_connection

ws = create_connection("wss://api.gateio.ws/ws/v4/")
request = {
    "time": int(time.time()),
    "channel": "spot.margin_balances",
    "event": "subscribe",  # "unsubscribe" for unsubscription
}
# refer to Authentication section for gen_sign implementation 
request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
ws.send(json.dumps(request))
print(ws.recv())

No payload is required.

Server Notification

{
  "time": 1605248616,
  "channel": "spot.margin_balances",
  "event": "update",
  "result": [
    {
      "timestamp": "1605248812",
      "timestamp_ms": "1605248812123",
      "user": "1000001",
      "currency_pair": "BTC_USDT",
      "currency": "BTC",
      "change": "-0.002",
      "available": "999.999836",
      "freeze": "1",
      "borrowed": "0",
      "interest": "0"
    }
  ]
}

Result format:

Field Type Description
result Array[MarginBalance] New margin balance update list
» timestamp String Unix timestamp in seconds
» timestamp_ms String Unix timestamp in milliseconds
» user String User id
» currency_pair String Currency pair
» currency String Changed currency
» change String Changed amount
» available String Amount available to use
» freeze String Amount locked, e.g. used in funding book
» borrowed String Amount borrowed
» interest String Total unpaid interest generated from borrowing

Funding Balance Channel

spot.funding_balances

Notify user funding balance updates. Including new lending loan being created, cancelled, or borrowed by someone else.

Client Subscription

Code samples

import time
import json

# pip install websocket_client
from websocket import create_connection

ws = create_connection("wss://api.gateio.ws/ws/v4/")
request = {
    "time": int(time.time()),
    "channel": "spot.funding_balances",
    "event": "subscribe",  # "unsubscribe" for unsubscription
}
# refer to Authentication section for gen_sign implementation 
request['auth'] = gen_sign(request['channel'], request['event'], request['time'])
ws.send(json.dumps(request))
print(ws.recv())

No payload is required.

Server Notification

{
  "time": 1605248616,
  "channel": "spot.funding_balances",
  "event": "update",
  "result": [
    {
      "timestamp": "1605248616",
      "timestamp_ms": "1605248616123",
      "user": "1000001",
      "currency": "USDT",
      "change": "100",
      "freeze": "100",
      "lent": "0"
    }
  ]
}

Result format:

Field Type Description
result Array[FundingBalance] New funding balance update list
» timestamp String Unix timestamp in seconds
» timestamp_ms String Unix timestamp in milliseconds
» user String User id
» currency String Changed currency
» change String Changed amount
» freeze String Amount locked, e.g. used in funding book
» lent String Amount lent