IDX Market Data
Indonesia Stock Exchange quotes, order book, brokers, and news.
Base URL
https://use.api.co.id
All paths live under /idx, for example GET /idx/v2/market/status. Send a stock symbol or broker code plus the filters listed on each endpoint, with the x-api-co-id header. Data is wrapped in the standard is_success response.
Endpoint groups
| Group | Contents |
|---|---|
| Charts | Price data for one stock: a live snapshot, intraday bars, and daily / weekly / monthly history. |
| Live Trades | Market-wide and per-symbol running-trade tape, order book, order queue, trade book, 1-minute buy/sell flow. |
| Flow | Foreign vs domestic net, per-broker bandarmology, broker stalker. |
| Market | Market-wide: movers, trending, top flows, top-broker ranking, corp-action calendar, status, holidays. |
| News | Market-wide news/reports feed, and one-ticker news, reports, or insider-activity feed. |
| Insider | Major-holder (insider) transactions and shareholder composition. |
| Corp. Actions | Dividends / splits / bonus / rights / RUPS, all types in one endpoint. |
| Fundamentals | Key stats + line items, and full financial statements. |
| Instruments | Tradable universe, instrument snapshot, company profile, broker directory, index list. |
Charts
Quote
A live price snapshot for one stock: last traded price and change, day open / high / low, VWAP, volume, value, trade count, best bid and ask with their sizes, the day's price limits (ARA / ARB), market status and any special notations.
Outside trading hours, or briefly if the live feed lags, the intraday figures (open,
high, low, VWAP, value, trade count, ARA, ARB) come back empty — message tells you
when the snapshot is partial. Foreign buy/sell is at /v2/foreign-flow/{symbol};
market capitalisation is at /v2/instruments/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the snapshot in data, and meta. |
data.messageRequired | string | status of the snapshot; notes when intraday figures could not be filled |
data.dataRequired | object | A live price snapshot for one stock. The intraday figures (open, high, low, vwap,
value, frequency, ara, arb) can be empty outside trading hours or if the feed briefly
lags — the wrapper's message says when the snapshot is partial. |
data.data.symbolRequired | string | |
data.data.nameRequired | string | |
data.data.dateRequired | string | |
data.data.lastRequired | number | last traded price |
data.data.changeOptional | string | price change from the previous close |
data.data.change_pctOptional | string | price change as a percent |
data.data.prev_closeOptional | string | previous trading day's close |
data.data.openRequired | string | |
data.data.highRequired | string | |
data.data.lowRequired | string | |
data.data.vwapOptional | string | volume-weighted average price for the day |
data.data.volumeRequired | string | |
data.data.valueOptional | string | traded value for the day, in rupiah |
data.data.frequencyOptional | string | number of trades today |
data.data.araOptional | string | highest price the stock may trade at today (auto-reject upper) |
data.data.arbOptional | string | lowest price the stock may trade at today (auto-reject lower) |
data.data.bidOptional | string | best bid price |
data.data.bid_volumeOptional | string | lots offered at the best bid |
data.data.askOptional | string | best ask price |
data.data.ask_volumeOptional | string | lots offered at the best ask |
data.data.market_statusOptional | string | whether the market is open, closed, in a break, etc. |
data.data.tradeableOptional | string | whether the stock can be traded right now |
data.data.notationOptional | object[] | IDX special notations on this stock, empty if none |
data.data.notation[].codeRequired | string | |
data.data.notation[].descriptionRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/chart/quote/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": { "notation": [] } }}Intraday
Intraday price bars for one stock, newest first by default (order=asc for oldest
first). Pick the bar size with timeframe; limit returns just the most recent bars.
Each bar carries OHLC, volume, traded value and lots. Prices are adjusted for stock
splits and bonus issues.
One request covers at most 90 days — for a longer span, call again with the window
moved further back. Recent years are covered in full; further back, intraday history
is partial and some periods are unavailable. Foreign buy/sell is not broken out at any
intraday resolution — the settled daily figure is at /v2/foreign-flow/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
timeframeOptional | string | bar size Values: 1m5m15m30m1h4h |
fromOptional | string | YYYY-MM-DD or ISO datetime (e.g. 2026-09-04T09:30:00+07:00), read as WIB. Default: start of today |
toOptional | string | YYYY-MM-DD or ISO datetime, read as WIB. Default: now |
limitOptional | string | just the most recent N bars; omit for every bar in the window |
orderOptional | string | row order — desc (newest first, default) or ascValues: descasc |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the bars in data (newest first by default,
order=asc to reverse), and meta with the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].timeRequired | string | |
data.data[].unix_timeOptional | string | bar time as a Unix timestamp (seconds) |
data.data[].openRequired | number | |
data.data[].highRequired | number | |
data.data[].lowRequired | number | |
data.data[].closeRequired | number | |
data.data[].volumeRequired | integer | |
data.data[].valueOptional | string | traded value for the bar, in rupiah |
data.data[].lotOptional | string | volume in lots (1 lot = 100 shares) |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/chart/intraday/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Daily
Daily, weekly or monthly price bars for one stock, newest first by default
(order=asc for oldest first). Prices are adjusted for stock splits and bonus issues.
Each bar carries OHLC, volume, value, trade count, foreign buy / sell / net for the day
plus the cumulative foreign flow, the dividend paid on the ex-date, shares outstanding
and market capitalisation. Weekly and monthly bars combine the days in the period
(prices to the period's open/high/low/close, the rest summed). History goes back
roughly 20 years — narrow the window with from / to.
The current day's bar is provisional: price and volume move through the session, and its foreign buy / sell / net and the cumulative foreign flow come back empty until they settle after the close.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
timeframeOptional | string | bar size Values: 1d1w1M |
fromOptional | string | YYYY-MM-DD. Default: 1y back (1d), 3y (1w), 10y (1M) |
toOptional | string | YYYY-MM-DD. Default: today (WIB) |
orderOptional | string | row order — desc (newest first, default) or ascValues: descasc |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the bars in data (newest first by default,
order=asc to reverse), and meta with the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].dateRequired | string | |
data.data[].unix_dateOptional | string | bar date as a Unix timestamp (seconds) |
data.data[].openRequired | number | |
data.data[].highRequired | number | |
data.data[].lowRequired | number | |
data.data[].closeRequired | number | |
data.data[].volumeRequired | integer | |
data.data[].valueOptional | string | traded value for the bar, in rupiah |
data.data[].frequencyOptional | string | number of trades in the bar |
data.data[].lotOptional | string | volume in lots (1 lot = 100 shares) |
data.data[].foreign_buyOptional | string | value bought by foreign investors |
data.data[].foreign_sellOptional | string | value sold by foreign investors |
data.data[].foreign_netRequired | string | foreign buy minus foreign sell for this bar |
data.data[].foreign_flowOptional | string | running total of foreign net flow up to and including this bar (not the per-bar figure — see foreign_net); the baseline is fixed far back so only changes between bars are meaningful; null on the current day until the session settles |
data.data[].shares_outstandingOptional | string | shares outstanding as of this bar |
data.data[].soxcloseOptional | string | market capitalisation at this bar's close |
data.data[].dividendRequired | string | cash dividend per share if this is an ex-date, otherwise 0 |
data.data[].freq_analyzerOptional | string | exchange-provided trade-activity indicator; exact formula not published and the scale is not comparable across years |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/chart/daily/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Live Trades
Running Trade
The whole market's running-trade tape (every matched print, not just one stock), newest first. Each row carries the trade's price, lot size, action (buy/sell), the buyer and seller codes and their investor type, the board it printed on, and the order/trade numbers.
For one or more specific stocks use /v2/running-trade/{symbols}; for the same tape
grouped by broker crossing use /v2/running-trade/{symbols}/group.
| Name | Type | Description |
|---|---|---|
actionOptional | string | show only buys or only sells |
min_lotOptional | string | drop prints smaller than this many lots |
atOptional | string | session date (YYYY-MM-DD); default today (WIB), falling back to the last session before the market opens |
limitOptional | integer | return only the N most recent prints (100 max) |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the trades in data, and meta with the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].idOptional | string | opaque id for this print |
data.data[].timeRequired | string | |
data.data[].actionOptional | string | the aggressor side (BUY lifts the offer, SELL hits the bid) |
data.data[].symbolRequired | string | |
data.data[].priceRequired | number | |
data.data[].change_pctOptional | string | this print's price change vs. the prior close, percent |
data.data[].lotRequired | number | 1 lot = 100 shares; fractional on a negotiated-board (NG) print smaller than one lot |
data.data[].buyerOptional | string | buying broker's code as reported, e.g. "AK [F]" (the bracket tag is a coarse investor marker — prefer buyer_type) |
data.data[].sellerOptional | string | selling broker's code, same form as buyer |
data.data[].trade_numberOptional | string | the exchange trade number for this print |
data.data[].buyer_typeOptional | string | Foreign | Local | Government |
data.data[].seller_typeOptional | string | Foreign | Local | Government |
data.data[].boardRequired | string | |
data.data[].buy_order_numberOptional | string | buy-side order reference |
data.data[].sell_order_numberOptional | string | sell-side order reference |
data.data[].group_order_numberOptional | string | order reference shared across the matched pair (usually equal to buy_order_number) |
data.data[].valueOptional | string | traded value for this print, in rupiah |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/running-trade" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Running Trade Symbols
Running-trade tape for one or more stocks (comma-separated, e.g. BBCA,BBRI,TLKM),
newest first — same row shape as /v2/running-trade, filtered to the given ticker(s).
For every stock at once use /v2/running-trade; for the same prints grouped by
broker crossing use /v2/running-trade/{symbols}/group.
| Name | Type | Description |
|---|---|---|
symbolsRequired | string | comma-separated ticker(s) Example: BBCA |
| Name | Type | Description |
|---|---|---|
actionOptional | string | show only buys or only sells |
min_lotOptional | string | drop prints smaller than this many lots |
atOptional | string | session date (YYYY-MM-DD); default today (WIB), falling back to the last session before the market opens |
limitOptional | integer | return only the N most recent prints (100 max) |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the trades in data, and meta with the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].idOptional | string | opaque id for this print |
data.data[].timeRequired | string | |
data.data[].actionOptional | string | the aggressor side (BUY lifts the offer, SELL hits the bid) |
data.data[].symbolRequired | string | |
data.data[].priceRequired | number | |
data.data[].change_pctOptional | string | this print's price change vs. the prior close, percent |
data.data[].lotRequired | number | 1 lot = 100 shares; fractional on a negotiated-board (NG) print smaller than one lot |
data.data[].buyerOptional | string | buying broker's code as reported, e.g. "AK [F]" (the bracket tag is a coarse investor marker — prefer buyer_type) |
data.data[].sellerOptional | string | selling broker's code, same form as buyer |
data.data[].trade_numberOptional | string | the exchange trade number for this print |
data.data[].buyer_typeOptional | string | Foreign | Local | Government |
data.data[].seller_typeOptional | string | Foreign | Local | Government |
data.data[].boardRequired | string | |
data.data[].buy_order_numberOptional | string | buy-side order reference |
data.data[].sell_order_numberOptional | string | sell-side order reference |
data.data[].group_order_numberOptional | string | order reference shared across the matched pair (usually equal to buy_order_number) |
data.data[].valueOptional | string | traded value for this print, in rupiah |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/running-trade/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Running Trade Group
The running-trade tape for one or more stocks (comma-separated, e.g.
BBCA,BBRI,TLKM), grouped by broker crossing — buyer/seller list every broker
on each side of a matched print, so one row can carry several counterparties.
Filter to prints touching a specific broker with broker_buy/broker_sell. total
carries the whole result's aggregate value/lot/frequency. Check date — broker
identities are only disclosed once a session settles, so during trading hours this
returns the previous session, not today's prints.
For the ungrouped, per-print tape use /v2/running-trade/{symbols}.
| Name | Type | Description |
|---|---|---|
symbolsRequired | string | comma-separated ticker(s) Example: BBCA |
| Name | Type | Description |
|---|---|---|
actionOptional | string | show only buys or only sells |
broker_buyOptional | string | only prints where this broker is on the buy side |
broker_sellOptional | string | only prints where this broker is on the sell side |
broker_operatorOptional | string | how broker_buy and broker_sell combine when both are givenValues: orand |
atOptional | string | session date (YYYY-MM-DD); default today (WIB), falling back to the last session before the market opens |
limitOptional | integer | return only the N most recent prints (100 max) |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the rows in data, meta with the count,
and total — the aggregate across every row matching the filter, not just this page. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].idOptional | string | opaque id for this print |
data.data[].order_numberOptional | string | the order this row groups around |
data.data[].timeRequired | string | |
data.data[].actionOptional | string | this print's own aggressor side |
data.data[].group_actionOptional | string | the grouping's own side; can differ from action |
data.data[].symbolRequired | string | |
data.data[].priceRequired | object | A number the source itself keeps paired with its own formatted string, kept as that same pair rather than picked apart into two differently-named fields. |
data.data[].price.rawRequired | number | |
data.data[].price.formattedRequired | string | |
data.data[].changeOptional | string | this print's price change vs. the prior close |
data.data[].lotRequired | object | A number the source itself keeps paired with its own formatted string, kept as that same pair rather than picked apart into two differently-named fields. |
data.data[].lot.rawRequired | number | |
data.data[].lot.formattedRequired | string | |
data.data[].frequencyOptional | string | number of individual trades folded into this row |
data.data[].buyerRequired | object[] | |
data.data[].buyer[].codeRequired | string | |
data.data[].buyer[].typeOptional | string | Foreign | Local | Government |
data.data[].sellerRequired | object[] | |
data.data[].seller[].codeRequired | string | |
data.data[].seller[].typeOptional | string | Foreign | Local | Government |
data.data[].boardRequired | string | |
data.data[].valueRequired | object | A number the source itself keeps paired with its own formatted string, kept as that same pair rather than picked apart into two differently-named fields. |
data.data[].value.rawRequired | number | |
data.data[].value.formattedRequired | string | |
data.dateRequired | string | |
data.totalRequired | object | |
data.total.valueRequired | object | A number the source itself keeps paired with its own formatted string, kept as that same pair rather than picked apart into two differently-named fields. |
data.total.value.rawRequired | number | |
data.total.value.formattedRequired | string | |
data.total.lotRequired | object | A number the source itself keeps paired with its own formatted string, kept as that same pair rather than picked apart into two differently-named fields. |
data.total.lot.rawRequired | number | |
data.total.lot.formattedRequired | string | |
data.total.frequencyRequired | object | A number the source itself keeps paired with its own formatted string, kept as that same pair rather than picked apart into two differently-named fields. |
data.total.frequency.rawRequired | number | |
data.total.frequency.formattedRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/running-trade/BBCA/group" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [ { "buyer": [], "seller": [] } ] }}Orderbook
The full bid/ask depth ladder (usually 30-60 levels a side, not just the top-of-book) + last-trade snapshot, whole-book totals, the pre-opening/pre-closing auction's indicative price, today's activity split by board, and a few at-a-glance flags (active corporate action, Unusual Market Activity, whether a foreign buy/sell breakdown is available right now).
Outside trading hours, or if the book is briefly empty, bids/asks come back
empty — message tells you when that happened.
For the individual orders behind these price levels use /v2/order-queue/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
full_depthOptional | boolean | fill the ladder in the rest of the way to the auto-reject bounds (down to arb on the bid side, up to ara on the offer side); default on |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the orderbook in data, and meta. |
data.messageOptional | string | status message for the response |
data.dataRequired | object | |
data.data.symbolRequired | string | |
data.data.lastRequired | string | |
data.data.bidsRequired | object[] | best bid first |
data.data.bids[].priceRequired | number | |
data.data.bids[].lotRequired | integer | |
data.data.bids[].frequencyOptional | string | number of orders queued at this price level |
data.data.bids[].change_pctOptional | string | this price level's distance from the last traded price, percent — only populated when full_depth=true |
data.data.asksRequired | object[] | best ask first |
data.data.asks[].priceRequired | number | |
data.data.asks[].lotRequired | integer | |
data.data.asks[].frequencyOptional | string | number of orders queued at this price level |
data.data.asks[].change_pctOptional | string | this price level's distance from the last traded price, percent — only populated when full_depth=true |
data.data.total_bidOptional | string | the full bid side's lot/frequency, not just the levels listed in bids |
data.data.total_offerOptional | string | the full offer side's lot/frequency, same scope as total_bid |
data.data.bid_percentOptional | string | bid's share of total_bid + total_offer lot, percent |
data.data.by_boardOptional | object[] | today's frequency/volume/value split by trading board |
data.data.by_board[].boardRequired | string | All Market | Regular | Nego | Cash |
data.data.by_board[].frequencyRequired | object | A number the source itself keeps paired with its own formatted string, kept as that same pair rather than picked apart into two differently-named fields. |
data.data.by_board[].volumeRequired | object | A number the source itself keeps paired with its own formatted string, kept as that same pair rather than picked apart into two differently-named fields. |
data.data.by_board[].valueRequired | object | A number the source itself keeps paired with its own formatted string, kept as that same pair rather than picked apart into two differently-named fields. |
data.data.auctionOptional | string | indicative auction price/volume; null outside the pre-opening/pre-closing window |
data.data.has_active_corp_actionOptional | boolean | a corporate action is currently active for this stock — see /v2/corporate-actions/{symbol} for detail |
data.data.umaOptional | boolean | flagged for Unusual Market Activity |
data.data.foreign_breakdown_availableOptional | boolean | whether foreign buy/sell figures are published for this stock/board right now |
data.data.trading_statusOptional | string | e.g. "Active" — this stock's own trading status, not the exchange-wide session (see /v2/market/status for that) |
data.data.openOptional | string | |
data.data.highOptional | string | |
data.data.lowOptional | string | |
data.data.closeOptional | string | today's close — equal to last outside a live session |
data.data.vwapOptional | string | volume-weighted average price for the day |
data.data.changeOptional | string | price change from the previous close |
data.data.change_pctOptional | string | price change as a percent |
data.data.prev_closeOptional | string | previous trading day's close |
data.data.volumeOptional | string | today's traded volume, in shares |
data.data.valueOptional | string | today's traded value, in rupiah |
data.data.frequencyOptional | string | number of trades today |
data.data.araOptional | string | highest price the stock may trade at today (auto-reject upper) |
data.data.arbOptional | string | lowest price the stock may trade at today (auto-reject lower) |
data.data.tradeableOptional | string | whether the stock can be traded right now |
data.data.company_typeOptional | string | e.g. "Saham" — instrument type |
data.data.notationOptional | object[] | IDX special notations on this stock, empty if none |
data.data.notation[].codeRequired | string | |
data.data.notation[].descriptionRequired | string | |
data.data.foreign_buyOptional | string | today's foreign buy value, in rupiah |
data.data.foreign_sellOptional | string | today's foreign sell value, in rupiah |
data.data.foreign_netOptional | string | foreign_buy minus foreign_sell for today |
data.data.domestic_pctOptional | string | domestic investors' share of today's volume, percent |
data.data.foreign_pctOptional | string | foreign investors' share of today's volume, percent |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/orderbook/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": { "bids": [], "asks": [], "by_board": [], "notation": [] } }}Order Queue
The order-by-order queue for one symbol — open, matched and withdrawn orders, in exchange matching-priority order (not chronological). Each entry carries its price, lot size, remaining unfilled quantity, broker, and (once matched) the exchange order number.
Live during trading hours; outside them it returns the last session's snapshot instead of erroring.
For the aggregated bid/ask ladder instead of individual orders use
/v2/orderbook/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
actionOptional | string | show only buy-side or sell-side orders |
statusOptional | string | restrict to orders in this state Values: allopenpartial_matchfull_matchamendwithdrawn |
boardOptional | string | restrict to one trading board Values: allregularcashnegotiation |
priceOptional | string | filter to one price level |
limitOptional | integer | max orders to return (300 max) |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, data/meta like any other page, plus
the symbol this queue is for (the route only ever takes one). |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].idOptional | string | opaque id for this entry, distinct from order_number |
data.data[].queue_numberOptional | string | this order's position in the matching queue at its price level — 0 outside active trading |
data.data[].timeRequired | string | |
data.data[].actionRequired | string | the order's side |
data.data[].priceRequired | number | |
data.data[].statusRequired | string | the order's current state (OPEN, PARTIAL_MATCH, FULL_MATCH, AMEND, WITHDRAWN) |
data.data[].openRequired | integer | remaining unfilled lot |
data.data[].lotOptional | string | the order's original lot size — equal to open until partially filled |
data.data[].queue_lotOptional | string | lot ahead of this order in the matching queue at its price level — 0 outside active trading |
data.data[].boardRequired | string | |
data.data[].broker_codeOptional | string | null until the order matches — the placing broker isn't disclosed before then |
data.data[].exchange_order_numberOptional | string | |
data.data[].broker_groupOptional | string | Foreign | Local | Government; same disclosure timing as broker_code |
data.data[].order_numberRequired | string | |
data.symbolRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/order-queue/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Trade Book
Buy/sell broken down by price level or time bucket for one session, in exchange
order (price descending, time ascending). Each row carries the buy/sell lot, value
and frequency, their share of the session as a percentage, and (when available) the
pre-opening/post-closing activity at that level. total is the whole session's
aggregate, not just the rows in data; date is the session actually returned —
check it if at was left out, since it can be an earlier session rather than today.
For the same session's flow over time instead of by price level, use
/v2/trade-flow/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
group_byOptional | string | break the session down by price level or by time bucket Values: pricetime |
big_moneyOptional | boolean | only large prints |
atOptional | string | session date (YYYY-MM-DD); default today (WIB), falling back to the last session before the market opens |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the rows in data, meta with the count,
total (the whole session's aggregate, not just this page), and a few
session-level flags. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].keyRequired | string | price level or time bucket, per group_by |
data.data[].buy_lotRequired | string | |
data.data[].sell_lotRequired | string | |
data.data[].net_lotRequired | string | buy_lot minus sell_lot — which side dominates this level |
data.data[].total_lotOptional | string | buy_lot plus sell_lot — how much traded at this level, regardless of side |
data.data[].buy_valueRequired | string | |
data.data[].sell_valueRequired | string | |
data.data[].buy_frequencyOptional | string | number of buy trades at this level/bucket |
data.data[].sell_frequencyOptional | string | number of sell trades at this level/bucket |
data.data[].total_frequencyOptional | string | buy_frequency plus sell_frequency |
data.data[].buy_percentageOptional | string | buy's share of lot at this level, percent |
data.data[].sell_percentageOptional | string | sell's share of lot at this level, percent |
data.data[].buy_value_percentageOptional | string | buy's share of value at this level, percent |
data.data[].sell_value_percentageOptional | string | sell's share of value at this level, percent |
data.data[].pre_openOptional | string | |
data.data[].post_closeOptional | string | |
data.symbolRequired | string | |
data.dateRequired | string | |
data.totalRequired | object | The whole session's aggregate — not just the page of rows in data. |
data.total.buy_lotRequired | string | |
data.total.sell_lotRequired | string | |
data.total.total_lotRequired | string | |
data.total.buy_frequencyRequired | string | |
data.total.sell_frequencyRequired | string | |
data.total.total_frequencyRequired | string | |
data.total.buy_valueRequired | string | |
data.total.sell_valueRequired | string | |
data.total.buy_percentageRequired | string | |
data.total.sell_percentageRequired | string | |
data.total.buy_value_percentageRequired | string | |
data.total.sell_value_percentageRequired | string | |
data.total.pre_lotOptional | string | lot matched in the pre-opening auction |
data.total.post_lotOptional | string | lot matched in the post-closing auction |
data.total.pre_frequencyOptional | string | |
data.total.post_frequencyOptional | string | |
data.total.overall_net_per_minuteOptional | string | buy/sell split, normalized per minute of the session |
data.total.big_money_net_per_minuteOptional | string | same split restricted to large prints; null unless big_money=true |
data.previous_priceOptional | string | the session's reference price (prior close) |
data.is_show_pre_postRequired | boolean | whether pre_open/post_close carry real data for this session |
data.is_fca_stockRequired | boolean | trading under the Full Call Auction mechanism (the periodic call-auction board for special-monitoring stocks) rather than continuous trading |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/trade-book/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Trade Flow
1-minute buy/sell value flow for one session (cumulative running totals, not
independent per-minute figures), split out into the big-print-only ("big money")
slice of the same flow. total is the same session aggregate as
/v2/trade-book/{symbol}.
For the same session broken down by price level instead of by time, use
/v2/trade-book/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
atOptional | string | session date (YYYY-MM-DD); default today (WIB), falling back to the last session before the market opens |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the bars in data, meta with the count,
the symbol this flow is for, the session's aggregate (total, same shape as
TradeBookPage's), and the same two session-level flags. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].timeRequired | string | |
data.data[].priceOptional | string | traded price at this minute |
data.data[].buy_valueRequired | string | |
data.data[].sell_valueRequired | string | |
data.data[].net_valueRequired | string | buy_value minus sell_value |
data.data[].buy_lotOptional | string | |
data.data[].sell_lotOptional | string | |
data.data[].net_lotOptional | string | net lot for this minute (a reported figure, not buy_lot − sell_lot) |
data.data[].buy_frequencyOptional | string | |
data.data[].sell_frequencyOptional | string | |
data.data[].big_buy_valueRequired | string | |
data.data[].big_sell_valueRequired | string | |
data.data[].big_net_valueOptional | string | big_buy_value minus big_sell_value |
data.data[].big_buy_lotOptional | string | |
data.data[].big_sell_lotOptional | string | |
data.data[].big_net_lotOptional | string | same as net_lot, restricted to large prints |
data.data[].big_buy_frequencyOptional | string | |
data.data[].big_sell_frequencyOptional | string | |
data.symbolRequired | string | |
data.totalRequired | object | The whole session's aggregate — not just the page of rows in data. |
data.total.buy_lotRequired | string | |
data.total.sell_lotRequired | string | |
data.total.total_lotRequired | string | |
data.total.buy_frequencyRequired | string | |
data.total.sell_frequencyRequired | string | |
data.total.total_frequencyRequired | string | |
data.total.buy_valueRequired | string | |
data.total.sell_valueRequired | string | |
data.total.buy_percentageRequired | string | |
data.total.sell_percentageRequired | string | |
data.total.buy_value_percentageRequired | string | |
data.total.sell_value_percentageRequired | string | |
data.total.pre_lotOptional | string | lot matched in the pre-opening auction |
data.total.post_lotOptional | string | lot matched in the post-closing auction |
data.total.pre_frequencyOptional | string | |
data.total.post_frequencyOptional | string | |
data.total.overall_net_per_minuteOptional | string | buy/sell split, normalized per minute of the session |
data.total.big_money_net_per_minuteOptional | string | same split restricted to large prints; null unless big_money=true |
data.is_show_pre_postRequired | boolean | whether pre/post-auction totals carry real data for this session |
data.is_fca_stockRequired | boolean | trading under the Full Call Auction mechanism — see TradeBookPage |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/trade-flow/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Flow
Foreign Flow
Daily foreign buy / sell / net value for one stock, newest first by default
(order=asc for oldest first) — the settled figures the exchange publishes after each
close, so the series ends at the last completed trading day and never includes today's
session in progress. Values are in rupiah; foreign_net positive means net foreign
buying that day.
For the same figures alongside full OHLCV use /v2/chart/daily/{symbol}; for the
intraday broker-level flow use /v2/broker-flow/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
fromOptional | string | first day (YYYY-MM-DD). Default: 90 days back |
toOptional | string | last day (YYYY-MM-DD). Default: the last completed trading day |
orderOptional | string | row order — desc (newest first, default) or ascValues: descasc |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the daily rows in data (newest first by
default, order=asc to reverse), and meta with the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].dateRequired | string | |
data.data[].foreign_buyRequired | string | value bought by foreign investors that day |
data.data[].foreign_sellRequired | string | value sold by foreign investors that day |
data.data[].foreign_netRequired | string | foreign buy minus foreign sell for the day (positive = net foreign inflow) |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/foreign-flow/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Broker Flow
Intraday broker flow for one stock's session: for each 1-minute bucket, the price
and the running net value / net lots of the ~5 most active brokers up to that point
(a negative net means a net seller so far). Use investor_type to track the top
foreign or domestic brokers instead of overall.
The exchange doesn't identify individual brokers until a session settles, so with at
omitted you get the last completed session, not today's — date in the response says
which. Pass at for an older settled day.
For the settled per-broker totals without a time axis use /v2/broker-summary/{symbol};
for the raw buy/sell tape use /v2/trade-flow/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
atOptional | string | settled session date (YYYY-MM-DD). Default: the last completed session |
investor_typeOptional | string | all | foreign | domestic — which side's most-active brokers to track Values: allforeigndomestic |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the bars in data (oldest first), date
(the settled session the bars are for — broker-level data isn't published until a
session settles, so during trading hours this is the previous session), brokers
(the broker codes tracked, most active first), and meta with the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].timeRequired | string | |
data.data[].priceRequired | string | last traded price in this bucket |
data.data[].brokersRequired | object[] | |
data.data[].brokers[].broker_codeRequired | string | |
data.data[].brokers[].net_valueRequired | string | cumulative net value through this bar, in rupiah — negative means the broker is a net seller so far |
data.data[].brokers[].net_lotRequired | string | cumulative net lots through this bar (1 lot = 100 shares) |
data.dateRequired | string | |
data.brokersRequired | string[] | tracked broker codes, most active first |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/broker-flow/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [ { "brokers": [] } ], "brokers": [] }}Broker Activity
Which stocks one broker net-bought and net-sold over a window — the broker stalker.
Each row is one stock with the broker's net value, net lots, average price and trade
count there; value and lot are negative on the sell side. Biggest net moves first
within each side. For more than limit rows a side, pass meta.cursor back as
cursor for the next page; it's null when there are no more.
The exchange publishes broker identities only after a session settles, so the window
covers completed sessions — start / end in the response are the dates it actually
returned.
See the broker's flow inside one stock's session with /v2/broker-flow/{symbol}, or
every broker's net in one stock with /v2/broker-summary/{symbol}.
| Name | Type | Description |
|---|---|---|
codeRequired | string | broker code Example: YP |
| Name | Type | Description |
|---|---|---|
periodOptional | string | window length — 1d | 7d | 1m | 3m | 1y | ytd. Ignored if from/to are givenValues: 1d7d1m3m1yytd |
fromOptional | string | window start (YYYY-MM-DD); overrides period |
toOptional | string | window end (YYYY-MM-DD) |
limitOptional | integer | stocks per side (buy and sell counted separately), biggest net first |
cursorOptional | string | meta.cursor from the previous response — the next block of smaller net moves. Omit for the first page. |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the stocks in data (biggest net first per
side), the broker's own code / name / investor_group, the window (start / end,
the dates the exchange actually covered), and meta with the count and cursor (pass
back as ?cursor= for the next page of smaller net moves; null once a page is short). |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].symbolRequired | string | |
data.data[].sideRequired | string | BUY | SELL — the broker's net side in this stock over the window |
data.data[].valueRequired | string | net value over the window, in rupiah — negative on the SELL side |
data.data[].lotRequired | string | net lots over the window (1 lot = 100 shares) — negative on the SELL side |
data.data[].avg_priceRequired | string | the broker's average traded price in this stock over the window |
data.data[].frequencyRequired | string | number of the broker's trades in this stock over the window |
data.data[].has_corp_actionRequired | boolean | the stock currently has an active corporate action |
data.broker_codeRequired | string | |
data.broker_nameRequired | string | |
data.investor_groupRequired | string | the broker's classification — Foreign | Local | Government |
data.startRequired | string | first day of the window the exchange returned |
data.endRequired | string | last day of the window the exchange returned |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/broker-activity/YP" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Broker Summary
Every broker's net position in one stock for a session or window — each broker
appears on just one side, buy or sell. net_value, net_lot and net_volume are
signed: positive for a net buyer, negative for a net seller (net_volume is
net_lot × 100 shares). Biggest net first within each side, up to limit per side.
The exchange publishes broker identities only after a session settles, so latest
(the default) is the last completed session — date in the response says which.
For one broker across every stock use /v2/broker-activity/{code}; for who traded
with whom use /v2/broker-distribution/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
periodOptional | string | latest | 1w | 1m | 3m | 6m | ytd | 1y. Ignored if from/to are givenValues: latest1w1m3m6mytd1y |
fromOptional | string | window start (YYYY-MM-DD); overrides period |
toOptional | string | window end (YYYY-MM-DD) |
investor_typeOptional | string | all | foreign | domestic — restrict to brokers of that classification Values: allforeigndomestic |
limitOptional | integer | brokers per side, biggest net first — capped at however many were active that session |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the brokers in data (biggest net first per
side), the symbol, date (the settled session — broker attribution is published
after the close, so during trading hours this is the previous session), and meta. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].broker_codeRequired | string | |
data.data[].investor_groupRequired | string | Foreign | Local | Government |
data.data[].sideRequired | string | BUY | SELL — the broker's net side this session |
data.data[].net_valueRequired | string | net value in rupiah — positive for a net buyer, negative for a net seller |
data.data[].net_volumeRequired | string | net volume in shares (net_lot × 100), signed like net_value |
data.data[].net_lotRequired | string | net lots (1 lot = 100 shares), signed like net_value |
data.data[].avg_priceRequired | string | the broker's average traded price this session |
data.data[].frequencyRequired | string | number of the broker's trades this session |
data.symbolRequired | string | |
data.dateRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/broker-summary/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Broker Distribution
The broker-to-broker crossing map for one stock's session: each top broker on the
buy or sell side, and every broker on the other side of their flow with how much
crossed between them — the "who traded with whom" view the plain broker summary can't
show. unit measures the crossings in rupiah or shares.
The exchange publishes the crossing map only after a session settles, so with at
omitted you get the last completed session — date in the response says which.
For each broker's net without the counterparty breakdown use
/v2/broker-summary/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
unitOptional | string | value | volume — measure crossings in rupiah or shares Values: valuevolume |
atOptional | string | settled session date (YYYY-MM-DD). Default: the last completed session |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the top brokers each side in data with their
crossing map, the symbol, unit (value or volume), date (the settled session — the
crossing map is only published after a session settles), and meta. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].broker_codeRequired | string | |
data.data[].investor_groupRequired | string | Foreign | Local | Government |
data.data[].sideRequired | string | BUY | SELL — this broker's side |
data.data[].totalRequired | string | the broker's total on that side, in the response unit |
data.data[].crossed_withRequired | object[] | the brokers on the other side of this broker's flow, biggest first |
data.data[].crossed_with[].broker_codeRequired | string | |
data.data[].crossed_with[].investor_groupRequired | string | Foreign | Local | Government |
data.data[].crossed_with[].amountRequired | string | value (rupiah) or volume (shares), per the response unit |
data.symbolRequired | string | |
data.unitRequired | string | value | volume — what total and amount are measured in |
data.dateRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/broker-distribution/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [ { "crossed_with": [] } ] }}Market
Trending
The stocks drawing the most attention on the platform right now, most trending first. Each row carries the last price, the day's change, IDX special notations, and whether the stock is currently tradeable or has an active corporate action.
For the biggest price / value / volume moves use /v2/market/movers.
| Name | Type | Description |
|---|---|---|
limitOptional | integer | the N most trending (25 max) |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the stocks in data (most trending first), and
meta with the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].symbolRequired | string | |
data.data[].nameRequired | string | |
data.data[].lastRequired | string | |
data.data[].prev_closeOptional | string | previous trading day's close |
data.data[].changeOptional | string | price change vs. the previous close, in rupiah |
data.data[].change_pctOptional | string | the same change, as a percent |
data.data[].notationOptional | object[] | IDX special notations, empty if none |
data.data[].notation[].codeRequired | string | |
data.data[].notation[].descriptionRequired | string | |
data.data[].umaOptional | boolean | flagged for Unusual Market Activity |
data.data[].tradeableOptional | string | whether the stock can be traded right now |
data.data[].has_corp_actionOptional | boolean | a corporate action is active — see /v2/corporate-actions/{symbol} |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/market/trending" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [ { "notation": [] } ] }}Movers
Top gainers, losers, or most-active by traded value / volume / trade count for the
current session. Each row carries the price and change, the session's value / volume /
frequency, the live net buy / sell, and the settled foreign net (see net_foreign_as_of
— the foreign figures lag the live session).
For the stocks foreign or all investors are net-accumulating use /v2/market/top-foreign
and /v2/market/top-net; for what's simply drawing attention right now (not
necessarily a mover) use /v2/market/trending.
| Name | Type | Description |
|---|---|---|
byOptional | string | which ranking to return Values: gainerslosersvaluevolumefrequency |
stocks_onlyOptional | boolean | exclude warrants and other non-stock instruments; default on |
limitOptional | integer | how many stocks (50 max) |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the stocks in data, and meta with the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].symbolRequired | string | |
data.data[].nameRequired | string | |
data.data[].lastRequired | string | |
data.data[].changeOptional | string | price change vs. the previous close, in rupiah |
data.data[].change_pctOptional | string | the same change, as a percent |
data.data[].volumeOptional | string | today's traded volume, in shares |
data.data[].valueOptional | string | today's traded value, in rupiah |
data.data[].frequencyOptional | string | today's trade count |
data.data[].net_buyOptional | string | today's buy-side value, in rupiah |
data.data[].net_sellOptional | string | today's sell-side value, in rupiah |
data.data[].netOptional | string | net_buy minus net_sell |
data.data[].net_foreign_buyOptional | string | foreign buy value — a settled figure, see net_foreign_as_of |
data.data[].net_foreign_sellOptional | string | foreign sell value — a settled figure, see net_foreign_as_of |
data.data[].net_foreignOptional | string | net_foreign_buy minus net_foreign_sell |
data.data[].net_foreign_as_ofOptional | string | the session the foreign figures settled for — they lag the live session |
data.data[].big_money_netOptional | string | net value of large prints today, in rupiah |
data.data[].buy_value_pctOptional | string | buy share of today's traded value, percent |
data.data[].sell_value_pctOptional | string | sell share of today's traded value, percent |
data.data[].big_money_buy_pctOptional | string | large-print buy share of today's traded value, percent |
data.data[].big_money_sell_pctOptional | string | large-print sell share of today's traded value, percent |
data.data[].bid_percentOptional | string | bid share of total bid + offer lot, percent |
data.data[].has_umaOptional | boolean | flagged for Unusual Market Activity |
data.data[].has_corp_actionOptional | boolean | a corporate action is active — see /v2/corporate-actions/{symbol} |
data.data[].notationOptional | object[] | IDX special notations, empty if none |
data.data[].notation[].codeRequired | string | |
data.data[].notation[].descriptionRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/market/movers" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [ { "notation": [] } ] }}Top Foreign
The stocks foreign investors are net-buying (accumulation) or net-selling
(distribution) hardest this session, biggest first. net_value is the net foreign
value in rupiah (negative on the distribution side); date says which session.
For the same ranking across all investors use /v2/market/top-net.
| Name | Type | Description |
|---|---|---|
sideOptional | string | net foreign buyers or net foreign sellers Values: accumulationdistribution |
cursorOptional | string | meta.cursor from the previous response — the next block of 100. Omit for the first page. |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the stocks in data, the date the figures are
for, and meta — meta.cursor fetches the next 100. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].symbolRequired | string | |
data.data[].rankOptional | string | 1 = biggest on this side |
data.data[].net_valueRequired | string | net value for the session, in rupiah — negative on the distribution side |
data.data[].lotOptional | string | net lot for the session (1 lot = 100 shares) |
data.data[].avg_priceOptional | string | average traded price on this side |
data.data[].foreign_valueOptional | string | the foreign portion of net_value; 0 for an all-investor query |
data.data[].frequencyOptional | string | trade count; 0 on a pure crossing / negotiated block |
data.data[].sideRequired | string | ACCUMULATION or DISTRIBUTION |
data.dateRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/market/top-foreign" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Top Net
The stocks all investors together are net-buying (accumulation) or net-selling
(distribution) hardest this session, biggest first — same shape as
/v2/market/top-foreign but not restricted to foreign flow.
For foreign flow only use /v2/market/top-foreign.
| Name | Type | Description |
|---|---|---|
sideOptional | string | net buyers or net sellers Values: accumulationdistribution |
cursorOptional | string | meta.cursor from the previous response — the next block of 100. Omit for the first page. |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the stocks in data, the date the figures are
for, and meta — meta.cursor fetches the next 100. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].symbolRequired | string | |
data.data[].rankOptional | string | 1 = biggest on this side |
data.data[].net_valueRequired | string | net value for the session, in rupiah — negative on the distribution side |
data.data[].lotOptional | string | net lot for the session (1 lot = 100 shares) |
data.data[].avg_priceOptional | string | average traded price on this side |
data.data[].foreign_valueOptional | string | the foreign portion of net_value; 0 for an all-investor query |
data.data[].frequencyOptional | string | trade count; 0 on a pure crossing / negotiated block |
data.data[].sideRequired | string | ACCUMULATION or DISTRIBUTION |
data.dateRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/market/top-net" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Top Broker
Market-wide broker ranking for a window — every broker's buy / sell / net value,
volume and trade count, plus their Foreign / Local / Government classification. Biggest
first by the chosen metric. End-of-day: broker figures are published after the close, so
date is the last completed session unless from / to ask for an older window.
For one broker's stock-by-stock activity use /v2/broker-activity/{code}.
| Name | Type | Description |
|---|---|---|
fromOptional | string | window start (YYYY-MM-DD) |
toOptional | string | window end (YYYY-MM-DD) |
sortOptional | string | ranking metric Values: nettotalvolume |
limitOptional | integer | how many brokers — capped at however many were active in the window |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the brokers in data (biggest first by the
chosen sort), the settled date the ranking is for, and meta with the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].broker_codeRequired | string | |
data.data[].broker_nameRequired | string | |
data.data[].investor_groupOptional | string | Foreign | Local | Government |
data.data[].net_valueOptional | string | buy value minus sell value for the window |
data.data[].total_valueOptional | string | buy + sell value for the window |
data.data[].buy_valueOptional | string | buy-side value for the window, in rupiah |
data.data[].sell_valueOptional | string | sell-side value for the window, in rupiah |
data.data[].total_volumeOptional | string | buy + sell volume, in shares |
data.data[].total_frequencyOptional | string | buy + sell trade count |
data.dateRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/market/top-broker" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Calendar
Upcoming corporate-action calendar across the whole market — dividends, splits,
bonus issues, rights issues, RUPS meetings, warrants, tender offers, public expose and
IPOs, soonest first. Each event carries the defining date plus the cum / record /
payment dates where the type has them, and a short summary in note.
For the full detail of one stock's actions use /v2/corporate-actions/{symbol}.
| Name | Type | Description |
|---|---|---|
typeOptional | string | restrict to one action type (default: all) |
fromOptional | string | earliest date (YYYY-MM-DD); default: today |
toOptional | string | latest date (YYYY-MM-DD); default: no limit |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the events in data (soonest first), and meta.
For the full detail of one stock's actions use /v2/corporate-actions/{symbol}. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].symbolRequired | string | |
data.data[].nameOptional | string | company name, when the source carries it |
data.data[].typeRequired | string | the corporate-action type this event is |
data.data[].dateRequired | string | |
data.data[].cum_dateOptional | string | last day to buy and still be entitled |
data.data[].record_dateOptional | string | ownership record date |
data.data[].payment_dateOptional | string | dividend payment date |
data.data[].noteOptional | string | a short type-specific summary (amount, ratio, venue) |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/market/calendar" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Market Status
Where the exchange is in the trading day right now — the regular board and the
Full Call Auction board each with their session number, current phase, and when that
phase ends. is_trading is true only during continuous trading on the regular board
(not in pre-open, the lunch break, pre-close, post-trading, or when closed).
For the days the exchange is closed use /v2/market/holidays.
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the status in data, and meta (count = 1). |
data.messageOptional | string | status message for the response |
data.dataRequired | object | |
data.data.dateRequired | string | |
data.data.is_tradingRequired | boolean | true only during continuous trading on the regular board — false in pre-open, the lunch break, pre-close, post, or when closed |
data.data.regularRequired | object | One trading board's current phase. |
data.data.regular.sessionOptional | string | this board's own numbering — 1/2 for the regular board's morning/afternoon session, the Full Call Auction board runs a third |
data.data.regular.phaseOptional | string | the phase this board is in right now |
data.data.regular.phase_ends_atOptional | string | WIB clock time this phase ends (HH:MM:SS) |
data.data.regular.is_last_sessionOptional | boolean | no more sessions today after this one |
data.data.regular.is_end_of_dayOptional | boolean | the trading day has finished |
data.data.fcaRequired | object | One trading board's current phase. |
data.data.fca.sessionOptional | string | this board's own numbering — 1/2 for the regular board's morning/afternoon session, the Full Call Auction board runs a third |
data.data.fca.phaseOptional | string | the phase this board is in right now |
data.data.fca.phase_ends_atOptional | string | WIB clock time this phase ends (HH:MM:SS) |
data.data.fca.is_last_sessionOptional | boolean | no more sessions today after this one |
data.data.fca.is_end_of_dayOptional | boolean | the trading day has finished |
data.data.server_timeOptional | string | exchange server time (WIB) |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/market/status" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success"}Holidays
Indonesian public holidays and collective-leave (cuti bersama) days — the days the exchange is closed — for one calendar year, chronological. A bundled list, refreshed yearly.
For where the exchange is in today's session use /v2/market/status.
| Name | Type | Description |
|---|---|---|
yearOptional | string | calendar year (default: current) |
typeOptional | string | restrict to one kind |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the days in data (chronological), and meta. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].dateRequired | string | |
data.data[].nameRequired | string | |
data.data[].typeRequired | string | whether it's a public holiday or a collective-leave (cuti bersama) day |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/market/holidays" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}News
Market News
Market-wide news, filing and insider-move feed, newest first — no article body, just
title/timestamp/link plus the tickers it's tagged with. category switches between
plain news, broker/company filing reports (each with an AI-generated summary), and
insider share-move posts (for the structured transaction records behind those posts
use /v2/insider/{symbol}).
Page with cursor: pass the previous response's meta.cursor back to get the next
batch; null means there's nothing older left.
| Name | Type | Description |
|---|---|---|
categoryOptional | string | which feed to return Values: newsreportsinsider |
limitOptional | integer | how many items (100 max) |
cursorOptional | string | meta.cursor from the previous response. Omit for the first page. |
include_all_reportsOptional | boolean | widen the result to report sub-types the default view leaves out (monthly holder registrations, capital-action filings, and others); only applies when category=reports |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the items in data, and meta with the
count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].idRequired | string | |
data.data[].titleRequired | string | |
data.data[].sourceOptional | string | always null for now — no per-item byline is available |
data.data[].published_atRequired | string | |
data.data[].urlOptional | string | a link to the full item, when one exists outside the app |
data.data[].symbolsRequired | string[] | tickers the item is tagged with |
data.data[].summaryOptional | string | present on category=reports items only |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/news" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [ { "symbols": [] } ] }}Symbol News
One ticker's news, filing and insider-move feed, newest first — same shape as
/v2/news, scoped to symbol.
Page with cursor: pass the previous response's meta.cursor back to get the next
batch; null means there's nothing older left.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
categoryOptional | string | which feed to return Values: newsreportsinsider |
limitOptional | integer | how many items (100 max) |
cursorOptional | string | meta.cursor from the previous response. Omit for the first page. |
include_all_reportsOptional | boolean | widen the result to report sub-types the default view leaves out (monthly holder registrations, capital-action filings, and others); only applies when category=reports |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the items in data, and meta with the
count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].idRequired | string | |
data.data[].titleRequired | string | |
data.data[].sourceOptional | string | always null for now — no per-item byline is available |
data.data[].published_atRequired | string | |
data.data[].urlOptional | string | a link to the full item, when one exists outside the app |
data.data[].symbolsRequired | string[] | tickers the item is tagged with |
data.data[].summaryOptional | string | present on category=reports items only |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/news/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [ { "symbols": [] } ] }}Insider
Insider
Major-holder (insider) share moves and the resulting ownership change, newest first.
Each row is one transaction: which insider, action type, share count, price, and the
ownership percentage before/after — action isn't limited to BUY/SELL.
from/to narrow the date window; action_type filters by type. One call returns at
most 50 rows (limit caps it lower, never higher) — pass the response's meta.cursor
back as cursor for the next page; it's null on the last page.
For the resulting current ownership breakdown (not the transactions themselves) use
/v2/shareholders/{symbol}; for a news-feed view of these same moves use
/v2/news/{symbol}?category=insider.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
fromOptional | string | YYYY-MM-DD. Default: the earliest transaction on file. |
toOptional | string | YYYY-MM-DD. Default: the most recent transaction. |
action_typeOptional | string | restrict to one transaction type; corp_action covers every corporate-action type at once rather than picking one. Unfiltered by default. |
limitOptional | integer | 50 is the max per call — use cursor for more. |
cursorOptional | string | meta.cursor from the previous response. Omit for the first page. |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the transactions in data, and meta with
the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].holderRequired | string | |
data.data[].actionRequired | string | The transaction type — not limited to BUY/SELL; see action_type on GET /v2/insider/{symbol} for the full set of values |
data.data[].sharesRequired | string | |
data.data[].priceRequired | string | |
data.data[].dateRequired | string | |
data.data[].ownership_before_pctRequired | string | |
data.data[].ownership_after_pctRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/insider/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Shareholders
Shareholder composition — holder / class, shares, ownership %, as of the latest filing. Only the current composition is available; there's no historical series to page through.
For the individual moves behind this composition use /v2/insider/{symbol}; for the
static >1% registered holder list from the company profile (a different snapshot —
IPO-era filing detail, not this composition breakdown) use
/v2/instruments/{symbol}/profile.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the composition rows in data, and meta
with the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].holderRequired | string | |
data.data[].categoryRequired | string | institution | retail | government | founder | public |
data.data[].sharesRequired | string | |
data.data[].ownership_pctRequired | string | |
data.data[].as_ofRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/shareholders/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Corp. Actions
Corporate Actions
Full corp-action history for one symbol, newest first: dividends, stock splits,
bonus shares, rights issues and shareholder meetings (RUPS). Filter to one type,
or narrow by ex-date with from/to.
Capped at the 30 most recent events on file — there's no way to page further back
through this endpoint. For upcoming events across every stock at once use
/v2/market/calendar.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
typeOptional | string | dividend | split | bonus | rights | rups — or, rarely, another event type name straight from the exchange feed for something that doesn't map to those five |
fromOptional | string | Filter by ex-date. Default: the earliest event on file. |
toOptional | string | Filter by ex-date. Default: the most recent event on file. |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the events in data, and meta with the
count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].typeRequired | string | dividend | split | bonus | rights | rups — occasionally another event type name straight from the exchange feed (e.g. "warrant"), passed through as-is when it doesn't fall into one of those five |
data.data[].announce_dateRequired | string | |
data.data[].ex_dateRequired | string | |
data.data[].record_dateRequired | string | |
data.data[].pay_dateRequired | string | |
data.data[].valueRequired | string | dividend per share, or rights issue price |
data.data[].yield_pctRequired | string | dividend per share / close price on the ex-date. Only available for a dividend on a symbol whose price history is on file locally — null otherwise |
data.data[].ratio_oldRequired | string | |
data.data[].ratio_newRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/corporate-actions/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Fundamentals
Keystats
Net income, EPS and revenue history, plus the current valuation/profitability/
balance-sheet ratios (PER, PBV, ROE, total assets, and more, grouped by category in
ratios). The ratios are a snapshot as of now, not a per-period series — there's no
historical PER/PBV/ROE/etc. available, only the current one. dividend/payout_ratio/
dividend_yield here are annual aggregates — for the underlying declarations (ex-date,
record date, ...) use /v2/corporate-actions/{symbol}?type=dividend. For full line-item
statements instead of these summary figures use /v2/financials/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
yearsOptional | integer | how many years of history to include (10 max) |
period_typeOptional | string | annual | quarterly Values: annualquarterly |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the per-period history in data, the
current-snapshot ratios in ratios (not per period — see KeyStatRatio), and
meta with data's count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].period_endRequired | string | |
data.data[].period_typeRequired | string | annual | quarterly |
data.data[].revenueRequired | string | |
data.data[].net_incomeRequired | string | |
data.data[].epsRequired | string | |
data.data[].dividendRequired | string | cash dividend declared for the year — annual rows only |
data.data[].payout_ratioRequired | string | annual rows only |
data.data[].dividend_yieldRequired | string | annual rows only |
data.ratiosRequired | object[] | |
data.ratios[].categoryRequired | string | e.g. "Current Valuation", "Profitability", "Balance Sheet" |
data.ratios[].nameRequired | string | e.g. "Current PE Ratio (TTM)", "Total Assets" |
data.ratios[].valueRequired | string | null when not applicable for this symbol |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/keystats/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [], "ratios": [] }}Financials
One financial statement (income statement, balance sheet or cash flow), full
line-item detail — lines[].level is the nesting depth (0 = a top-level line like
"Total Revenue", deeper for the sub-items beneath it). Most top-level lines carry
their own total; a few (e.g. the balance sheet's Assets/Liabilities/Equity headers)
don't — sum their sub-lines for those. values is keyed by period ("2024" for an
annual line, "2024Q1" for quarterly), newest period first. For summary ratios and
a multi-year history instead of full line-item detail use /v2/keystats/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
statementOptional | string | income | balance | cashflow Values: incomebalancecashflow |
period_typeOptional | string | annual | quarterly Values: annualquarterly |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the statement in data, and meta. |
data.messageOptional | string | status message for the response |
data.dataRequired | object | |
data.data.symbolRequired | string | |
data.data.statementRequired | string | income | balance | cashflow |
data.data.period_typeRequired | string | annual | quarterly |
data.data.currencyRequired | string | reporting currency, e.g. IDR |
data.data.linesRequired | object[] | |
data.data.lines[].labelRequired | string | |
data.data.lines[].levelRequired | integer | 0 = a top-level line item, deeper for a sub-line beneath it |
data.data.lines[].valuesRequired | object | {period: amount}, newest period first, e.g. {"2025": 1.2e12, "2024": 1.1e12}. Null for a period a section header has no total of its own for — add up its own sub-lines instead (seen on the balance sheet's Assets/Liabilities/Equity headers, not on the income statement or cash flow) |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/financials/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": { "lines": [] } }}Instruments
List Instruments
Tradable instruments in an index. index=IHSG is the whole market. For any other
IDX index (there are dozens — syariah, ESG, thematic, ...) use
/v2/indices/{code}/members instead.
| Name | Type | Description |
|---|---|---|
indexOptional | string | which index's members to list. Default: KOMPAS100 Values: LQ45IDX30KOMPAS100IHSG |
qOptional | string | name / symbol contains. Unfiltered by default |
limitOptional | integer | how many to return. Default: 100 |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the instruments in data, and meta
with the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].symbolRequired | string | |
data.data[].nameRequired | string | |
data.data[].sectorRequired | string | |
data.data[].subsectorRequired | string | |
data.data[].boardRequired | string | listing board, e.g. Papan Utama |
data.data[].listing_dateRequired | string | null unless on file for this symbol |
data.data[].shares_outstandingRequired | string | null unless on file for this symbol |
data.data[].indexesRequired | string[] | index memberships, e.g. ["LQ45", "KOMPAS100"] |
data.data[].lastRequired | string | latest settled close — an end-of-day figure, not a live tick; null unless recent price data is on file. For a live price, use /v2/chart/quote/{symbol} |
data.data[].change_pctRequired | string | vs. the prior settled close; same end-of-day caveat as last |
data.data[].market_capRequired | string | null unless on file for this symbol |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/instruments" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [ { "indexes": [] } ] }}Get Instrument
One instrument: sector / sub-sector, index membership, and end-of-day price fields
when on file. For a live price, use /v2/chart/quote/{symbol} instead; for financial
ratios and history, /v2/keystats/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the instrument in data, and meta. |
data.messageOptional | string | status message for the response |
data.dataRequired | object | |
data.data.symbolRequired | string | |
data.data.nameRequired | string | |
data.data.sectorRequired | string | |
data.data.subsectorRequired | string | |
data.data.boardRequired | string | listing board, e.g. Papan Utama |
data.data.listing_dateRequired | string | null unless on file for this symbol |
data.data.shares_outstandingRequired | string | null unless on file for this symbol |
data.data.indexesRequired | string[] | index memberships, e.g. ["LQ45", "KOMPAS100"] |
data.data.lastRequired | string | latest settled close — an end-of-day figure, not a live tick; null unless recent price data is on file. For a live price, use /v2/chart/quote/{symbol} |
data.data.change_pctRequired | string | vs. the prior settled close; same end-of-day caveat as last |
data.data.market_capRequired | string | null unless on file for this symbol |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/instruments/BBCA" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": { "indexes": [] } }}Get Profile
Company profile — narrative background, IPO / listing history, board of
commissioners & directors, corporate secretary, subsidiaries, registered >1%
holders, beneficial owners, and the reported shareholder count. For the current
ownership composition breakdown (institution/retail/government/founder/public) use
/v2/shareholders/{symbol}; for financial ratios and history, /v2/keystats/{symbol}.
| Name | Type | Description |
|---|---|---|
symbolRequired | string | ticker Example: BBCA |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the profile in data, and meta. |
data.messageOptional | string | status message for the response |
data.dataRequired | object | |
data.data.symbolRequired | string | |
data.data.backgroundRequired | string | |
data.data.listing_dateRequired | string | |
data.data.listing_boardRequired | string | |
data.data.ipo_priceRequired | string | |
data.data.ipo_sharesRequired | string | |
data.data.underwritersRequired | string[] | |
data.data.free_float_pctRequired | string | |
data.data.share_registrarRequired | string | |
data.data.corporate_secretaryRequired | string | |
data.data.executivesRequired | object[] | |
data.data.executives[].roleRequired | string | commissioner | director |
data.data.executives[].nameRequired | string | |
data.data.subsidiariesRequired | object[] | |
data.data.subsidiaries[].nameRequired | string | |
data.data.subsidiaries[].ownership_pctRequired | string | |
data.data.subsidiaries[].businessRequired | string | |
data.data.major_holdersRequired | object[] | >1% registered holders |
data.data.major_holders[].nameRequired | string | |
data.data.major_holders[].ownership_pctRequired | string | |
data.data.major_holders[].sharesRequired | string | |
data.data.major_holders[].typeRequired | string | raw holder-type code, e.g. CP / ID / FD — see classification for a decoded category |
data.data.major_holders[].nationalityRequired | string | |
data.data.major_holders[].classificationRequired | string | Corporate | Individual | … |
data.data.beneficial_ownersRequired | string[] | |
data.data.holder_countRequired | string | latest reported number of shareholders |
data.data.holder_count_as_ofRequired | string | |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/instruments/BBCA/profile" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": { "underwriters": [], "executives": [], "subsidiaries": [], "major_holders": [], "beneficial_owners": [] } }}List Brokers
The IDX broker directory — 2-letter code, name, Foreign/Local group. For one
broker's cross-market trading activity use /v2/broker-activity/{code} instead.
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the brokers in data, and meta with
the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].codeRequired | string | |
data.data[].nameRequired | string | |
data.data[].groupRequired | string | Foreign | Local |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/brokers" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Get Broker
One broker — name and Foreign/Local group. For its cross-market trading activity
use /v2/broker-activity/{code} instead.
| Name | Type | Description |
|---|---|---|
codeRequired | string | 2-letter broker code, e.g. YP |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the broker in data, and meta. |
data.messageOptional | string | status message for the response |
data.dataRequired | object | |
data.data.codeRequired | string | |
data.data.nameRequired | string | |
data.data.groupRequired | string | Foreign | Local |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/brokers/{code}" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success"}List Indices
Every IDX index — code, name and category. See /v2/indices/{code}/members for
a specific index's constituents.
| Name | Type | Description |
|---|---|---|
kindOptional | string | unfiltered by default |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the indices in data, and meta with
the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].codeRequired | string | |
data.data[].nameRequired | string | |
data.data[].kindRequired | string | main | syariah | esg | thematic |
data.data[].member_countRequired | string | null unless this index's membership is tracked locally (currently LQ45 / IDX30 / KOMPAS100 only) |
data.data[].lastRequired | string | not currently populated here — an index has its own price too, look the code up at /v2/instruments/{code} instead (e.g. /v2/instruments/IHSG) |
data.data[].change_pctRequired | string | not currently populated here — see last |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/indices" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [] }}Index Members
Current constituents of an index.
| Name | Type | Description |
|---|---|---|
codeRequired | string | index code, e.g. LQ45 |
| Name | Type | Description |
|---|---|---|
is_successOptional | boolean | Example: true |
messageOptional | string | Example: Success |
dataOptional | object | Response wrapper: a status message, the instruments in data, and meta
with the count. |
data.messageOptional | string | status message for the response |
data.dataRequired | object[] | |
data.data[].symbolRequired | string | |
data.data[].nameRequired | string | |
data.data[].sectorRequired | string | |
data.data[].subsectorRequired | string | |
data.data[].boardRequired | string | listing board, e.g. Papan Utama |
data.data[].listing_dateRequired | string | null unless on file for this symbol |
data.data[].shares_outstandingRequired | string | null unless on file for this symbol |
data.data[].indexesRequired | string[] | index memberships, e.g. ["LQ45", "KOMPAS100"] |
data.data[].lastRequired | string | latest settled close — an end-of-day figure, not a live tick; null unless recent price data is on file. For a live price, use /v2/chart/quote/{symbol} |
data.data[].change_pctRequired | string | vs. the prior settled close; same end-of-day caveat as last |
data.data[].market_capRequired | string | null unless on file for this symbol |
data.metaRequired | object | |
data.meta.countRequired | integer | number of items in data |
data.meta.as_ofOptional | string | when the data was last updated |
data.meta.cursorOptional | string | pass back as ?cursor= to fetch the next page; null on the last page |
data.meta.stale_secondsOptional | string | how many seconds old the newest item is |
curl -X GET "https://use.api.co.id/idx/v2/indices/{code}/members" \ -H "x-api-co-id: $API_CO_ID_KEY"{ "is_success": true, "message": "Success", "data": { "data": [ { "indexes": [] } ] }}