bharatstock
v0.1.8
Published
Official JavaScript/TypeScript client for the BharatStock API - reliable Indian stock market data (NSE/BSE).
Maintainers
Readme
BharatStock JavaScript/TypeScript Client
Official JS/TS client for the BharatStock API — reliable Indian stock market data (NSE/BSE): EOD prices, quarterly/annual financials, shareholding patterns, corporate actions, derived per-stock metrics, a screener, bulk/block deals, insider trades, indices, and market-wide FII/DII activity.
Works in Node.js 20+ (native fetch) and modern browsers/edge runtimes.
Ships both ESM and CommonJS builds, plus TypeScript types.
📋 Jump to Changelog — what's new in each release.
Install
npm install bharatstockTo work on the client from a checkout of this repo:
cd sdk/js
npm install
npm run buildAuthentication
Every data endpoint is authenticated with your bsk_live_... key, sent in
the X-API-Key header. Get one from the
dashboard.
import { BharatStock } from "bharatstock";
// Pass the key explicitly...
const client = new BharatStock({ apiKey: "bsk_live_..." });
// ...or (Node only) set BHARATSTOCK_API_KEY in the environment and omit it:
const client2 = new BharatStock();Quickstart
import { BharatStock } from "bharatstock";
const client = new BharatStock({ apiKey: "bsk_live_..." });
// A single stock, with latest price + ~70 derived metrics
const stock = await client.stocks.get("RELIANCE");
console.log(stock.companyName, stock.exchange);
console.log("P/E:", stock.metrics?.peRatio, "ROE:", stock.metrics?.roe);
// Batch quotes for a watchlist (one call, up to 50 symbols)
for (const q of await client.stocks.quotes(["TCS", "INFY", "HDFCBANK"])) {
console.log(q.symbol, q.close, q.changePct);
}
// Search
for (const hit of await client.search("tata")) {
console.log(hit.symbol, hit.companyName);
}
// Public data-integrity status (no key required)
console.log((await client.status()).status); // "operational" | "degraded"Pagination
Paginated endpoints return a Page<T>:
const page = await client.stocks.prices("RELIANCE", { pageSize: 100 });
console.log(page.data.length, page.totalPages);Or iterate every page lazily:
for await (const stock of client.stocks.iterAll({ sector: "Banking" })) {
console.log(stock.symbol);
}Screener
const results = await client.screener.run({
filters: ["pe_ratio.lt.15", "roe.gt.18"], // metric.operator.value
sector: "Banking",
sortBy: "market_cap",
});Mutual funds
The industry-wide AMFI scheme NAV dataset — every scheme/plan/option across
all AMCs, keyed by AMFI schemeCode (distinct from stocks.mfHoldings,
which is which schemes hold a given stock).
// Search schemes
const schemes = await client.mutualFunds.listSchemes({
category: "Flexi Cap",
plan: "Direct",
option: "Growth",
});
// One scheme + latest NAV
const scheme = await client.mutualFunds.getScheme("120503");
console.log(scheme.latestNav, scheme.latestNavDate);
// NAV history (paid keys: full archive; free keys: recent window)
const nav = await client.mutualFunds.nav("120503", { fromDate: "2024-01-01" });
// Trailing returns computed from the NAV series (CAGR for >=1y)
const ret = await client.mutualFunds.returns("120503");
console.log(ret.returnsPct["1y"], ret.returnsPct.sinceInception);Error handling
Every error the client throws is a BharatStockError, with more specific
subclasses:
import { BharatStockError, RateLimitError, NotFoundError } from "bharatstock";
try {
await client.stocks.get("NOPE");
} catch (err) {
if (err instanceof NotFoundError) {
// ticker doesn't exist
} else if (err instanceof RateLimitError) {
// daily request limit hit -- err.statusCode === 429
} else if (err instanceof BharatStockError) {
console.error(err.message, err.statusCode, err.detail);
}
}HTTP 429 (rate limit) is automatically retried with exponential backoff
(maxRetries, default 3) before RateLimitError is thrown — the API does
not send Retry-After, so the wait schedule is entirely client-side.
Configuration
new BharatStock({
apiKey: "bsk_live_...",
baseUrl: "https://bharatstockapi.com", // override for testing
timeoutMs: 30_000,
maxRetries: 3,
backoffFactor: 0.5,
fetchImpl: myCustomFetch, // inject a custom fetch (advanced/testing)
});Development
cd sdk/js
npm install
npm run typecheck
npm test
npm run buildTests use a mocked fetchImpl — nothing hits the network.
Changelog
- 0.1.8 (2026-09-15): Docs only — added a "Jump to Changelog" link at the top of this README. No code, API, or behavior changes.
- 0.1.7 (2026-09-15): Packaging metadata only — added a standalone
CHANGELOG.md. No code, API, or behavior changes. - 0.1.6 (2026-09-15): Documentation and metadata refresh for the Mutual
Funds surface — no code or behavior changes, fully backward compatible.
The
mutualFundsresource is now completely documented with runnable TypeScript examples: list and search the full universe of AMFI schemes (client.mutualFunds.listSchemes({ q, amc, plan, option, category })), fetch a single scheme's identity and latest NAV (client.mutualFunds.getScheme(schemeCode)), pull its daily NAV time series going back as far as ~20 years for backtesting and SIP/rolling-return analysis (client.mutualFunds.nav(schemeCode, { fromDate, toDate, limit }), server-side capped at 5000 points per call — page withfromDate/toDate), and read trailing returns computed from that NAV series (client.mutualFunds.returns(schemeCode)→1m/3m/6m/1y/3y/5y/sinceInception, where ≥1-year horizons are annualized CAGR). Fully typed responses (MFScheme,MFSchemeReturns, and the scheme-list / NAV-history interfaces). Free-tier keys are limited to ~1 year of NAV history; paid tiers get the full archive. - 0.1.5: Added the
mutualFundsresource (client.mutualFunds) — the first release with mutual fund coverage. IntroducedlistSchemes(),getScheme(),nav()andreturns()plus their TypeScript response interfaces, backed by the AMFI industry-wide daily NAV feed and the returns endpoint (1m/3m/6m/1y/3y/5y/since-inception). No breaking changes to the existing stocks / deals / screener / indices / market resources.
License
MIT
