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.

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.