Two files, and why they are not one file
They hold different kinds of fact and merging them would destroy one of them.
fundamentals.jsonl is append-only. BSE's
resultsSnapshot endpoint only ever returns three periods — the latest quarter,
the one before it, and the latest full year. Nothing on BSE gives you the fourth. So the
accumulated file is the long series: each monthly sweep adds the periods that have
appeared since, and existing rows are never touched. Overwrite it and you destroy the only
thing here that compounds, and no re-run can rebuild it.
snapshot.jsonl is the opposite. Price, market cap, PE, PB and
ROE are true only of the moment they were read, so every sweep writes a new row and the old
ones stay as a record of what BSE said then.
Every record in both files carries a schema_version and a
source naming the endpoint it came from. There is no record without provenance.
fundamentals.jsonl
/data/fundamentals.jsonl —
14,700 rows,
4,955 companies,
4,378 KB. Keyed (scrip, period). Append-only. Refreshed
monthly.
| Field | Meaning |
|---|---|
| scrip | BSE scripcode. The join key across every file here. |
| isin | The only identifier that joins BSE to NSE. |
| period | Jun-26 for a quarter, FY25-26 for a full year — BSE's own labels, unaltered. |
| period_type | quarter or year. |
| currency_unit | Stated, not normalised. BSE returns the same figures in crore and in millions; this file takes crore and says so. |
| revenue, net_profit | In currency_unit. Negative net profit is a loss and is kept as a negative number. |
| eps, cash_eps | Rupees per share. |
| opm_pct, npm_pct | Operating and net margin, per cent. |
| source | bse.resultsSnapshot. |
| captured_at | The date this row was read from BSE. |
| schema_version | Currently 1. |
snapshot.jsonl
/data/snapshot.jsonl —
5,035 rows,
5,035 companies,
2,502 KB. Keyed (scrip, capture_date). One row per company
per sweep. Refreshed monthly.
| Field | Meaning |
|---|---|
| scrip, isin | Identity, as above. |
| capture_date | The date the row was read. Half the key. |
| price, day_change_pct | Last traded price and the move against the previous close. |
| mktcap_full, mktcap_ff | Full and free-float market capitalisation, in rupees crore. |
| cap_band | Large / Mid / Small / Micro / Unknown. Unknown is the absence of a market cap, not the smallest one. |
| pe, pb, roe, opm_pct, npm_pct, eps | BSE's published standalone ratios. |
| face_value, bse_group | Face value in rupees; BSE's trading group. |
| index_membership | Array of index names, from the NSE constituent lists joined on ISIN. |
| week52_high, week52_low | 52-week range. |
| listing_status | Active, Suspended or Delisted. |
| source | Comma-separated list of the endpoints the row was assembled from. |
| schema_version | Currently 1. |
The aggregate files
Three integer-indexed files covering the published window, rebuilt every night. They are what /atlas/ and /analysis/ both read, so those two pages cannot disagree about a number.
- facts.json —
day, sector, tag, count. - company.json —
company, tag, count. - dims.json — what those integers mean, plus the window they cover and the exact encoding rule.
They are stored as columns rather than rows and the first column is
delta-encoded; dims.json states the rule under encoding.
What the figures are, and are not
These are BSE's published values as of the capture date on each row. They
are not live, they are not ours, and nothing here is calculated by us — a figure is either
transcribed from the endpoint named in source or it is absent. Where BSE
publishes nothing, the field is null rather than zero, because an absent value and
a zero are different facts.
The site reports these numbers and never ranks on them. The front page's selection takes no PE, no margin and no return as an input, deliberately. Transcribing an exchange's published figure is reporting; ordering a page by it is analysis, and this site is not a registered research analyst. Publishing a screenable dataset does not make the desk a screener.
Licence
Placeholder — not yet legal text
This wording has not been settled and must not be relied on. It is a marker for terms Vivek's lawyer will draft, kept here because a dataset with no stated licence is unusable by anyone cautious — including us, in two years, when nobody remembers what was intended.
What the terms need to settle, at minimum:
- Whether these files may be redistributed, and under what attribution.
- Whether commercial use is permitted, and whether that differs from academic or personal use.
- What is claimed over the compilation as against the underlying figures, which originate with BSE and with the issuers themselves.
- What downstream obligations follow from BSE's own website policy, which governs the source these figures were read from.
- Whether any warranty is offered. It is not intended that one is.
Until this section is replaced with drafted terms, treat the files as all rights reserved and ask before redistributing.
Cadence and stability
/data/fundamentals.jsonl— monthly, append-only. Rows are never rewritten./data/snapshot.jsonl— monthly, one new row per company per sweep./data/agg/*.json— nightly, rebuilt in full each time./data/tearsheet.json— nightly. A compact per-company view the drawer reads; derived entirely from the two datasets above and not a source of its own.
The URLs above are intended to be stable. If a schema changes in a way that
would break a reader, schema_version increments and this page says what moved.