Parameters, response columns and types are generated from the SQL catalog and
render under Endpoints → Quotes in the sidebar. This page carries what a
schema cannot: the conventions, the nulls that are deliberate, and the traps.
Overview
B3 COTAHIST cash-market prints (tpmerc = 010), exactly as published. Nothing is split- or dividend-adjusted, and every row carries adjusted: false.
The grain is (ticker, trade_date, board, term_days). A ticker can print on more than one board on the same day, so a query that does not pin board can return several rows per session. codbdi varies by instrument type (02 common equities, 12 FIIs, 14 ETFs, 34 BDRs). quote_history follows the instrument (its ISIN) across boards unless you pass one; quote_latest reads every board.
asset_class is derived conservatively from B3’s published tpmerc and especi: equity, unit, bdr, fund_quota, index, right, bonus, or cash_security. To split fund_quota into ETF vs FII vs FIAGRO, use fund_quotas’ fund_type column, which comes from B3’s published CODBDI board code.
GET /quotes
The view — full column set, arbitrary filters and sort. Use it for cross-sectional slices (a whole session, a set of tickers) rather than one instrument’s series.
POST /rpc/quote_history
One ticker’s daily series over a window, ordered by trade_date ascending, one JSON object per session holding only the fields you select.
ticker, trade_date, close_adj. close_adj is the close per single share, backward-adjusted for splits (DESDOBRAMENTO), groupings (GRUPAMENTO) and bonus shares (BONIFICACAO) by B3’s rule (1 + factor/100 for splits and bonuses, factor for groupings, events on one date multiplied), anchored to the instrument’s latest session and rounded to 6 decimal places. Past levels change when an event lands; returns do not. Dividends, JCP and subscription rights are not adjusted: they move value to holders and change no share count, so they belong to a total-return series, not this one. Shares (ISIN code ACN) and units (CDA/UNT, ticker ending 11) only.
The raw close is an explicit selection: p_fields: ["close"], or any of open, high, low, average, bid, ask, close_unit, trades, quantity, volume, quotation_factor, board, isin, short_name, spec, currency, asset_class, source, coverage_start, coverage_end, prior_no_trade_sessions, events_proven_at, data_revision (types in catalog().defaults.quote_history.available). Keep the same p_fields on every page.
Additional preserved fields are opt-in: market, term_days, contract_price,
contract_expiry, contract_correction, contract_points, contract_points_raw,
distribution_number and fetched_at. The last is warehouse time, not original
publication time. See catalog().cotahist for the source aliases and dated code
reference. No change to the default adjusted-price selection.
BRVIIAACNOR7 until 2023-09-19, then BHIA3 BRBHIAACNOR1 from 2023-09-20), a window that reaches back runs through the older instrument. Each row keeps its own ticker and isin, close_adj stays continuous across the seam, and close_total_return is null before it. The splice needs the same company in CVM’s FCA, the same share class, adjacent sessions with no overlap, no stock event at the seam and exactly one candidate (docs/adr/0002-ticker-activity-and-lineage.md); otherwise the window is refused.
What it refuses (22023, with details starting reason=) rather than serve a partial or substituted series:
Inside the coverage a missing session is a session with no trade (COTAHIST lists only papers that traded;
prior_no_trade_sessions counts them) and holidays are not sessions. A field with no value is a JSON null.
Data revision. Every response carries the header X-Silo-Data-Revision (and the data_revision field when selected): the newest load of the tape, the corporate events or their proof. close_adj levels move when it changes, so never combine pages or calls with different revisions; the SDK restarts instead.
POST /rpc/quote_latest
The most recent stored session for one ticker. At most one row, same columns as quote_history.
p_board null means “latest across all boards”.
trade_date on the row and coverage for the dataset. A stale close is never advanced to today’s date to make it look current.
Empty and error behavior
- Unknown ticker →
200 []. Not a 404, and never a fabricated last close. - Known ticker, no sessions in the window (a holiday range, or a window before the paper listed) → also
200 []. The two cases are indistinguishable from the response; uselookupto confirm the ticker exists. - Wrong board is a common cause of a surprising empty result. Some papers do not print on
02— retry with"p_board": null. - A malformed date or filter returns
400.