Historical Data¶
The Historical Data API provides time-series OHLCV (Open, High, Low, Close, Volume) data for instruments across various intervals. This is ideal for charting, analysis, and building trading strategies.
Two endpoints share the same candle contract, the same intervals and the same per-call limits: one for instruments that are still trading, and one for F&O contracts that have expired. They differ only in how an instrument is identified. The expired-contract endpoint is coming soon; its contract is documented below so you can build against it ahead of time.
| Request Type | Path | Description |
|---|---|---|
| GET | /market/historical/{interval} | Fetches historical OHLCV data. |
| GET | /market/historical/expired/{interval} | Fetches historical OHLCV data for expired F&O contracts. Coming soon. |
Get Historical Data¶
Endpoint
Path Parameters
| Parameter | Description |
|---|---|
interval | The time interval for each candle. See the table of Supported Intervals below. |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
scrip-codes | string | Yes | A comma-separated list of at most 5 instrument identifiers. Example: NSE_3045,NFO_51011 |
start_time | int64 | Yes | Start timestamp (Unix epoch milliseconds, inclusive). |
end_time | int64 | Yes | End timestamp (Unix epoch milliseconds, exclusive). |
Up to 5 instruments per request
scrip-codes takes a maximum of five identifiers; requests with more return 400 {"debug_info": "Invalid scrip codes", "message": "Bad Request"}. Repeated codes are de-duplicated and count once. For a larger universe, batch your instruments five at a time.
The segment travels in each code's prefix — NSE_ for cash, NFO_ for F&O — so there is no separate segment parameter to set.
Example Request
curl --location 'https://api.indstocks.com/market/historical/1minute?scrip-codes=NSE_3045&start_time=1750055540000&end_time=1750141940000' \
--header 'Authorization: YOUR_ACCESS_TOKEN'
Response Format The response uses a success boolean. data is keyed by scrip code, and each scrip's candles is an array of objects.
| Candle field | Description |
|---|---|
ts | Candle open time, Unix epoch seconds (IST). See Candle timestamps. |
o | Open price |
h | High price |
l | Low price |
c | Close price |
v | Volume |
{
"success": true,
"data": {
"NSE_1594": {
"candles": [
{ "ts": 1782877500, "o": 1007, "h": 1013.9, "l": 999.3, "c": 1000.4, "v": 2847163 },
{ "ts": 1782881100, "o": 1000.4, "h": 1002, "l": 996.7, "c": 999.6, "v": 1389042 }
]
}
}
}
Request times are milliseconds, candle times are seconds
start_time and end_time are epoch milliseconds, while the ts on each returned candle is epoch seconds. Multiply by 1000 when using a returned ts to build the next request.
Candle fields
Candles carry ts, o, h, l, c and v across every interval and segment. For open interest, use the Option Chain, which returns OI and previous OI per leg.
Response shape
- This endpoint wraps its response in a
successboolean — checksuccessrather thanstatuswhen handling it. - Each requested code gets its own key under
datawith its owncandlesarray — they are not merged into a single list. - Codes with no data in the requested window are not included under
data, so read the keys returned rather than assuming one per code requested.
Candle timestamps¶
ts is the time at which the candle opens. Each candle covers the half-open interval [ts, ts + interval) — its own opening time is included, the next candle's opening time is not.
Worked example, on 5minute:
Candle ts | Covers the minutes | Next candle opens |
|---|---|---|
09:15 | 09:15 – 09:19 | 09:20 |
09:20 | 09:20 – 09:24 | 09:25 |
09:25 | 09:25 – 09:29 | 09:30 |
The 09:20 candle opens on the first trade at or after 09:20:00 and closes on the last trade before 09:25:00. The rule is the same on every interval, and on both endpoints.
Deriving a closing time
If your charting or backtesting engine indexes bars by closing time rather than opening time, add the interval to ts as you read it: a 5minute candle stamped 09:20 closes at 09:25.
Intraday candles are anchored to the session open
Buckets are aligned to 09:15 IST, the start of the trading session, rather than to wall-clock :00/:05 boundaries. 5minute candles fall at 09:15, 09:20, 09:25 …, 15minute candles at 09:15, 09:30, 09:45 …, and 60minute candles at 09:15, 10:15, 11:15 …
Get Expired Contract Candles¶
Coming soon
This endpoint is not yet available on production. The contract below is settled and is published so you can build against it in advance; requests to it will start returning data once it is enabled. This page and the Changelog will be updated when it goes live.
The same OHLCV candles, for F&O contracts whose expiry has already passed — Get Historical Data covers instruments that are still trading. Together the two endpoints will give a strategy the full price history of a contract, from listing through to expiry.
Contracts here are identified by trading_symbol, the identifier returned by Search Expired Contracts and Contracts for an Expired Expiry. Exchanges reuse numeric instrument tokens once a contract has expired, so trading_symbol is the stable way to address a contract that is no longer trading.
Endpoint
Path Parameters
| Parameter | Description |
|---|---|
interval | The time interval for each candle. Same values and same per-call maximums as the live endpoint — see Supported Intervals & Maximum Time Range. |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
trading-symbols | string | Yes | A comma-separated list of 1 to 50 trading_symbols. Example: NIFTY26AUG2523950CE |
start_time | int64 | Yes | Start timestamp (Unix epoch milliseconds, inclusive). |
end_time | int64 | Yes | End timestamp (Unix epoch milliseconds, exclusive). |
segment | string | The exchange derivatives segment the contracts belong to. Enum: NFO, BFO Default: NFO |
Up to 50 symbols per request
trading-symbols takes between one and fifty identifiers; requests with more return 400 {"debug_info": "trading-symbols must contain 1-50 symbols.", "message": "Bad request"}. Get Historical Data takes up to five scrip-codes, so size your batching per endpoint rather than sharing one constant across both.
Set segment to reach BSE derivatives
segment selects the exchange's derivatives segment. Only F&O contracts expire, so two values apply:
| Value | Segment |
|---|---|
NFO | NSE Derivatives (F&O) |
BFO | BSE Derivatives (F&O) |
NFO is the default, so NSE contracts need no segment at all. BSE contracts must be requested with segment=BFO — a BSE trading_symbol sent without it is looked up against NSE, finds no match, and comes back absent from data.
These are the exchange-segment codes used across the API, the same ones that prefix a scrip-code or a WebSocket instrument — see Instrument Code Formats. They are not the segment=DERIVATIVE value taken by Contracts & Expiries.
trading-symbols, start_time, end_time and segment are the complete query contract; your account is resolved from the access token.
Example Request
These calls will work once the endpoint is enabled. NSE derivatives, using the default segment:
curl --location 'https://api.indstocks.com/market/historical/expired/1minute?trading-symbols=NIFTY26AUG2523950CE&start_time=1787542200000&end_time=1787652000000' \
--header 'Authorization: YOUR_ACCESS_TOKEN'
BSE derivatives, with segment=BFO:
curl --location 'https://api.indstocks.com/market/historical/expired/1minute?trading-symbols=SENSEX26AUG2581000CE&segment=BFO&start_time=1787542200000&end_time=1787652000000' \
--header 'Authorization: YOUR_ACCESS_TOKEN'
Response Format Identical in shape to Get Historical Data — a success boolean, data keyed per instrument, each with an array of {ts, o, h, l, c, v} candle objects. The only difference is the key: trading_symbol rather than scrip code.
{
"success": true,
"data": {
"NIFTY26AUG2523950CE": {
"candles": [
{ "ts": 1787543100, "o": 374.1, "h": 395.15, "l": 374.1, "c": 390, "v": 19955 },
{ "ts": 1787543160, "o": 390, "h": 402.5, "l": 388.2, "c": 399.7, "v": 14320 }
]
}
}
}
The candle contract is identical to the live endpoint. ts is the candle's open time in epoch seconds and covers [ts, ts + interval) (see Candle timestamps), start_time and end_time are epoch milliseconds, intraday buckets are anchored to the 09:15 IST session open, and each interval carries the same per-call maximum range.
Read the keys returned
data carries an entry for each requested symbol that has candles in the window. A symbol with no data in that window, and any symbol the endpoint does not recognise — a numeric security_id sent in place of a trading symbol, or a BSE contract requested without segment=BFO — is absent from data rather than returned empty. Match the keys in the response against the symbols you requested.
A zero-width window, where start_time equals end_time, returns "candles": null.
Candle fields
Candles carry ts, o, h, l, c and v, the same set as the live endpoint. For open interest, use the Option Chain, which returns OI and previous OI per leg.
Supported Intervals & Maximum Time Range¶
| Interval Label | Value | Max Range Per Call |
|---|---|---|
| 1 Minute | 1minute | 7 Days |
| 2 Minutes | 2minute | 7 Days |
| 3 Minutes | 3minute | 7 Days |
| 4 Minutes | 4minute | 7 Days |
| 5 Minutes | 5minute | 7 Days |
| 10 Minutes | 10minute | 7 Days |
| 15 Minutes | 15minute | 7 Days |
| 30 Minutes | 30minute | 7 Days |
| 1 Hour | 60minute | 15 Days |
| 2 Hours | 120minute | 15 Days |
| 3 Hours | 180minute | 15 Days |
| 4 Hours | 240minute | 15 Days |
| 1 Day | 1day | 1 Year |
| 1 Week | 1week | 1 Year |
| 1 Month | 1month | 1 Year |
These intervals and maximums apply to both Get Historical Data and Get Expired Contract Candles.
This is the ceiling on a single call, not the depth of history available. Reaching further back is a matter of making more calls — one per window, walking backwards — not of asking for a wider window.
The maximum applies to the window you request, not to the span you get back. On 1week and 1month the returned candles land on week and month boundaries, so a full one-year request comes back spanning slightly less than a year.
Use the exact interval values
The table above is the complete set. Hour intervals are expressed in minutes — 60minute, 120minute, 180minute, 240minute — and the daily, weekly and monthly intervals take the 1 prefix: 1day, 1week, 1month. Other values return 400 {"debug_info": "invalid interval.", "message": "Bad request"}.
Paging by date range¶
A wider request returns the maximum window, not an error
The maximum is applied to every call. A request for a window wider than the interval's maximum returns 200 with "success": true and the maximum window's data, so the width of the request is what determines the coverage you receive.
Both Get Historical Data and Get Expired Contract Candles work this way, and neither returns a continuation token — paging is by date range. Size each request to the maximum for its interval, and check the candles you receive against the candles the window should contain.
To build a series longer than one window, issue one request per maximum-width window and walk backwards, stitching the results together.
Notes¶
start_time/end_timequery parameters are in IST and Unix epoch milliseconds; thetsfield inside each returned candle is in Unix epoch seconds.- Keep each request within the maximum range for the chosen interval. A wider window returns the maximum range's data rather than an error, so size each request to the limit in the table above and page by date range for longer histories.
start_timemust not be later thanend_time, which returns400 {"debug_info": "start_time must not be after end_time.", "message": "Bad request"}.- If requesting multiple instruments, each one gets its own
candlesarray underdata— they are not merged into a single list. - The two endpoints take different identifiers and different batch sizes:
scrip-codeswith a maximum of five for live instruments,trading-symbolswith a maximum of fifty for expired contracts. - Both endpoints return the same candle fields,
ts,o,h,l,candv. For open interest, use the Option Chain.
See Also¶
- Market Quotes — live snapshot instead of historical candles
- Instruments — look up the
SECURITY_IDused to buildscrip-codes - Contracts & Expiries — find the
trading_symbolof an expired contract - Error Bucket —
DataExceptionfor invalid interval/time-range parameters