Skip to main content
QFEX provides 2 endpoints for websocket: MDS is public and does not require authentication. Trade requires an API key and a connection must authenticate within 1 minute of connecting. If you want the Trade WebSocket session to operate on a subaccount, include account_id in the auth payload. When omitted, the connection uses the primary account.

Getting Started

To access private data or place orders, you must connect to trade.qfex.com and authenticate. The following examples show how to connect, authenticate using HMAC-SHA256, and maintain the connection.
# pip install websocket-client
import hashlib
import hmac
import json
import secrets
import time
import websocket

PUB_KEY = "qfex_pub_xxxxx"
SECRET_KEY = "qfex_secret_yyyyyy"

def build_auth_message():
    nonce = secrets.token_hex(16)
    unix_ts = int(time.time())
    payload = f"{nonce}:{unix_ts}".encode()
    signature = hmac.new(SECRET_KEY.encode(), payload, hashlib.sha256).hexdigest()
    return {
        "type": "auth",
        "params": {
            "hmac": {
                "public_key": PUB_KEY,
                "nonce": nonce,
                "unix_ts": unix_ts,
                "signature": signature,
            }
        },
    }

def on_open(ws):
    print("Connected")
    ws.send(json.dumps(build_auth_message()))

def on_message(ws, message):
    print("Received:", message)

ws = websocket.WebSocketApp(
    "wss://trade.qfex.com?api_key=" + PUB_KEY,
    on_open=on_open,
    on_message=on_message
)

ws.run_forever()
// npm i ws
import crypto from "crypto";
import WebSocket from "ws";

const pubKey = "qfex_pub_xxxxx";
const secretKey = "qfex_secret_yyyyyy";

function buildAuthMessage() {
  const nonce = crypto.randomBytes(16).toString("hex");
  const unixTs = Math.floor(Date.now() / 1000);
  const payload = `${nonce}:${unixTs}`;
  const signature = crypto
    .createHmac("sha256", secretKey)
    .update(payload)
    .digest("hex");

  return {
    type: "auth",
    params: {
      hmac: {
        public_key: pubKey,
        nonce,
        unix_ts: unixTs,
        signature,
      },
    },
  };
}

const ws = new WebSocket(`wss://trade.qfex.com?api_key=${pubKey}`);

ws.on("open", () => {
  console.log("Connected");
  ws.send(JSON.stringify(buildAuthMessage()));
});

ws.on("message", (msg) => {
  console.log("Received:", msg.toString());
});
// go get github.com/gorilla/websocket
package main

import (
  "crypto/hmac"
  "crypto/rand"
  "crypto/sha256"
  "encoding/hex"
  "fmt"
  "log"
  "time"
  "github.com/gorilla/websocket"
)

func main() {
  pubKey := "qfex_pub_xxxxx"
  secretKey := []byte("qfex_secret_yyyyyy")

  c, _, err := websocket.DefaultDialer.Dial("wss://trade.qfex.com?api_key="+pubKey, nil)
  if err != nil {
    log.Fatal("dial:", err)
  }
  defer c.Close()

  // Build Auth Message
  nonceBytes := make([]byte, 16)
  rand.Read(nonceBytes)
  nonce := hex.EncodeToString(nonceBytes)
  unixTs := time.Now().Unix()
  message := fmt.Sprintf("%s:%d", nonce, unixTs)

  h := hmac.New(sha256.New, secretKey)
  h.Write([]byte(message))
  signature := hex.EncodeToString(h.Sum(nil))

  auth := map[string]any{
    "type": "auth",
    "params": map[string]any{
      "hmac": map[string]any{
        "public_key": pubKey,
        "nonce":      nonce,
        "unix_ts":    unixTs,
        "signature":  signature,
      },
    },
  }

  c.WriteJSON(auth)

  for {
    _, message, err := c.ReadMessage()
    if err != nil {
      log.Println("read:", err)
      return
    }
    fmt.Printf("recv: %s\n", message)
  }
}

Authentication

Authentication is required for the trade.qfex.com endpoint.
  1. Connect: Include your public API key as a query parameter:
    wss://trade.qfex.com?api_key=YOUR_PUBLIC_KEY
    
  2. Authenticate: Send an authentication message signed with your secret key within 1 minute. You can use either an HMAC-SHA256 signature (recommended) or a valid JWT token.
For full details on the authentication payload and parameters, see the Authenticate documentation.