> ## Documentation Index
> Fetch the complete documentation index at: https://octo-98895abd.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Data inventory

> What we ingest, what we don't, and what we hold but don't serve.

The warehouse in three lists: [what we ingest](#1-what-we-ingest), [what we don't](#2-what-we-could-ingest-and-dont), [what we hold but don't serve](#3-what-we-ingest-and-dont-serve), then [how it is served](#4-how-it-is-served). Coverage figures are as of 2026-08-31. Full audit: [`docs/reference/DATA_INVENTORY.md`](https://github.com/PedroDnT/SILO-BZ/blob/main/docs/DATA_INVENTORY.md). Live gap register: [`docs/reference/DATABASE_MAINTENANCE.md`](https://github.com/PedroDnT/SILO-BZ/blob/main/docs/DATABASE_MAINTENANCE.md) §11.

### 1. What we ingest

Sources are CVM, B3, BACEN, IBGE and ANBIMA, all public except the ETF market feed.

#### CVM funds (`dados.cvm.gov.br`)

| Family | Table | Grain | Source shape | From |
| - | - | - | - | - |
| FI | `cvm_fi_diario` | fund × **day** | monthly ZIP 2021+, yearly HIST ≤2020 | 2019 (partition floor) |
| FI | `cvm_fi_perfil` | fund × month | monthly CSV | 2019 |
| FI | `cvm_fi_extrato` | fund or class × filed version (`DT_COMPTC`) | current CSV, daily; yearly CSV 2021+ | 2021 |
| FI | `cvm_fi_lamina` | fund or class × month × optional subclass | monthly ZIP | 2019 |
| FI | `cvm_fi_balancete` | fund × month × account | monthly ZIP | 2019 |
| FI | `cvm_fi_cda` | fund × month × asset **class** | monthly 2023+, yearly HIST ≤2022 | 2005 |
| FI | `cvm_fi_cda_acoes` | fund × month × class × **ticker** | CDA block 4 | 2005 |
| FI | `cvm_fi_cda_cotas` | fund × month × **held fund** | CDA block 2 | 2005 |
| FI | `cvm_fi_cda_debentures` | fund × month × **issuer** × maturity | CDA block 6 | 2005 |
| FI | `cvm_fund_registry` | fund (static) | CVM-175 registry ZIP | current |
| FI | `cvm_registro_fundo`, `cvm_registro_classe`, `cvm_registro_subclasse` | CVM 175 fund / class / subclass, keyed on the registry ids | the same CVM-175 registry ZIP, three members | current |
| FIDC | `cvm_fidc_mensal` | fund × month | monthly 2025+, yearly HIST ≤2024 | 2019 |
| FIDC | `cvm_fidc_tranche` | fund × month × tranche | monthly (tab X2/X3/X6) | **2025** |
| FIDC | `cvm_fidc_tranche_flows` | fund × month × tranche | monthly (tab X4) | **2025** |
| FIDC | `cvm_fidc_aging` | fund × month × bucket | monthly (tab VI) | **2025** |
| FIDC | `cvm_fidc_setor` | fund × month | tab II, monthly 2025+, HIST ≤2024 | 2013 |
| FIDC | `cvm_fidc_sacado` | fund × month × **rank** (1–25) | tab VIII, monthly 2025+, HIST ≤2024 | 2013 |
| FIDC | `cvm_fidc_cedente` | fund × month × block × slot (1–9) | tab I cedente slots, unpivoted | 2019-11 (slots appear) |
| FIDC | `cvm_fidc_scr` | fund × month | tab X, monthly 2025+, HIST ≤2024 | 2023-10 (member appears) |
| FIDC | `cvm_fidc_garantia` | fund × month | tab X\_7, monthly 2025+, HIST ≤2024 | 2019-11 (member appears) |
| FII | `cvm_fii_mensal` | fund × month × subtype × **version** | yearly ZIP | 2021 |
| FII | `cvm_fii_periodic` | fund × quarter/year × doc × **version** | yearly ZIP, 4 members | 2019 |
| FII | `cvm_fii_imovel` | fund × quarter × **source row** | yearly ZIP | 2019 |
| FIAGRO | `cvm_fiagro_mensal` | fund × month | monthly ZIP | **2025-05** |
| FIP | `cvm_fip_periodic` | fund × **filing date** × share class | yearly CSV | 2010 |
| SECURIT | `cvm_securit_mensal` / `_serie` / `_fluxo` / `_dfin` | vehicle × month / series / series × flow date / year × statement line | yearly ZIP (`_dfin`: yearly CSV) | 2019 |
| ETF | `cvm_etf_registry` | ticker (static) | curated seed ⋈ `cad_fi` | current |

#### CVM listed companies (CIA Aberta)

| Table | Grain | From |
| - | - | - |
| `cia_company` | company (static) | current |
| `cia_filing` | company × ITR/DFP filing × version | 2019 |
| `cia_account` | company × filing × **account line** | 2019 |
| `cia_event` | company × IPE event × version | 2010 |
| `cia_ticker` | company × ticker (published FCA map) | 2010 |

#### B3 and global series

| Table | Grain | Notes |
| - | - | - |
| `b3_cotahist` | instrument × **session** | every COTAHIST print: equities, BDRs, units, fund quotas, options, termo, auctions (`bvmf.bmfbovespa.com.br`) |
| `b3_cotahist_pre2019` | instrument × session | pre-2019 archive, kept separate |
| `b3_corporate_event` | instrument × event | splits/bonuses as published; **no adjustment factor derived** |
| `b3_futures_settlement` | session × outright DI1 contract | Price Report: settlement rate and PU, open interest, volume, quotes (DI1 is quoted in rate). From 2018-01-02 (`b3.com.br/pesquisapregao`) |
| `b3_reference_rate` | session × curve × vertex | `PRE` (DI x pré), `DOC` (onshore dollar coupon), `DPL` (IPCA coupon), every vertex. From 2008-01-02; the long end is B3's extrapolation |
| `mkt_series` | series × date | U.S. Treasury par yields, every tenor (U.S. Treasury, daily); Brent spot (EIA, published weekly); OFR Financial Stress Index and its volatility category (U.S. Office of Financial Research, two business days late; the value before each revision is kept) |

#### BACEN, IBGE, ANBIMA

| Table | Grain | Notes |
| - | - | - |
| `bacen_sgs` | series × date | macro series |
| `bacen_ptax` | currency × date | |
| `bacen_expectativas` | indicator × survey date × horizon | Focus survey |
| `ibge_ipca_item_monthly` | node × **month** | general index, 9 groups, 19 subgroups, 51 items, \~377 subitems: weight, monthly / YTD / 12-month change, as published; SIDRA 1419 (2012-01..2019-12) then 7060 (2020-01→) (`apisidra.ibge.gov.br`) |
| `anbima_class_monthly` | ANBIMA class × month | boletim class metrics |
| `anbima_etf_class_monthly` | none | ETF-only compat **view** over the above |
| `etf_market_snapshot` | ticker × day | scraped NAV/cotistas; needs `APIFY_TOKEN` |

Plus `cvm_ingest_log`: one row per `(entity, doc_type, period)` attempt, written exactly once by every ingest.

### 2. What we could ingest and don't

Each line is a decision, not an oversight; measurements are in the [repository inventory](https://github.com/PedroDnT/SILO-BZ/blob/main/docs/DATA_INVENTORY.md) §2.

#### CVM CDA blocks

The monthly CDA archive holds eight blocks; we read four. Adding one costs a field map, a migration and one `ingest_*` method.

| Block | Content | Status |
| - | - | - |
| BLC\_1 | Títulos públicos | **ingested** (`cvm_fi_cda`) |
| BLC\_2 | Cotas de fundos | **ingested** (`cvm_fi_cda_cotas`) |
| BLC\_4 | Ações / BDR | **ingested** (`cvm_fi_cda_acoes`) |
| BLC\_6 | Debêntures | **ingested** (`cvm_fi_cda_debentures`); no `CD_ATIVO`, so the key ends in `row_hash` |
| BLC\_3 | Swaps | not ingested, no consumer asked |
| BLC\_5 | Títulos privados | not ingested |
| BLC\_7 | Investimento no exterior | not ingested |
| BLC\_8 | Disponibilidades | not ingested, 28.9% of the archive by size for cash balances |

#### Other gaps

| Gap | Why |
| - | - |
| FIDC informe tabs unread | Ten of the ZIP's 18 members are ingested. Unread: tab I's other \~70 columns (asset composition, admin, condomínio), `III` (2025+), `V` (maturity ladder), `VII` (custody split, repurchases), `IX` (assignment prices), `X_1` / `X_1_1` (quotaholders per tranche and by investor type), `X_5` (liquidity ladder), `X_7` (collateral coverage) |
| Historical B3 index composition | Point-in-time membership and weights beyond the current portfolio in `b3_index_portfolio`. Gate: verify the archive, effective dates and each CIND layout version |
| FIDC tranche / flows / aging before 2025 | CVM publishes **no HIST equivalent** for tabs X2/X4/VI: an upstream limit, not a backlog item |
| FIAGRO before 2025-05 | the monthly file itself begins there |
| CIA ITR/DFP 2010–2018 | pipeline is wired from 2019; partitions are declared and empty |
| `cvm_fi_diario` before 2019 | RANGE partitions floor at 2019-01-01. Adding CVM's HIST back to 2000 means \~a decade of daily rows on the largest table. Deliberate |
| Company ↔ fund ownership beyond CDA | Two published edges exist and neither is inferred: `cvm_fi_cda_acoes.cd_ativo` (B3 ticker, joined to `cia_ticker`) and `cvm_fi_cda_debentures.cpf_cnpj_emissor` (joins to `cia_*` directly). No name matching, ever |
| Anything needing a licence or login | `etf_market_snapshot` is the one scrape, and it self-skips without its token |

#### Known defects in what is ingested

Both are written up with measurements in the repository inventory.

* **`cvm_fi_cda` keeps one bond in five and calls it the class total.** BLC\_1 is one row per security, but the shipped key carries none of `CD_SELIC` / `CD_ISIN` / `DT_VENC`, so 80.4% of rows are lost on upsert. The fix is additive: a `cvm_fi_cda_titpub` table keyed on the security, leaving `cvm_fi_cda` as the class roll-up the dashboards read.
* **`cia_event` cannot key an IPE filing with no protocol, and before 2015 none have one.** The natural key is `(protocolo, versao)`, so those rows are dropped, not given a synthesized key. 2010–2014 cannot be loaded; 2015 silently loses 12% of its filings. The fix is a second key era (a `row_hash` for protocol-less rows), which changes the grain and waits for the owner's call.

### 3. What we ingest and don't serve

The warehouse is wider than the API. Checked against `19_api_contract.sql` on 2026-09-15. "Indirect" means the table feeds `dim_fund` / `fact_fund_monthly` and reaches `funds`, `fund_nav` and `panel` without an endpoint of its own.

#### Served

Each endpoint's page has the detail; this maps table to endpoint.

| Held | Through `api` |
| - | - |
| `cvm_fi_diario`, `cvm_fidc_mensal`, `cvm_fii_mensal`, `cvm_fiagro_mensal`, `cvm_fip_periodic`, `cvm_fund_registry` | **Indirect**: `funds`, `fund_profile`, `fund_nav`, `search_funds`, `panel` (fund arms), `lookup`, `coverage`. No table is served raw |
| `b3_cotahist` | `quotes` and the five typed views, `auctions`, `quote_history`, `quote_latest`, `option_chain`, `option_history`, `option_exercises`, `termo_history`, `panel` (quote arms) |
| `cia_account`, `cia_company`, `cia_ticker` | `financials`, `company_financials`, `lookup`, `fund_debentures` (`issuer_tickers`). `cia_filing` reaches `coverage` only |
| `cvm_fi_cda_acoes` / `_cotas` / `_debentures` | `fund_holdings` (both directions); `fund_debentures` (by holder CNPJ or by issuer) |
| `anbima_class_monthly` | `anbima_classes` |
| `bacen_sgs` IPCA set (26 codes), `ibge_ipca_item_monthly` | [`inflation`](/api-docs/inflation) (plus a derived `acc_12m`) and `inflation_items` (weights, plus a derived `contribution`) |
| `cvm_fidc_cedente`, `_sacado`, `_setor`, `_scr` | `fidc_cedentes`, `fidc_sacados`, `fidc_portfolio`, panel metrics `receivables` / `sacado_top1` / `sacado_top25`, four `coverage()` rows. [FIDC concentration](/api-docs/fidc) |
| `cvm_fidc_tranche`, `_tranche_flows`, `_aging` | Since v32: `fidc_tranches` and `fidc_aging`, two `coverage()` rows. From 2013-01 (HIST archive through 2024-12). [FIDC tranches and aging](/api-docs/fidc-structure) |
| `fnet_document`, `fnet_document_filter` | Since v33: `fund_documents` and `fund_restatements`, one `coverage()` row. [Fund documents and restatements](/api-docs/fnet-documents) |
| `fnet_document_pair`, `fnet_document_diff` | Since v40: `fund_restatement_diff` and `fund_restatements`' `diff_status` / `n_fields_changed`. Restatements delivered from 2026 on; no document body is kept. [Fund documents and restatements](/api-docs/fnet-documents) |
| `cia_event` | Since v38: `company_events`, one `coverage()` row; from 2015, protocol-less filings are not held. [Company events](/api-docs/company-events) |
| `b3_futures_settlement`, `b3_reference_rate` | Since v42: [`future_curve` / `future_series`](/api-docs/rates) (from 2018) and [`curve` / `curve_history`](/api-docs/rates) (from 2008; never interpolated; the long end is B3's extrapolation), two `coverage()` rows |
| `bacen_sgs` (nine non-inflation series), `bacen_ptax` | Since v38: `macro_series` (unit on every row) and `ptax`, two `coverage()` rows. [Macro series and PTAX](/api-docs/macro) |
| Forensic screens over `cvm_fidc_aging`, `cvm_fidc_mensal`, `cvm_fii_mensal`, `cvm_securit_serie`, `fact_fund_monthly` | Seven `screen_*` functions as signals; every row carries `screen` and `params`; no score. [Forensic screens](/api-docs/screens) |
| FNET register and `dim_fund` / `cvm_fund_registry`, as filing behaviour | Since v37: `screen_restatements`, `screen_late_filers` (deadline from Resolução CVM 175, cited on every row), `screen_silent_filers`. [Filing-behaviour screens](/api-docs/filing-screens) |

#### Held and not served

Real gaps a caller could want; none has an endpoint.

| Held | What serving it would take |
| - | - |
| `bacen_expectativas` (Focus survey) | Its own shape (indicator × horizon × statistic) |
| `cvm_fiagro_mensal.vl_quota` / `nr_cotst` / `vl_total`; `cvm_fidc_mensal.vl_total` (pre-2025, \~82% of rows) | `fact_fund_monthly`'s fiagro arm sets all three `NULL`. Pass them through; the applicability block and its lockstep test follow |
| `cvm_fi_perfil` (FI investor mix, single-holder concentration) | `fund_investors(p_cnpj, …)` |
| `mkt_series`; IC-Br in `bacen_sgs` | Would follow `macro_series`: a registry, the unit on every row. Held for rates research (`research_examples/dustin_br/`). Not VIX: Cboe requires a signed licence |
| `cvm_fii_periodic`, `cvm_fii_imovel` | `fii_properties(p_cnpj)`; the register is the one FII fact with no monthly counterpart |
| `cvm_securit_*` (4 tables) | Structural: CRI/CRA are notes, not funds, and need a third id type (securitiser CNPJ plus a series key) |
| `etf_market_snapshot`, `cvm_etf_registry` | `etf_snapshot(p_ticker)`. Post-CVM-175 ETFs have no monthly CVM row, so this is the only ETF fundamentals path |
| `b3_corporate_event` | Held as published; `adjusted` stays `FALSE`. The convention was measured on 705 events and fell below the 90% bar. Candidate: serve the events without applying them |
| `cvm_fi_balancete` (\~111M rows) | Largest table; nothing reads it. Deliberate until a question needs it |
| `cvm_fi_cda` header block | Blocks 4, 2 and 6 are served; the header is read by nothing |
| `cvm_fidc_garantia` (tab X\_7, migration 45, from 2019-11) | CVM leaves both columns undescribed and the percentage's denominator does not reconcile to one sibling total, so it is stored as filed. Would need a `kind = 'guarantees'` arm in `fidc_portfolio` with that caveat in its note, plus a `coverage()` row |

#### Not served by design

| Held | Why |
| - | - |
| `cvm_ingest_log` | Audit table. Operator-only; `/ops` reads it through the build-time connection |
| `mv_savings_flow_monthly` | Reproduced as-found so CASCADE recreates cannot destroy it; revoked from every client role. Not in the catalog |
| `anbima_etf_class_monthly` | Compat view; `anbima_classes` with `p_category = 'ETF'` is the served form |
| `dim_*`, `fact_security_monthly`, `vw_*`, `etf_daily`, `etf_latest`, `etf_market_latest` | Analytical-layer objects the dashboard reads. The API reads through them and never exposes them |

### 4. How it is served

Five objects do the work; everything else is a typed view over `b3_cotahist`.

| Object | Does |
| - | - |
| `coverage()` | what is here, and how complete (read this FIRST) |
| `lookup()` | a name/ISIN/CNPJ/ticker to an id you can query |
| `panel()` | `(id, date, metric, value)`, mixing tickers and fund CNPJs |
| `quote_*()` | one instrument's own series |
| `fund_*()` | one fund's own series |

`panel` is the primitive: correlation, ranking and spreads are reductions of it, done in the client.

| Family | Native grain | Served as | Consequence |
| - | - | - | - |
| B3 cash | **session** | day, or month = last session | a monthly close is a real print, never an average |
| FI | fund × day (`cvm_fi_diario`) | **month** | daily rows exist but the panel does not serve them for funds |
| FIDC | fund × month-end | month | `delinquency` is a **BRL value**, not a rate: divide by `nav` yourself |
| FII | fund × month | month | the only family carrying `yield` |
| FIAGRO | fund × month | month | begins 2025-05: a shorter axis, not a thinner one |
| FIP | fund × **filing date** × share class | month | files 3–4× a year, not annually |
| CIA | company × filing × account line | **not served** by `panel` | a statement line fits no fund-shaped endpoint |

### Notes

* **FIP reads as annual and is not:** a fund files quarterly or three times a year, one row per share class each time. Until 2026-08-31 the key discarded 72–77% of every published file on upsert. The key is now `(cnpj, doc_type, period, classe_cota, row_hash)`.
* **No fabricated observations.** A missing month is absent, never interpolated or carried forward.
* **`as_of` ≠ `complete_through`.** The first is the newest row held, the second the last period believed complete. `coverage()` returns both.
* **Prices are unadjusted.** A split reads as a real \~50% jump; `adjusted` is `false` on every row. Exceptions: `quote_history`'s `close_adj`, continuous across splits and refused where unproven, and the selectable `close_total_return`, NULL with a reason where unproven.
* **1,000 rows per response, for everyone.** Signing in raises ids, page sizes and the query budget, never this.
* `coverage()` has no row for `fund_holdings` or `fund_debentures` yet; take freshness from the rows (`ORDER BY period DESC LIMIT 1`).
* Keeping this honest: a new dataset is a row in §1; a decision against one is a row in §2 with the reason; ingested but unserved belongs in §3. A table in none of the three is what this page exists to prevent.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.