Skip to content

REST API

:22222/api/* exposes 41 HTTP endpoints, all JSON.

Call format

# without auth (local dev)
curl http://localhost:22222/api/accounts

# with Bearer Token
curl -H "Authorization: Bearer fc_xxxx..." http://localhost:22222/api/accounts

# most write endpoints take POST + JSON body
curl -X POST http://localhost:22222/api/quote \
  -H 'Content-Type: application/json' \
  -d '{"security_list":[{"market":1,"code":"00700"}],"sub_type_list":[1]}'

Routing table

System

Method Path Scope Purpose
GET /api/global-state qot:read Global state (server time, market status)
GET /api/user-info qot:read Current user info
GET /api/delay-statistics qot:read Protocol latency stats

Quote

Method Path Scope
POST /api/subscribe qot:read
GET /api/sub-info qot:read
POST /api/quote qot:read
POST /api/kline qot:read
POST /api/orderbook qot:read
POST /api/broker qot:read
POST /api/ticker qot:read
POST /api/rt qot:read
POST /api/snapshot qot:read
POST /api/static-info qot:read
POST /api/plate-set qot:read
POST /api/plate-security qot:read
POST /api/reference qot:read
POST /api/owner-plate qot:read
POST /api/option-chain qot:read
POST /api/warrant qot:read
POST /api/capital-flow qot:read
POST /api/capital-distribution qot:read
POST /api/user-security qot:read
POST /api/stock-filter qot:read
POST /api/ipo-list qot:read
POST /api/future-info qot:read
POST /api/market-state qot:read
POST /api/history-kline qot:read

Trade

Method Path Scope
GET /api/accounts acc:read
POST /api/sub-acc-push acc:read
POST /api/funds acc:read
POST /api/positions acc:read
POST /api/orders acc:read
POST /api/order-fills acc:read
POST /api/max-trd-qtys acc:read
POST /api/history-orders acc:read
POST /api/history-order-fills acc:read
POST /api/margin-ratio acc:read
POST /api/order-fee acc:read
POST /api/unlock-trade trade:real
POST /api/order trade:real
POST /api/modify-order trade:real

Ops

Method Path Scope Purpose
GET /metrics none Prometheus scrape
GET /health none Liveness probe
GET /ws qot:read (handshake) WebSocket push upgrade

HTTP status codes

HTTP Meaning
200 Success
400 Malformed JSON body / missing required field
401 Bearer missing / token invalid / expired
403 Scope insufficient
404 Path not in the routing table (fail-closed — no info leak)
429 Limit tripped (rate / daily / per-order / market whitelist / time window / ...)
500 Server bug / gateway disconnect

Error body is uniform:

{"error": "limit check failed: rate limit exceeded: 3 orders in the last 60s (cap 3)"}

Request body shape

The routing layer receives Json<Value> and hands it off to adapter::proto_request, which converts JSON → protobuf and calls RequestRouter. So the body shape matches the Futu protobuf definitions verbatim — read the .proto files under proto/ for truth.

Place-order body (C2S section of proto/Trd_PlaceOrder.proto):

{
  "packet_id": { "conn_id": 12345, "serial_no": 1 },
  "header":   { "trd_env": 1, "acc_id": 987654, "trd_market": 1 },
  "trd_side": 1,
  "order_type": 1,
  "code": "00700",
  "qty": 100,
  "price": 300.0,
  "sec_market": 1
}

Main enum values (identical to Futu's Trd_Common.proto, protocol-compatible):

  • trd_env: 1 = simulate, 2 = real
  • trd_side: 1 = BUY, 2 = SELL, 3 = SELL_SHORT, 4 = BUY_BACK
  • trd_market: 1 = HK, 2 = US, 3 = CN, 4 = HKCC, 5 = FUTURES, 6 = SG, 7 = JP
  • order_type: 1 = NORMAL (limit), 2 = MARKET, 5 = ABSOLUTE_LIMIT, 6 = AUCTION, 7 = AUCTION_LIMIT, 8 = SPECIAL_LIMIT

Reference implementations

Working call examples live in: