API Reference

Every endpoint, with real requests and real responses.

One base URL, one header, plain JSON. Everything below is copy-pasteable against the live API — no placeholder data.

Base URL https://bharatstockapi.com Get a free API key
Developer tools Sign in to unlock

Live request testing, one-click copy on every example, and a ready-made Postman collection — free with any account, paid or not.

Sign in to unlock

Authentication

Every endpoint (other than key creation and checkout) requires an X-API-Key header. There is no OAuth flow, no session token, and no key rotation endpoint yet — treat your key like a password.

curl https://bharatstockapi.com/v1/stocks/RELIANCE \ -H "X-API-Key: bsk_live_yourkeyhere"

A missing or invalid key returns 401 Unauthorized.

Python SDK

Prefer typed calls over raw HTTP? Install the official Python client from PyPI. It handles the X-API-Key header, JSON parsing into typed objects, pagination, and automatic retry with back-off when you hit a 429 rate limit.

pip install bharatstock

Then set your key (either pass it directly or via the BHARATSTOCK_API_KEY environment variable) and call any endpoint:

from bharatstock import BharatStock client = BharatStock(api_key="bsk_live_yourkeyhere") # A single stock, with latest price + derived metrics stock = client.stocks.get("RELIANCE") print(stock.company_name, stock.metrics.pe_ratio) # Batch quotes for a watchlist (one call) for q in client.stocks.quotes(["TCS", "INFY", "HDFCBANK"]): print(q.symbol, q.close, q.change_pct) # Run the screener for r in client.screener.run(filters=["pe_ratio.lt.15", "roe.gt.18"]): print(r.symbol, r.pe_ratio, r.roe)

The client mirrors this reference: client.stocks, client.deals, client.screener, client.indices, client.market, plus client.search(), client.movers(), client.price_shockers(), and client.status(). Source and full docs on PyPI →

JS/TS SDK

Building in Node.js or TypeScript? Install the official JS/TS client from npm. It handles the X-API-Key header, camelCased typed responses, pagination, and automatic retry with back-off when you hit a 429 rate limit. Works in Node 18+ and modern browsers/edge runtimes (native fetch, zero runtime dependencies).

npm install bharatstock

Then set your key (either pass it directly or, in Node, via the BHARATSTOCK_API_KEY environment variable) and call any endpoint:

import { BharatStock } from "bharatstock"; const client = new BharatStock({ apiKey: "bsk_live_yourkeyhere" }); // A single stock, with latest price + derived metrics const stock = await client.stocks.get("RELIANCE"); console.log(stock.companyName, stock.metrics?.peRatio); // Batch quotes for a watchlist (one call) for (const q of await client.stocks.quotes(["TCS", "INFY", "HDFCBANK"])) { console.log(q.symbol, q.close, q.changePct); } // Run the screener const results = await client.screener.run({ filters: ["pe_ratio.lt.15", "roe.gt.18"] }); for (const r of results.data) { console.log(r.symbol, r.peRatio, r.roe); }

The client mirrors this reference and the Python SDK's structure: client.stocks, client.deals, client.screener, client.indices, client.market, plus client.search(), client.movers(), client.priceShockers(), and client.status(). Source and full docs on npm →

Rate limits

Enforced per calendar day (UTC), per API key. Limits depend on your plan: 50/day on Free, 2,000/day on Starter, 10,000/day on Developer, 50,000/day on Pro. Every plan has access to every endpoint — the plan governs your daily request quota and how far back you can read (see Historical data depth).

{ "detail": "Daily rate limit of 50 requests exceeded for plan 'free'. Upgrade your plan for higher limits." }

Returned with HTTP status 429. The counter resets at UTC midnight.

Usage & redistribution

Your subscription grants a limited, internal-use right: you may consume the data inside your own application or workflow and display it (or analysis derived from it) to your own end-users. You may not resell, re-serve, relicense, syndicate, or bulk-redistribute the raw data to third parties as a feed, dataset, file, or API, or use it to build a competing data-distribution product.

This is strictest for exchange-sourced data (EOD prices/OHLCV, index names and values, and bulk/block deals), which is owned by the exchanges (NSE/BSE). Redistributing that data generally requires your own direct redistribution licence from the exchange — we do not grant, and cannot pass through, any such right. If you have a redistribution or white-label use case, contact us before building on it. Full terms are in the Terms of Use.

Historical data depth

Paid plans return the full archive — over a decade of daily prices, financials, corporate actions, shareholding, and more. On the Free plan the time-series endpoints return only the most recent 1 year of history (annual financials get 2 years so you can still compare year-over-year). This applies to prices, technical indicators, index prices, financials, corporate actions, shareholding, bulk/block/insider deals, and FII/DII activity.

The window is silently clamped — a Free key requesting an older from date just receives rows from within the allowed window (no error). Upgrade to any paid plan for the complete history.

MCP server

Use BharatStock as native tools inside AI assistants (Claude Desktop, Cursor, and other MCP hosts) via our official Model Context Protocol server, published on npm as bharatstock-mcp. It wraps the same data endpoints as this API, using your API key — so your plan's limits and history depth apply exactly as they do here.

MCP is a Developer/Pro feature. The server verifies your plan on startup; Free and Starter keys are declined with an upgrade prompt.

Add it to your MCP host's config (no install needed — npx fetches it on demand):

{ "mcpServers": { "bharatstock": { "command": "npx", "args": ["-y", "bharatstock-mcp"], "env": { "BHARATSTOCK_API_KEY": "bsk_live_..." } } } }

Once connected, your assistant gets ~30 tools covering the full consumer API — quotes, historical prices, financials, fundamentals, technicals, shareholding, corporate actions, bulk/block/insider deals, sector peer comparison, search, market movers, the screener, indices, FII/DII activity, and mutual-fund schemes/NAVs/returns/holdings.

Optional fields: only BHARATSTOCK_API_KEY is required. You may also set BHARATSTOCK_BASE_URL in env to point at a self-hosted/staging API (defaults to the public API). Some hosts (e.g. Kiro) also accept an autoApprove array listing tool names to run without a per-call prompt — a host-specific convenience, not part of the config the key needs.

Prefer a hosted URL (for hosts that connect to a remote MCP endpoint instead of spawning a process)? Point them at https://bharatstockapi.com/v1/mcp with an Authorization: Bearer <your key> header — same Developer/Pro requirement.

Errors

Validation errors return 422 with a structured detail array. Not-found resources return 404. Everything else follows standard HTTP status codes.

{ "error": "validation_error", "detail": [{ "loc": ["query", "limit"], "msg": "Input should be less than or equal to 200" }] }

NSE vs BSE data coverage

Every stock has an exchange field: "NSE" for stocks listed on NSE (including ones cross-listed on BSE too), or "BSE" for stocks listed only on BSE. The two data pipelines are now equivalent in coverage — quarterly and annual financials, sector/industry, daily prices and corporate actions are all populated for BSE-exclusive stocks as well. Quarterly financials come from BSE's integrated filing feed and are current to the latest reported quarter, same freshness as NSE. Sector/industry, which BSE's own security master doesn't expose, is backfilled by inference and populated for the large majority of BSE-exclusive stocks (it may be null where no reliable classification exists — best-effort, not guaranteed, same as NSE's own feed). Every stock response includes a data_coverage object stating this, so you can branch on it programmatically instead of inferring it from exchange:

NSE stock (e.g. RELIANCE)
{ "exchange": "NSE", "data_coverage": { "financials_quarterly_current": true, "financials_annual": true, "financials_quarterly_historical_only": false, "sector_industry": true, "daily_prices": true, "corporate_actions": true } }
BSE-exclusive stock (e.g. a BSE SME listing)
{ "exchange": "BSE", "data_coverage": { "financials_quarterly_current": true, "financials_annual": true, "financials_quarterly_historical_only": false, "sector_industry": true, "daily_prices": true, "corporate_actions": true } }

data_coverage is a structural statement of what the pipeline can populate for that exchange, not a live check of the database — e.g. sector_industry: true means "populated where available," not "guaranteed non-null." For NSE it comes from NSE's classification feed (which covers roughly 750 of the more liquid names); for BSE-exclusive stocks it's backfilled by inference and populated for the large majority, but may still be null where no reliable classification exists.

GET /v1/status

Public data-integrity status — no API key required. Reports whether our daily automated checks are currently passing: freshness (each feed current to its real publication cadence) and correctness (every derived value recomputed from its inputs and required to agree, e.g. P/E = price ÷ TTM EPS, adjusted close = close × factor). This is the same data behind the human-friendly status page.

Request
GET /v1/status
Response
{ "status": "operational", "summary": "All data-integrity checks passing.", "last_verified": "2026-08-31T16:15:00+00:00", "checks_total": 19, "checks_passing": 19, "checks": [{ "label": "P/E equals price ÷ TTM EPS", "category": "Correctness", "status": "operational" }] }

Values: status is operational, degraded, or unknown (not yet verified). Each check reports a plain-English label, a category (Freshness / Completeness / Correctness), and a status. Unauthenticated and safe to poll.

GET /v1/stocks

List all stocks, paginated and optionally filtered by search text or sector.

ParamTypeDescription
pageintPage number. Default 1.
page_sizeintRows per page, max 200. Default 50.
q optionalstringSearch by symbol or company name.
sector optionalstringFilter by exact sector name, e.g. "Financial Services".
active_onlyboolExclude delisted stocks. Default true.
Request
GET /v1/stocks?q=reliance&page=1&page_size=10
Response
{ "data": [ { "symbol": "RELIANCE", "isin": "INE002A01018", "company_name": "Reliance Industries Limited", "sector": "Oil Gas & Consumable Fuels", "exchange": "NSE", "is_active": true, "market_cap_rank": 1, "data_coverage": { /* see "NSE vs BSE data coverage" below */ } } ], "pagination": { "page": 1, "page_size": 10, "total_items": 1, "total_pages": 1 } }
GET /v1/stocks/{ticker}

Company info plus the latest available EOD price for a ticker.

ParamTypeDescription
exchange optionalstringNSE or BSE. Only needed to disambiguate a ticker shared by two different companies across exchanges (see note below). Defaults to the NSE listing.
Request
GET /v1/stocks/RELIANCE
Response
{ "symbol": "RELIANCE", "company_name": "Reliance Industries Limited", "sector": "Oil Gas & Consumable Fuels", "exchange": "NSE", "industry": "Petroleum Products", "face_value": 10.0, "market_cap_rank": 1, "data_coverage": { /* see "NSE vs BSE data coverage" below */ }, "latest_price": { "trade_date": "2026-08-12", "close": 1421.35, "prev_close": 1408.90, "volume": 8452110, "delivery_pct": 42.6 } }

Unknown ticker returns 404.

Shared tickers (NSE vs BSE). A few tickers belong to two different companies — one listed on NSE, the other on BSE. For example KALYANI is Kalyani Commercials Limited on NSE and Kalyani Cast-Tech Limited on BSE. By default the plain ticker returns the NSE listing:
GET /v1/stocks/KALYANI // → Kalyani Commercials (NSE)
To reach the other company, either pass ?exchange= …
GET /v1/stocks/KALYANI?exchange=BSE // → Kalyani Cast-Tech (BSE)
… or address a specific listing directly by its ISIN in the path (globally unique, never ambiguous):
GET /v1/stocks/INE0N6U01018 // → Kalyani Cast-Tech (BSE)
Both ?exchange= and ISIN lookup work on every /v1/stocks/{ticker}/… sub-endpoint (prices, financials, corporate-actions, ratios, shareholding, mf-holdings, technical-indicators). The isin and exchange of any result are in its response body.
GET /v1/stocks/{ticker}/prices

Historical daily prices, optionally bounded by date range. Includes a bonus/split-adjusted close so charts don't show a fake jump on an ex-date.

ParamTypeDescription
from optionaldateStart date, e.g. 2026-01-01.
to optionaldateEnd date.
page, page_sizeintStandard pagination, most recent first.
Request
GET /v1/stocks/RELIANCE/prices?from=2026-08-01&to=2026-08-12
Response (one row)
{ "trade_date": "2026-08-12", "open": 1410.0, "high": 1428.5, "low": 1405.2, "close": 1421.35, "volume": 8452110, "delivery_pct": 42.6, "adjusted_close": 1421.35, "adjustment_factor": 1.0 }
GET /v1/stocks/quotes

Latest price snapshot for multiple tickers in one call — built for watchlists and dashboards. Unknown symbols come back with found: false instead of failing the whole request.

ParamTypeDescription
symbolsstringComma-separated tickers, e.g. RELIANCE,TCS,INFY. Max 50.
Request
GET /v1/stocks/quotes?symbols=RELIANCE,TCS,DOESNOTEXIST
Response
[ { "symbol": "RELIANCE", "close": 1421.35, "change_pct": 0.88, "found": true }, { "symbol": "TCS", "close": 3980.1, "change_pct": -0.42, "found": true }, { "symbol": "DOESNOTEXIST", "found": false } ]
GET /v1/stocks/{ticker}/financials

Quarterly or annual P&L, balance sheet, and cash flow, normalized from official company financial disclosures — including bank/NBFC statement formats and consolidated-vs-standalone reporting. Annual rows also expose other_equity (Ind-AS reserves + retained earnings, for the Altman Z-score) and capex (purchase of PPE + intangibles, so Free Cash Flow = cash_flow_operating − capex).

ParamTypeDescription
period_typestringquarterly or annual. Default quarterly.
page, page_sizeintStandard pagination, most recent period first.
Request
GET /v1/stocks/RELIANCE/financials?period_type=annual
Response (one row)
{ "period_type": "annual", "fiscal_year": "FY25", "period_end_date": "2025-03-31", "revenue": 964693.0, "net_profit": 79020.0, "eps": 58.6, "net_profit_attributable_to_minority_interest": 6821.0, "other_equity": 1057071.0, "cash_flow_operating": 192113.0, "capex": 128000.0, "consolidation_type": "consolidated" }
GET /v1/stocks/{ticker}/ratios

Valuation and profitability ratios, computed on read from the latest price and the latest annual filing (falling back to quarterly if no annual filing exists yet).

Request
GET /v1/stocks/RELIANCE/ratios
Response
{ "as_of_date": "2026-08-12", "price": 1421.35, "pe_ratio": 24.3, "pb_ratio": 2.1, "roe": 8.9, "roce": 10.4, "dividend_yield": 0.35, "week_52_high": 1551.0, "week_52_low": 1201.6, "financials_period_type": "annual", "financials_fiscal_year": "FY25" }
GET /v1/stocks/{ticker}/technical-indicators

SMA, EMA, RSI, and MACD, computed server-side from daily closes. Values are null wherever there isn't enough price history yet to compute them.

ParamTypeDescription
sma_periodintDefault 20.
ema_periodintDefault 20.
rsi_periodintDefault 14 (Wilder's smoothing).
from, to optionaldateBound the returned window.
Request
GET /v1/stocks/RELIANCE/technical-indicators?sma_period=20&rsi_period=14
Response (one row)
{ "trade_date": "2026-08-12", "close": 1421.35, "sma": 1398.42, "ema": 1405.11, "rsi": 58.3, "macd": 6.2, "macd_signal": 4.8, "macd_histogram": 1.4 }
GET /v1/stocks/{ticker}/corporate-actions

Dividends, bonus issues, splits, and rights issues for a ticker, most recent ex-date first.

ParamTypeDescription
action_type optionalstringdividend, bonus, split, rights, buyback, or other.
Request
GET /v1/stocks/RELIANCE/corporate-actions?action_type=bonus
Response (one row)
{ "action_type": "bonus", "subject": "Bonus issue 1:1", "ex_date": "2024-10-28", "ratio_from": 1, "ratio_to": 1, "source": "nse_corporate_actions" }
GET /v1/stocks/{ticker}/shareholding

Quarterly shareholding pattern (promoter / public / employee-trust split, with FII/DII/mutual-fund sub-splits where the filing reports them).

Request
GET /v1/stocks/RELIANCE/shareholding
Response (one row)
{ "as_on_date": "2026-06-30", "promoter_pct": 50.48, "public_pct": 49.52, "employee_trust_pct": 0.0, "source": "nse_shareholding_pattern" }
GET /v1/stocks/{ticker}/mf-holdings

Monthly mutual fund holdings — which MF schemes hold this stock, their position size in crores, percentage of AUM, and month-over-month quantity change. Paginated, sorted by market value descending.

Source: compiled from the fund houses' own official monthly portfolio disclosures — pulled directly from 44+ AMCs' sites (first-party) for the houses we cover, with an aggregator filling any remaining houses. First-party AMC data is authoritative where available.

ParamTypeDescription
pageintPage number (default 1).
page_sizeintItems per page, 1-100 (default 20).
monthstringOptional. Filter by month in YYYY-MM format (e.g. 2026-06). Defaults to latest available.
Request
GET /v1/stocks/RELIANCE/mf-holdings?page=1&page_size=5
Response
{ "data": [ { "portfolio_date": "2026-06-01", "fund_house": "Nippon India Mutual Fund", "scheme_name": "Nippon India ETF Nifty 50 BeES", "quantity": 3987200, "market_value_cr": 5162.80, "pct_of_aum": 7.97, "quantity_change": 125000 } ], "pagination": { "page": 1, "page_size": 5, "total_items": 302, "total_pages": 61 } }
GET /v1/stocks/compare

Compare valuation and profitability ratios across every active stock in a sector — computed in bulk rather than looping the single-ticker ratios endpoint.

ParamTypeDescription
sectorstringExact sector name, e.g. "Financial Services".
sortstringmarket_cap, pe_ratio, pb_ratio, roe, or roce. Default market_cap.
limitintMax 100. Default 20.
Request
GET /v1/stocks/compare?sector=Financial Services&sort=pe_ratio&limit=5
Response (one row)
{ "symbol": "AAVAS", "company_name": "Aavas Financiers Limited", "sector": "Financial Services", "price": 1711.7, "pe_ratio": 27.8, "roe": 14.2 }
GET /v1/stocks/{ticker}/bulk-deals

Bulk deals for a ticker — single-day trades where one client traded more than 0.5% of the company's listed equity. Most recent first.

ParamTypeDescription
buy_sellstringOptional. Filter by BUY or SELL only.
pageintDefault 1.
page_sizeintMax 200. Default 50.
exchangestringOptional. NSE or BSE to disambiguate shared tickers.
Request
GET /v1/stocks/RELIANCE/bulk-deals?page=1&page_size=10
Response (one row)
{ "deal_date": "2026-08-20", "client_name": "ALPHA FUND PVT LTD", "buy_sell": "BUY", "quantity": 500000, "avg_price": 2850.75 }
GET /v1/stocks/{ticker}/block-deals

Block deals for a ticker — large trades executed in the exchange's dedicated block-deal window (minimum ticket size ~₹10 Cr). Same parameters and shape as bulk deals.

ParamTypeDescription
buy_sellstringOptional. BUY or SELL.
pageintDefault 1.
page_sizeintMax 200. Default 50.
exchangestringOptional. NSE or BSE.
Request
GET /v1/stocks/TCS/block-deals?buy_sell=BUY
GET /v1/stocks/{ticker}/insider-trades

Insider / promoter (SEBI PIT) disclosures for a ticker — filed when promoters, directors, or KMPs buy or sell above the regulatory threshold. Strong "smart money" signal.

ParamTypeDescription
transaction_typestringOptional. acquisition or disposal.
promoters_onlyboolOptional. true to see only promoter/promoter-group disclosures.
pageintDefault 1.
page_sizeintMax 200. Default 50.
exchangestringOptional. NSE or BSE.
Request
GET /v1/stocks/BAJAJFINSV/insider-trades?promoters_only=true
Response (one row)
{ "acquirer_name": "Bajaj Holdings & Investment Limited", "person_category": "Promoters", "is_promoter": true, "transaction_type": "acquisition", "quantity": 2090050, "value": 3700224520, "shares_after_pct": 38.41, "mode": "Market Purchase", "intimation_date": "2026-04-29" }
GET /v1/deals/bulk

Recent bulk deals across all stocks, most recent first. Includes symbol and company_name in each row. Cached.

ParamTypeDescription
buy_sellstringOptional. BUY or SELL.
pageintDefault 1.
page_sizeintMax 200. Default 50.
Request
GET /v1/deals/bulk?page=1&page_size=5&buy_sell=BUY
Response (one row)
{ "symbol": "AARTECH", "company_name": "Aartech Solonics Limited", "deal_date": "2026-08-20", "client_name": "KABRA KAILASH", "buy_sell": "BUY", "quantity": 1155, "avg_price": 50.21 }
GET /v1/deals/block

Recent block deals across all stocks, most recent first. Same response shape as /v1/deals/bulk.

ParamTypeDescription
buy_sellstringOptional. BUY or SELL.
pageintDefault 1.
page_sizeintMax 200. Default 50.
Request
GET /v1/deals/block?page=1&page_size=10
Response (one row)
{ "symbol": "KFINTECH", "company_name": "Kfin Technologies Limited", "deal_date": "2026-08-20", "client_name": "BANDHAN MUTUAL FUND", "buy_sell": "BUY", "quantity": 518919, "avg_price": 925.0 }
GET /v1/insider-trades

Recent insider/promoter disclosures across all stocks. Includes symbol, company_name, and all fields from the per-ticker endpoint. Useful for scanning "who's been buying" market-wide.

ParamTypeDescription
transaction_typestringOptional. acquisition or disposal.
promoters_onlyboolOptional. true for promoter-only.
pageintDefault 1.
page_sizeintMax 200. Default 50.
Request
GET /v1/insider-trades?promoters_only=true&page=1&page_size=5
Response (one row)
{ "symbol": "BAJAJFINSV", "company_name": "Bajaj Finserv Limited", "acquirer_name": "Bajaj Holdings & Investment Limited", "person_category": "Promoters", "is_promoter": true, "transaction_type": "acquisition", "quantity": 2090050, "value": 3700224520, "shares_after_pct": 38.41, "mode": "Market Purchase", "intimation_date": "2026-04-29" }
GET /v1/movers

Top gainers, losers, or most-active-by-volume stocks for the most recent trading day with price data. Uses the latest date present in the data, not today's calendar date, so it stays correct on weekends and holidays.

ParamTypeDescription
categorystringgainers, losers, or active. Default gainers.
limitintMax 100. Default 20.
Request
GET /v1/movers?category=gainers&limit=5
Response (one row)
{ "symbol": "SWARAJ", "company_name": "Swaraj Engines Limited", "trade_date": "2026-08-12", "close": 2840.0, "prev_close": 2607.5, "change_pct": 8.92, "volume": 312440 }
GET /v1/price-shockers

Stocks whose price moved by at least a given percent versus the previous close. Unlike /movers (always a top-N ranking), this is a threshold filter — it can return zero rows on a quiet day, or more than limit on a volatile one.

ParamTypeDescription
min_change_pctfloatMinimum absolute % move. Default 5.0.
directionstringup, down, or both. Default both.
limitintMax 200. Default 50.
Request
GET /v1/price-shockers?min_change_pct=5&direction=both
Response (one row)
{ "symbol": "SWARAJ", "company_name": "Swaraj Engines Limited", "trade_date": "2026-08-12", "close": 2840.0, "prev_close": 2607.5, "change_pct": 8.92, "volume": 312440 }
GET /v1/screener

Filter and screen stocks by 72 pre-computed metrics (refreshed daily) using a generic filter syntax. Combine as many filters as needed. Returns paginated results sorted by any metric.

Pagination & sorting

ParamTypeDescription
page optionalintPage number. Default 1.
page_size optionalintResults per page, 1-200. Default 50.
sort_by optionalstringAny metric name (e.g. market_cap, pe_ratio, roe, return_1y, free_cash_flow). Default: market_cap.
sort_order optionalstringdesc or asc. Default: desc.

Filtering (generic syntax)

ParamTypeDescription
filter repeatablestringFormat: metric.operator.value. Pass multiple filter params to combine conditions (AND logic).
sector optionalstringSector name (exact match), e.g. "Information Technology".
exchange optionalstringNSE or BSE.

Operators

OperatorMeaningExample
gtGreater than (>)filter=roe.gt.15
ltLess than (<)filter=pe_ratio.lt.20
gteGreater than or equal (≥)filter=promoter_holding.gte.50
lteLess than or equal (≤)filter=debt_to_equity.lte.1
eqEquals (=)filter=current_ratio.eq.2
Request
GET /v1/screener?filter=pe_ratio.lt.15&filter=roe.gt.12&filter=debt_to_equity.lt.1&filter=fii_holding.gt.10&filter=market_cap.gt.10000&sort_by=market_cap
Response (one row, abbreviated)
{ "symbol": "ONGC", "company_name": "Oil and Natural Gas Corporation Limited", "sector": "Oil Gas & Consumable Fuels", "exchange": "NSE", "price": 262.50, "market_cap": 330120.45, "pe_ratio": 7.8, "pb_ratio": 1.2, "roe": 18.5, "roce": 22.1, "earnings_yield": 12.82, "peg_ratio": 0.41, "ev_to_ebitda": 4.5, "price_to_sales": 0.52, "return_1w": 1.2, "return_1m": 4.2, "return_1y": 15.3, "return_5y": 85.6, "volatility_30d": 1.85, "price_vs_200dma_pct": -5.2, "debt_to_equity": 0.45, "current_ratio": 1.8, "interest_coverage": 8.2, "free_cash_flow": 45200000000.0, "ebitda_margin": 32.5, "revenue_growth_yoy": 12.4, "eps_growth_yoy": 22.1, "promoter_holding": 58.89, "fii_holding": 18.5, "dii_holding": 12.3, "mutual_funds_holding": 6.8, "computed_at": "2026-08-15" }

Note: Response includes 72 metrics per stock. market_cap in the response is in Crores; filter=market_cap.gt.10000 also expects Crores. Metrics are refreshed daily at 9pm IST. Stocks with NULL for a filtered metric are excluded from that filter.

All 72 filterable & sortable metrics

CategoryMetrics
Priceprice, high_52w, low_52w, distance_from_52w_high_pct, distance_from_52w_low_pct, avg_volume_30d, avg_delivery_pct_30d, avg_turnover_30d, price_vs_200dma_pct, price_vs_50dma_pct
Returnsreturn_1w, return_1m, return_3m, return_6m, return_1y, return_2y, return_3y, return_5y
Volatilityvolatility_30d, volatility_365d
Valuationmarket_cap, pe_ratio, pb_ratio, book_value_per_share, roe, roce, dividend_yield, earnings_yield, peg_ratio, ev_to_ebitda, enterprise_value, price_to_sales, shares_outstanding
Per-shareeps, diluted_eps, cash_per_share, revenue_per_share
Marginsoperating_margin, net_margin, ebitda_margin
Absolute financialsebitda, revenue_ttm, net_profit_ttm
Growthrevenue_growth_yoy, profit_growth_yoy, eps_growth_yoy, revenue_growth_qoq, net_profit_margin_qoq_change
Balance sheetdebt_to_equity, current_ratio, interest_coverage, total_debt, working_capital, asset_turnover, inventory_turnover, receivables_days, payables_days
Cash flowcash_flow_operating, free_cash_flow, cfo_to_net_profit
Tax & depreciationtax_rate, depreciation_to_revenue
Shareholdingpromoter_holding, promoter_holding_change_qoq, fii_holding, dii_holding, mutual_funds_holding, public_holding, individuals_holding, fii_holding_change_qoq, dii_holding_change_qoq, mutual_funds_holding_change_qoq, total_shares

Every metric above supports _gt and _lt filter suffixes. For example: pe_ratio_lt=15, fii_holding_gt=10, debt_to_equity_lt=1, return_5y_gt=100. Combine as many as needed.

GET /v1/market/fii-dii

Daily aggregate FII/DII cash market activity — buy, sell, and net values in ₹ Crores. Market-wide aggregate (not per-stock). Sorted by date descending.

ParamTypeDescription
from optionaldateStart date (YYYY-MM-DD). Default: 30 days ago.
to optionaldateEnd date (YYYY-MM-DD). Default: today.
limit optionalintMax rows (1-365). Default: 30.
latest optionalboolIf true, return only the single most recent day (ignores from/to/limit).
Request
GET /v1/market/fii-dii?from=2026-08-01&to=2026-08-17 GET /v1/market/fii-dii?latest=true
Response
{ "from": "2026-08-01", "to": "2026-08-17", "count": 12, "data": [{ "date": "2026-08-17", "fii_buy": 12456.78, "fii_sell": 10234.56, "fii_net": 2222.22, "dii_buy": 8765.43, "dii_sell": 9012.34, "dii_net": -246.91 }] }

Note: Values are in ₹ Crores. Positive fii_net/dii_net = net buying. Published after market close each trading day.

GET /v1/mf/schemes

List / search mutual-fund schemes across every AMC (the industry-wide AMFI NAV universe). Each row is one AMFI scheme_code — a (scheme, plan, option) variant with its own NAV. Distinct from /v1/stocks/{ticker}/mf-holdings (which schemes hold a given stock).

Source: the scheme universe and daily NAVs come from AMFI's official industry-wide NAV feed, updated every evening — with NAV history back to 2006 (~20 years).

ParamTypeDescription
q optionalstringCase-insensitive substring match on scheme name.
amc optionalstringFilter by AMC name (substring).
category optionalstringFilter by AMFI category (substring), e.g. Flexi Cap.
plan optionalstringDirect or Regular (substring).
option optionalstringGrowth or IDCW (substring).
isin optionalstringExact match on either ISIN (growth or div-reinvest).
limit optionalintMax rows (1-500). Default: 50.
offset optionalintRows to skip (pagination). Default: 0.
Request
GET /v1/mf/schemes?category=Flexi%20Cap&plan=Direct&option=Growth
Response
{ "count": 1, "total": 1, "limit": 50, "offset": 0, "data": [{ "scheme_code": "120503", "scheme_name": "Axis Flexi Cap Fund", "amc_name": "Axis Mutual Fund", "category": "Open Ended Schemes(Equity Scheme - Flexi Cap Fund)", "plan": "Direct Plan", "option": "Growth", "isin_growth": "INF846K01EW2", "isin_div_reinvest": null }] }
GET /v1/mf/schemes/{scheme_code}

One scheme's identity plus its latest NAV (with the as-of date). The path value is the AMFI scheme_code from the list endpoint.

Request
GET /v1/mf/schemes/120503
Response
{ "scheme_code": "120503", "scheme_name": "Axis Flexi Cap Fund", "amc_name": "Axis Mutual Fund", "category": "Open Ended Schemes(Equity Scheme - Flexi Cap Fund)", "plan": "Direct Plan", "option": "Growth", "latest_nav": 29.587, "latest_nav_date": "2026-09-16" }
GET /v1/mf/schemes/{scheme_code}/nav

Daily NAV history for one scheme, most recent first. NAVs are sourced from AMFI's official daily feed, with history back to 2006 (~20 years) for schemes that existed then.

ParamTypeDescription
from optionaldateStart date (YYYY-MM-DD). Default: 1 year ago.
to optionaldateEnd date (YYYY-MM-DD). Default: today.
limit optionalintMax NAV points (1-5000). Default: 400.
Request
GET /v1/mf/schemes/120503/nav?from=2024-01-01&to=2024-12-31
Response
{ "scheme_code": "120503", "scheme_name": "Axis Flexi Cap Fund", "from": "2024-01-01", "to": "2024-12-31", "count": 248, "data": [{ "date": "2024-12-31", "nav": 24.813 }] }

Free tier: NAV history is limited to a recent window; paid plans return the full archive.

GET /v1/mf/schemes/{scheme_code}/returns

Trailing returns computed from the scheme's NAV series (sourced from AMFI's daily feed). Sub-1-year horizons are point-to-point; 1Y and longer are annualized (CAGR). Always derived from the raw NAV — never precomputed — so they can't drift from the underlying series. Horizons without enough history are null.

Request
GET /v1/mf/schemes/120503/returns
Response
{ "scheme_code": "120503", "scheme_name": "Axis Flexi Cap Fund", "as_of": "2026-09-16", "latest_nav": 29.587, "inception_date": "2020-01-01", "returns_pct": { "1m": 2.51, "3m": 7.84, "6m": 11.02, "1y": 18.34, "3y": 15.12, "5y": 14.05, "since_inception": 12.67 } }

Note: Percentages. For 1Y and longer the value is annualized (CAGR); for shorter horizons it's the simple point-to-point change.

GET /v1/indices

List all tracked NSE indices, paginated and optionally filtered by category (e.g. broad-market vs. sectoral).

ParamTypeDescription
category optionalstringe.g. "BROAD MARKET INDICES", "SECTORAL INDICES".
Request
GET /v1/indices?category=BROAD MARKET INDICES
Response (one row)
{ "name": "NIFTY 50", "category": "BROAD MARKET INDICES", "is_active": true }
GET /v1/indices/{name}/prices

Historical daily EOD levels for an index, optionally bounded by date range.

Request
GET /v1/indices/NIFTY 50/prices?from=2026-08-01
Response (one row)
{ "trade_date": "2026-08-12", "open": 24580.2, "high": 24710.9, "low": 24540.0, "close": 24695.4 }

Changelog

Notable changes to the official SDKs (Python bharatstock on PyPI, JavaScript/TypeScript bharatstock on npm). The SDKs track the API surface; the REST API itself is additive and backward compatible.

Python SDK

  • 0.1.7 (2026-09-15) — Added a Changelog project link and this changelog page. Metadata only; no code change.
  • 0.1.6 (2026-09-15) — Packaging metadata: CHANGELOG.md shipped in the sdist. No code change.
  • 0.1.5 (2026-09-15) — Documentation refresh for the Mutual Funds resource (fully documented, runnable examples). No code change.
  • 0.1.4 — Added the MutualFunds resource: list/search schemes, scheme detail + latest NAV, daily NAV history (~20 years), and trailing returns (1m/3m/6m/1y/3y/5y/since-inception).

JavaScript / TypeScript SDK

  • 0.1.8 (2026-09-15) — Added a "Jump to Changelog" link and this changelog page. Metadata only; no code change.
  • 0.1.7 (2026-09-15) — Shipped a standalone CHANGELOG.md. No code change.
  • 0.1.6 (2026-09-15) — Documentation refresh for the mutualFunds resource. No code change.
  • 0.1.5 — Added the mutualFunds resource: listSchemes, getScheme, nav, returns, mirroring the Python SDK.

Full per-release notes also ship inside each package (README changelog + CHANGELOG.md).