Taiwan Market API

5 endpoints

Last updated 2026-10
Base URL
https://api.blave.org
Auth
api-key + secret-key headers on every request
Access
API plan or data fee
Rate Limit
500 requests / 5 min per key and per IP

Conventions

Whole-market daily series (no stock_id). start / end are optional YYYY-MM-DD; omit for full history. Do not sum per-stock endpoints as a substitute — coverage and units differ.

TAIEX Daily OHLC

GET/studio/market/twmarket/index/<index_id>
Data From
1999-01-05
Update
Daily; server cache 5 min
Source
TWSE MI_5MINS_HIST

Parameters

index_idstringpathRequired
Only TAIEX is supported
Allowed TAIEX (case-insensitive)
startstringquery
First date
Default 1999-01-05Allowed YYYY-MM-DD
endstringquery
Last date
Default todayAllowed YYYY-MM-DD

Example

Python
body = requests.get(f"{BASE_URL}/studio/market/twmarket/index/TAIEX", headers=headers,                    params={"start": "2024-01-01", "end": "2024-12-31"}, timeout=60).json()# {"index_id": "TAIEX", "data": [{"date": "2024-01-02", "open": 17939.79, "high": 17956.74, "low": 17784.97, "close": 17853.76}, ...]}

Response

{"index_id": "TAIEX", "data": [{"date", "open", "high", "low", "close"}]}; prices in index points. No volume — use /twmarket/turnover.

Errors

StatusBodyWhen
400{"error": "Unsupported index"}Not TAIEX
404error messageNo data
503{"error": "Market data is not ready on this server. Please retry later."} / upstream rate limitStore not ready / upstream down

Market Turnover

GET/studio/market/twmarket/turnover
Data From
1990-01-04
Update
Daily; server cache 5 min
Source
TWSE FMTQIK

Parameters

startstringquery
First date
Default 1990-01-04Allowed YYYY-MM-DD
endstringquery
Last date
Default todayAllowed YYYY-MM-DD

Example

Python
data = requests.get(f"{BASE_URL}/studio/market/twmarket/turnover", headers=headers,                    params={"start": "2024-01-01"}, timeout=60).json()["data"]# [{"date": "2024-01-02", "volume": 6411778806.0, "value": 301290668897.0, "trades": 2267660.0}, ...]

Response

{"data": [...]}.

FieldUnitDescription
date—Trading day
volumeshares成交股數
valueTWD成交金額
tradescount成交筆數

Errors

404 no data; 503 store not ready or upstream rate limit.

Market Institutional Net Buy/Sell

GET/studio/market/twmarket/institutional
Data From
2004-04-07
Update
Daily; server cache 5 min
Source
FinMind; TWSE BFI82U before FinMind publishes the day

Parameters

startstringquery
First date
Default 2004-04-07Allowed YYYY-MM-DD
endstringquery
Last date
Default todayAllowed YYYY-MM-DD

Example

Python
data = requests.get(f"{BASE_URL}/studio/market/twmarket/institutional", headers=headers,                    params={"start": "2024-01-01"}, timeout=60).json()["data"]# [{"date": "2024-01-02", "foreign": 1047078183.0, "investment_trust": 189637635.0,#   "dealer": -4448119903.0, "total": -3211404085.0}, ...]

Response

{"data": [{"date", "foreign", "investment_trust", "dealer", "total"}]}; all values are net (buy − sell) in TWD.

Errors

404 no data; 503 upstream rate limit.

Notes

  • Whole-market layer. foreign is 外資及陸資 excluding foreign dealers' own-account trading (外資自營商); dealer is 自營商 (自行買賣 + 避險), which TWSE already counts 外資自營商 inside. The per-stock endpoint (GET /studio/market/twstock/institutional/<stock_id>) is a different layer: it returns the raw per-category columns and buckets nothing. Don't mix the two.
  • foreign + investment_trust + dealer equals total, the exchange's published 三大法人合計, on every day (verified against FinMind for all 5,537 days 2004-04-07 → 2026-10-06). 外資自營商 is not a separate column: it sits on warrants/ETNs, which Blave does not serve, and has been 0 every day after 2024-08-16.

Market Margin Balance

GET/studio/market/twmarket/margin
Data From
2001-01-03
Update
Daily; server cache 5 min
Source
FinMind

Parameters

startstringquery
First date
Default 2001-01-03Allowed YYYY-MM-DD
endstringquery
Last date
Default todayAllowed YYYY-MM-DD

Example

Python
data = requests.get(f"{BASE_URL}/studio/market/twmarket/margin", headers=headers,                    params={"start": "2024-01-01"}, timeout=60).json()["data"]# [{"date": "2024-01-02", "margin_balance": 8012561, "margin_balance_prev": 7999081,#   "margin_balance_value": 248424271000, "short_balance": 369678, "short_balance_prev": 359738}, ...]

Response

{"data": [...]}.

FieldUnitDescription
date—Trading day
margin_balance / margin_balance_prevlots (張)融資餘額 today / previous day
margin_balance_valueTWD融資餘額金額
short_balance / short_balance_prevlots (張)融券餘額 today / previous day

Errors

404 no data; 503 upstream rate limit.

TAIEX Daily Dividend Points

GET/studio/market/twmarket/dividend_points
Data From
2003-01-02 (realized); forecasts up to today + 120 days
Update
Realized leg each trading day ~17:00 Taipei; server cache 5 min (forecast inputs 1 h)
Source
FinMind total-return vs price index (realized); announced dividends + last-year template (forecast)

Parameters

startstringquery
First date
Default 2003-01-02Allowed strict YYYY-MM-DD
endstringquery
Last date; silently clamped to today + 120 days
Default today + 120 daysAllowed strict YYYY-MM-DD

Example

Python
import pandas as pdpayload = requests.get(f"{BASE_URL}/studio/market/twmarket/dividend_points", headers=headers,                       params={"start": "2026-08-01"}, timeout=60).json()# {"data": [{"date": "2026-08-03", "points": 2.853, "estimated": false}, ...,#           {"date": "2026-08-28", "points": 3.846, "estimated": true}, ...],#  "meta": {"estimated_coverage": 0.9999, "degraded": false}}df = pd.DataFrame(payload["data"])future_div = df[df["estimated"]].set_index("date")["points"]# fair basis at t for settlement T: futures_price - (spot_index - future_div.loc[t_plus_1:T].sum())

Response

{"data": [{"date", "points", "estimated"}], "meta": {"estimated_coverage", "degraded"}}.

FieldTypeDescription
data[].datestringDay
data[].pointsfloatIndex points removed by ex-dividend events that day
data[].estimatedboolfalse = realized (from the TR/price index spread; non-ex days ≈ 0); true = forecast (future weekdays, zero-filled where no event)
meta.estimated_coveragefloat | nullFraction of TAIEX weight whose inputs were readable for the forecast; null when no estimated rows
meta.degradedbooltrue = forecast materially under-covered — treat as a lower bound

Errors

StatusBodyWhen
400{"error": "Invalid start date, expected YYYY-MM-DD"} (or end)Malformed date
404{"error": "No TAIEX index data available from FinMind"}Cold store and no upstream data
503error messageForecast coverage below 90%, store not ready, or upstream rate limit

Notes

  • Before ~17:00 Taipei the latest realized row is the previous trading day.
  • Forecasts more than ~2 weeks out lean on the last-year template.
  • Forecast rows are always returned from tomorrow through end, even when start is later than tomorrow — filter client-side.