Real-time market data API developer docs
Clear references, runnable examples, and SDKs for the languages your team already uses.
Quickstart
Three steps from sign-up to your first live push. The free tier needs no credit card.
- Create an API keyGenerate a key in theconsole · API keyssection — use a separate key for dev, staging, and production.
- Make your first REST callSend
X-API-Keyin the request header and call the crypto quote endpoint to verify auth. - Subscribe over WebSocketConnect to the stream channel and send subscribe; the handshake counts once against quota, and later tick pushes are not billed again.
curl "https://api.tiqex.io/api/v1/market/crypto/quote?symbols=BTCUSDT" \\
-H "X-API-Key: $TIQEX_KEY"{
"succ": true,
"data": { ... } // Field details are documented per endpoint; on failure succ=false with msg and code
}Base URL and response envelope
| Purpose | Address |
|---|---|
| REST | https://api.tiqex.io/api/v1 |
| WebSocket | wss://api.tiqex.io/api/v1/market/stream |
| Field | Type | Description |
|---|---|---|
succ | boolean | Whether the request succeeded. Can be false even on HTTP 2xx, so check both |
data | object | array | Business data; see each endpoint for its fields |
msg | string | Human-readable error message on failure (optional) |
code | string | Machine-readable error code (optional), seeerror codes |
X-Request-Id | Response header | Request trace ID. Not in the JSON body; include it when debugging or filing a ticket |
Authentication
Every REST and WebSocket request needs an API key. Send it asX-API-Key: YOUR_API_KEYheader, or useAuthorization: Bearer YOUR_API_KEY.
- Keep keys on the server or in a secret manager — never in front-end code or a Git repository.
- Create separate keys per environment and rotate or revoke them from the console at any time.
- A missing or invalid key returns 401; a market that is not enabled or insufficient scope returns 403.
Read the full guide:Authentication →
REST endpoints
One JSON envelope, with filtering by symbol or interval, plus pagination and rate-limit headers. Endpoints are grouped by market scope.
Crypto
crypto scope- GET
/api/v1/market/crypto/quoteLatest quote snapshot; param symbols (e.g. BTCUSDT) - GET
/api/v1/market/crypto/klineHistorical candles: symbol, interval (1s–1M, default 1h), limit 1–1000
US stocks
stocks scope- GET
/api/v1/market/equity/quoteUS equity quotes - GET
/api/v1/market/equity/klineUS equity candles
Unified multi-market quotes
Scoped by each symbol’s market- GET
/api/v1/market/quoteFX / commodities / A-shares / Hong Kong / futures / index quotes; codes comma-separated, up to 50
A-shares · Hong Kong
cn / hk scope- GET
/api/v1/market/cn/klineA-share candles
FX · indices · futures
forex / indices / futures scope- GET
/api/v1/market/forex/klineFX candles - GET
/api/v1/market/continuous-futures/klineContinuous futures candles (path /tv-futures, futures scope)
Commodities
metals / energy / agri / commodities scope- GET
/api/v1/market/metals/klineMetals candles - GET
/api/v1/market/energy/klineEnergy candles - GET
/api/v1/market/agri/klineAgriculture candles - GET
/api/v1/market/commodities/klineCommodities candles
Live streaming
Scoped by the market you subscribe to- WS
wss://api.tiqex.io/api/v1/market/streamLive market stream: send subscribe, then receive tick pushes
No matching endpoints
Try another keyword, or see themarket coverage table.
WebSocket live streaming
Connect towss://api.tiqex.io/api/v1/market/streamthen make subscribe the first frame. One connection can batch-subscribe multiple symbols, limited by your plan.
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | First frame must besubscribe |
market | string | Yes | crypto | stocks | cn | futures | forex | commodities | metals | energy | agri |
symbols | string[] | Yes | List of symbols to subscribe to |
Send a subscription
{ "action": "subscribe", "market": "crypto", "symbols": ["BTCUSDT", "ETHUSDT"] }Server messagesSample value
Messages are flat: a successful subscribe replies with type=subscribed (market + symbols); quotes arrive as type=tick with the fields listed above. Verified against the live implementation.
{ "type": "subscribed", "market": "crypto", "symbols": ["BTCUSDT", "ETHUSDT"] }{
"type": "tick",
"tick": {
"symbol": "BTCUSDT",
"last": 0.00, "bid": 0.00, "ask": 0.00, "volume": 0,
"change": 0.00, "changePercent": 0.00, "high": 0.00, "low": 0.00,
"at": "2026-10-12T06:00:00.000Z"
}
}{ "type": "error", "code": "WS_CONN_LIMIT", "msg": "WebSocket connection limit reached for your plan" }Client example
const ws = new WebSocket("wss://api.tiqex.io/api/v1/market/stream");
ws.onopen = () => {
ws.send(JSON.stringify({ action: "subscribe", market: "crypto", symbols: ["BTCUSDT"] }));
};
ws.onmessage = (ev) => {
const msg = JSON.parse(ev.data);
if (msg.type === "tick") console.log(msg.tick.symbol, msg.tick.last);
if (msg.type === "error") console.warn(msg.code, msg.msg);
};
// On disconnect, reconnect with 1s, 2s, 4s... backoff and resend every subscribeRate limits and quotas
REST quote / kline calls and stream handshakes count against your daily (or monthly) quota and RPM; tick pushes after the handshake are not billed again. Figures are the defaults from the online docs — the console plan is authoritative.
| Plan | REST quota | Default RPM | WS connections / symbols | Markets and latency |
|---|---|---|---|---|
| Free $0 | 300 / day | 30 | 1 / 10 | Crypto realtime only |
| Growth $99/mo | 500,000 / month | 120 | 3 / 25 | Crypto / US stocks / indices / metals / FX realtime |
| Pro $299/mo | 5,000,000 / month | 600 | 10 / 50 | All markets real-time (including futures, energy, agriculture) |
| Enterprise Custom | Unlimited or contracted | 3000 | 50 / 200 | Level 2 (FX real-time), private deployment |
On 429, readRetry-After, retry with exponential backoff plus jitter, and cache non-real-time data locally. Use theQuota calculatorto estimate your usage.
Error codes overview
Most 4xx errors are client-side, 429 means quota or rate limiting, and 5xx comes from upstream or the server. The most common ones are below; the full list is on the error codes page.
| HTTP | code | Meaning | Suggested action |
|---|---|---|---|
| 401 | UNAUTHORIZED | Missing or invalid key | Check the request header and key status |
| 403 | MARKET_NOT_ENABLED | Market not enabled on your plan | Upgrade your plan or switch markets |
| 403 | API_KEY_SCOPE_DENIED | Key scope is insufficient | Adjust the key scope in the console |
| 429 | RATE_LIMIT_EXCEEDED | User-level RPM exceeded | Back off using Retry-After |
| 429 | DAILY_LIMIT_EXCEEDED | Daily request quota exhausted | Resets next day, or upgrade your plan |
| 502 | UPSTREAM_UNAVAILABLE | Upstream market data source temporarily unavailable | Retry with exponential backoff; keep X-Request-Id |
SDKs & language examples
The REST API is plain HTTP + JSON, so any language can call it directly. The examples below match the code window on the home page.
// Node 18+ / same-origin BFF in the browser; keep the key server-side only
const res = await fetch(
"https://api.tiqex.io/api/v1/market/crypto/quote?symbols=BTCUSDT",
{ headers: { "X-API-Key": process.env.TIQEX_KEY } }
);
const json = await res.json();
if (!json.succ) throw new Error(json.code + " " + json.msg);
console.log(json.data);import os, requests
resp = requests.get(
"https://api.tiqex.io/api/v1/market/crypto/quote",
params={"symbols": "BTCUSDT"},
headers={"X-API-Key": os.environ["TIQEX_KEY"]},
timeout=10,
)
body = resp.json()
if not body["succ"]:
raise RuntimeError(body.get("code"), resp.headers.get("X-Request-Id"))
print(body["data"])<?php
$ch = curl_init("https://api.tiqex.io/api/v1/market/crypto/quote?symbols=BTCUSDT");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("TIQEX_KEY")],
CURLOPT_TIMEOUT => 10,
]);
$body = json_decode(curl_exec($ch), true);
var_dump($body["data"]);// JDK 11+ ships HttpClient
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.tiqex.io/api/v1/market/crypto/quote?symbols=BTCUSDT"))
.header("X-API-Key", System.getenv("TIQEX_KEY"))
.build();
HttpResponse<String> res = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(res.body());req, _ := http.NewRequest("GET",
"https://api.tiqex.io/api/v1/market/crypto/quote?symbols=BTCUSDT", nil)
req.Header.Set("X-API-Key", os.Getenv("TIQEX_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer res.Body.Close()
io.Copy(os.Stdout, res.Body)Per-language install, WebSocket, and wrapper guidance → · GitHub · TIQEXAPI
FAQ
How should REST and WebSocket work together?
Use REST for snapshots and historical candle backfills, and WebSocket for live ticks. Both use the same API key; the stream handshake is billed once and pushes are not counted again.
How do I format symbols?
Crypto usually uses BTCUSDT; US equities look like AAPL; multi-market quote accepts product short codes or exchange-native symbols. See each endpoint’s parameter table and the console symbol list.
What can the free tier do?
It is meant for learning and integration testing. Upgrade to Growth or Pro when production needs more markets, real-time data, or a higher quota.
How should I interpret latency and coverage?
Latency, field granularity, and history depth vary by market and plan — the console entitlements and endpoint docs are authoritative, and values are not guaranteed to match any single exchange order book field by field.
