Skip to content

REST API

Start with a read request, then add accounts, trading, or streaming as needed. The REST API reference owns endpoint paths, scopes, fields, and examples; this guide explains the workflow and how to interpret results.

Call format

Confirm the connection mode

Scenario Connection
First local read check Follow Quick Start: bind 127.0.0.1 and explicitly enable --rest-port 22222; send no Bearer token over no-key HTTP
Client using an API Key Native daemon HTTPS with rest_keys_file, a certificate, and a private key; verify the server certificate and send a Bearer token

API Key configuration requires TLS even on loopback. Follow the API Key tutorial for certificates and keys. REST and /ws on the same listener share the transport mode: HTTPS pairs with WSS.

Make a quote read request

This uses the same symbol shorthand as the reference entry for /api/quote, against the local no-key setup from Quick Start:

curl --fail-with-body -X POST http://127.0.0.1:22222/api/quote \
  -H 'Content-Type: application/json' \
  -d '{"symbol":"HK.00700"}'

POST is also used for reads; it does not imply a trade write. Quote results depend on login, market-data permissions, and any subscription prerequisites. Follow the business diagnostic if the request is rejected.

For an environment already configured with native HTTPS:

curl --fail-with-body --cacert /path/to/ca.pem \
  -H "Authorization: Bearer $FUTU_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"symbol":"HK.00700"}' \
  https://127.0.0.1:22222/api/quote

Use your CA file, a hostname matching the certificate, and an API Key with qot:read. Keep certificate verification enabled.

Request body shape

Copy the request shape from the target reference entry. Not every endpoint requires a c2s wrapper, and subscription fields do not belong in every quote request. Field names, accepted aliases, and enum representations follow each endpoint's contract.

Quote market and trading trd_market are different enums: US equities use 11 and 2, respectively. Do not copy numeric values across interfaces. Where supported, a symbol such as HK.00700 makes the market explicit.

HTTP status codes

Check both the HTTP status and the business response's ret_type, ret_msg, and err_code. HTTP 200 does not prove business success, and an empty s2c does not by itself identify a field-name error.

Result Check first
Connection or TLS failure Process, port, URL scheme, certificate hostname, and CA
HTTP 400 JSON shape, required fields, and accepted fields
HTTP 401 / 403 Key validity, scope, account allowlist, and transport requirements
HTTP 404 Path and method against the reference
HTTP 429 Rate limits and quotas; avoid immediate retry loops
HTTP 5xx Gateway and backend state using probes and logs
HTTP 200 with nonzero ret_type Business diagnostic, permissions, inputs, and prerequisites

Error shapes depend on the endpoint and failure stage: they may contain {"error":"..."} or business error fields. See Common pitfalls for more guidance.

Routing table

The REST API reference maintains the full route catalog. The notes below cover behaviors that affect client workflows.

System

Read global state with /api/global-state. Process and readiness probes serve different purposes, described below; a business query is not a liveness check.

Quote

/api/sub-info is a current-connection view, not the gateway's complete subscription inventory. An empty list does not prove global subscription loss. For cross-client inspection, use /api/query-subscription with is_req_all_conn: true according to its request contract.

Trade

Remote HTTPS unlock workflow:

  1. Configure native daemon HTTPS using the authorization tutorial and verify certificates on the client. A reverse proxy must also use HTTPS upstream to the daemon.
  2. Prepare an API Key with trade:unlock and check the account allowlist. Other trading scopes do not replace this permission.
  3. When unlock is explicitly needed, prepare the request using POST /api/unlock-trade. Both the trade password and its MD5 are credentials; keep them out of logs and frontend code.
  4. Inspect the response to determine whether unlock succeeded. Unlock does not grant order permissions: trade writes still require their scopes, trading switches, and explicit authorization.

Forwarded and X-Forwarded-Proto headers cannot substitute for real TLS. Non-loopback plaintext requests reaching the unlock route are rejected; plaintext sent to a TLS listener fails during the handshake.

Use /api/cancel-order for single-order cancellation; /api/modify-order retains the modify_order_op=2 compatibility shape. A modify/cancel response with ret_type=0 means the backend accepted the request. Determine final order state from trade pushes or /api/orders with refresh_cache=true. Determine sellable quantity from pushes or an explicit refreshed /api/positions query.

After a successful single-order cancel, the gateway performs one bounded order refresh before its ACK, without implicitly refreshing positions. Refresh failure does not turn an accepted cancellation into a failure, so do not resend a cancellation on that basis.

Ops

  • /livez checks process liveness; /health checks backend transport; /readyz checks backend connectivity and gateway dispatch readiness. They require no Bearer token but share the listener's TLS configuration.
  • In scope mode, /metrics requires metrics:read or admin. It is public in legacy no-key mode; FUTU_METRICS_PUBLIC=1 explicitly makes it public as well.
  • In scope mode, /ws handshakes require qot:read, authenticated with a Bearer header or ?token=. Legacy no-key mode remains public. See the WebSocket guide for browser use.
  • Admin endpoints require admin. See Operations for deployment, monitoring, and authentication recovery.

Reference implementations

REST API reference · Browser frontend recipe · Integration options