Dados B3 › Transparency
Transparency
Transparency — how you check the numbers yourself
Data version 2026-11-09-ancora-do-fre · page generated 2026-11-12 08:09 UTC. If these do not match /saude, you are reading a cached copy.
What is checked, before every publication — 1298 automated tests, collected live
28 are DATA invariants (does the number tie out?) and 131 are product tests — access gate, navigation, language, AI connector. Calling all 1298 'invariants' would be inflating it: the split is checkable in the list itself. Not a hand-picked highlight reel: every test below was found by introspecting the actual test files just now, the same way pytest --collect-only would. Grouped by what it protects against, not by which file it lives in.
Level 1 — Integrity: does the data tie out? (28)
AC01— The whole follow-by-e-mail flow with the file provider: since 30/10/2026 the request on the company page creates an ACTIVE row at once and queues ONE welcome e-mail with the leave link and the not-me link and no confirm link; the weekly notice is built from the watcher events for that company, with the leave link; leaving cancels, and no notice follows. Asking again sends nothing. Unknown ticker is a 404.AC02— No response — request page, confirmation, leave, invalid e-mail error, the admin metrics panel — contains the address, and no log line writes it. The panel counts requests, confirmations, cancellations and the most followed companies: numbers only.AC03— Cleanup deletes a never-confirmed request older than the configured deadline, and only that one: the confirmed stays, the recent stays. The deadline is a parameter from the configuration, not a constant.AC04— The follow block appears right after the verdict on EVERY company page — the three most viewed (ITUB4, PETR4, BBAS3) and the others, in Portuguese and English — with the form to /acompanhar and the right ticker, and no text of the block, the response pages or the e-mails carries a forbidden term.AC05— A crawler following the form creates no request and sends no e-mail, and above the configured hourly cap the answer is 429 — without storing IP addresses, like the free key.AC06— Without RESEND_API_KEY/CORREIO_REMETENTE the provider is 'file': it writes to the pending queue and returns False. With both, it sends a POST to the Resend API with sender, recipient, subject and text — and if the API refuses, the message falls into the queue instead of vanishing. The address never goes to the log.AC07— The weekly job, with the file provider: each CONFIRMED e-mail gets ONE e-mail with the events of the last 7 days (before the sending Monday) of the tickers it follows, with the stop link for each ticker; whoever has no event gets nothing; the configured daily cap holds the rest in the queue, which goes out on the next day of the same week; running again does not send twice; an unconfirmed request gets nothing. Only counts on the panel; the e-mail never reaches the log.AC08— The due week is the most recent Monday on which 08:00 IN THE CONFIGURED TIME ZONE (America/Sao_Paulo) has passed: Monday 07:59 in São Paulo is still the previous week; 08:00 is the new one; Sunday night is the previous Monday. A week is served only up to the configured number of days after its Monday: a deploy on Sunday does not send last Monday’s alert. Cap, time and window come from the file, not the code.AC09— The weekly internal product report is built from the data, one line per figure in funnel order: real Google clicks, concentration, active and returning keys, confirmed follows, the week’s e-mails, watcher events by class (Monday to today only) and backup. A failed or missing source reads “not measured”, never zero. /admin/metricas returns the report and the SAME text is saved in DADOS_DIR/relatorios/YYYY-WW.md. No adjective or recommendation, no e-mail address.AC10— The Pro Monday portfolio e-mail: unconfirmed requests get nothing; a confirmed Pro request gets ONE e-mail with the value, only dividends paid from today on, the week's events for the portfolio's tickers and the stop link; a key that is no longer Pro gets nothing and uses no quota; the daily cap is shared with the watchdog e-mail; re-running does not repeat; asking again replaces the portfolio; the key is stored only as a hash; no e-mail in the panel or the log.AC11— The request on /carteira: a key that is not Pro gets 403 and the plans page, storing nothing; a Pro key stores ONE unconfirmed request and queues the confirmation, and the reply does not repeat the e-mail; the links confirm and stop; an empty portfolio is 400; the portfolio page shows the request form.AC12— The free newsletter: unconfirmed gets nothing; confirmed gets ONE e-mail with the closed ISO week, the counts, at most 5 lines per type plus how many more, the week link and the leave link; a week with no facts sends nothing; the daily cap is ONE for watcher + portfolio + newsletter; re-running does not repeat; leaving stops it; asking again before confirming resends the SAME link. No e-mail in panel or log.AC13— POST /boletim turns the bulletin on at once and queues the welcome e-mail with leave and not-me links, without echoing the e-mail; bots store nothing; invalid e-mail is 400; the old confirm link still turns on a pending request from before the change; leave works and unknown links are a noindex 404; answer pages offer following that company and /hoje the invitation.AC14— The free weekly e-mail for followed companies now carries the dividends to receive of those tickers (amount, record date, payment) and goes out even without a watcher event when there is a dividend; it goes as HTML (house template) with the plain text alongside; dividends of other tickers do not enter; the subject says what is inside; with nothing, nothing is sent.AC15— One sign-up, two lists: choosing both turns on one row per list at once, with the same token, and sends ONE welcome e-mail with the leave link of each list and the not-me link; leaving the magazine removes only the magazine and leaving the bulletin removes only the bulletin; no choice is a 400 and nothing is stored; a robot stores nothing; the page never repeats the e-mail; only the e-mail and the choice are kept.AC16— On /chave-gratis the box to get the Super Dados B3 weekly magazine comes unticked; creating a key without it puts nobody on any list; ticked (the box is the consent) it turns the magazine on at once and sends the welcome e-mail with leave and not-me links, and the bulletin is not added.AC17— Only an issue whose approval field holds the date of the owner OK is public: listed on /revista, served on /revista/{n} as an indexable page with canonical, no script and a link home, and in the sitemap; a draft (null, any text, invalid date, missing file or path outside the folder) is a 404 and shows nowhere.AC18— Sending an issue: no admin token or a wrong one is a 404; no owner OK or a draft is a 400 and nothing is sent; simulate only counts; each confirmed magazine subscriber gets the issue once, in the house e-mail with the highlights, the issue link and the leave link; the shared daily cap leaves the rest pending; the order is logged with the OK and no e-mail; only the admin route calls the send.AC19— The magazine invitation to bulletin subscribers only goes through the admin route with the owner OK, once per confirmed subscriber not already on the magazine and not on the do-not-send list; the invitation alone subscribes nobody; clicking its link subscribes as confirmed, and a token without a sent invitation does nothing.AC20— The two-list form is on /revista in both languages with no option preselected and the home links to it, the footer links the magazine, /admin/stats counts subscribers per list (bulletin, magazine, both) and confirmed ones with no e-mail, and the deletion on request and the 12-month retention reach the magazine table.AC21— Following a company now turns on at once: the row is stored already active and the answer is new; asking again changes nothing; one address stops at the configured cap of 20 followed companies, and leaving frees a slot. An old request from before the change that was never confirmed is NOT turned on by itself: it stays out of the weekly send and is deleted on the deadline, unless the person asks again for that company. The panel counts the new request as request and confirmation of the same week.AC22— The welcome e-mails (company in Portuguese and English, bulletin, magazine, both) say what arrives and when exactly as the sender does it (Mondays at 8 a.m. Brasilia from the sender config; for a company the material facts filed with the CVM, with the source delay of up to a week, the watcher facts and the dividends to receive; nothing in a week with nothing new), carry the one-click leave link and the not-me sentence with its link in text and HTML, and no confirm link. Every later e-mail (weekly notice, bulletin, magazine issue) keeps the leave link.AC23— From one connection at most 5 new company follows per day: the 6th is a 429 that stores nothing and sends nothing; another connection is still free. A separate cap of the same size covers bulletin plus magazine. The IP never reaches disk: the follow database holds neither the IP nor its hash, and the count restarts the next day.AC24— The not-me link opens a noindex page with one button and by itself changes nothing, so an e-mail link scanner cancels nobody; the button cancels everything the address gets (companies, bulletin, magazine) and blocks new sign-ups for 30 days on the three routes, which answer 429 without sending e-mail or echoing the address; the block keeps only a hash of the e-mail and expires; an unknown token is a noindex 404.AC25— Requests made before the change stay pending until the click: the old confirm link (company follow, magazine) still turns on a pending request with a 200; no old request is turned on by a new request for another list or company; the link of a cancelled or unknown request is a 404.AC26— On the company answer pages (dividends, profit, debt, in Portuguese and English) the follow block sits right below the answer at the top, before the table and the how-to-cite line, not at the end; on the company page it stays right below the verdict. The text is the one set by the owner, with the Receber avisos button (Get notices in English) and the link to the watcher page of the ticker. The home page gained nothing.AC27— Each sign-up sends a welcome e-mail, so one address cannot be signed up again and again: at most 3 new sign-ups per list in 30 days, counting the ones that left; the 4th is refused (429 on the route, no e-mail); the other list is not affected; after the period it works again.AC28— The Monday e-mail for company followers carries the material facts (Fatos Relevantes) the company filed with the CVM and the radar saw in that week (subject, filing date, link to the original CVM document) next to watcher events and dividends; a week with only a material fact still sends; facts go by company (following PETR3 gets the Petrobras fact), land in exactly one week (by the date the radar saw them, since the CVM file lags), notices to the market and other companies stay out, the leave link stays, and a missing radar file breaks nothing.
Level 2 — Semantics: does the account mean what the calculation assumes? (0)
Level 3 — Economic: is the result possible in the real world? (0)
Other product tests (0)
Access gate, navigation and the MCP connector — they test whether the product works, not whether a number is right, so they don't fit the 3 levels above by design. Still counted, still listed:
Reconstruct it yourself — net margin across 5 companies, 4 sectors
We don't ask you to trust the numbers. Here's the net margin of five companies in four different sectors, each rebuilt straight from its annual report (DFP) at the CVM — net income ÷ revenue, matching the published figure exactly. For ANY indicator, of any company, the whole chain down to the line in CVM's file is at /linhagem:
| Company · sector | Net income (CVM acct) | Revenue (CVM acct) | Margin =÷ |
|---|---|---|---|
| WEGE3 · industrial | R$ 6.78 bn DRE:3.11 | R$ 40.80 bn DRE:3.01 | 16.6% |
| VALE3 · mining | R$ 11.81 bn DRE:3.11 | R$ 213.59 bn DRE:3.01 | 5.5% |
| PETR4 · oil & gas | R$ 110.61 bn DRE:3.11 | R$ 497.55 bn DRE:3.01 | 22.2% |
| ITUB4 · bank | R$ 45.85 bn DRE:3.09 | R$ 387.12 bn DRE:3.01 | 11.8% |
| BBAS3 · bank | R$ 16.78 bn DRE:3.11 | R$ 319.46 bn DRE:3.01 | 5.3% |
Download any of these DFPs from the CVM, take the income and revenue accounts, divide — you get the same number. Banks use interest income as revenue (what makes sense for a bank), so the reconciliation is sector-aware; the others use sales revenue. Figures are the latest fiscal year.
Why we may differ from another site (and it's not an error)
A difference between two sites usually isn't one being wrong — it's a method choice. We disclose ours:
- Average vs ending capital: ROE and ROIC use average equity/capital (this year + last ÷ 2), not the ending balance — so they're not a naive single-year division.
- Controlling vs consolidated: we state which one each item uses.
- TTM vs annual: quarterly multiples use trailing-twelve-months earnings.
- IFRS 16, goodwill, cash, exceptional tax: each handled explicitly and flagged when it distorts.
Do the tests bite? Yes — real cases the suite has caught
A test that never fails could mean perfect data — or a weak test. These were born from real errors that slipped through, and now fail — only shown for tests that actually exist in the collected suite above:
- I-B16 · banks' P/E = 0: the CVM reports share count sometimes in units, sometimes in thousands (varying by company and year); market cap came out 1000× too small and P/E was zero. I-B16 (price × shares recomputed) caught it — we fixed 661 annual and 2,027 quarterly multiples.
- I-B24 · the vanishing profit: the profit/equity account varies by bank (Itaú 3.09, BB 3.11); if the label search fails, the number vanishes silently and ROE is born wrong. I-B24 makes that hole fail.
- H-B23 · the 800% dividend yield: old B3 dividends carry a price not adjusted for splits; without H-B23 the yield would look absurdly real. The flag keeps the record and warns.
- I-B20 · the missing COTAHIST 2023: on the first deploy one year of prices failed to download silently; the API shipped with ~50k fewer prices and the suite passed, because nothing checked coverage. We added I-B20 — a year without prices now fails the build loudly.
- I-B33 · Oil & Gas at −89.6% in one week: COTAHIST isn't split-adjusted; a 10:1 split read as a −90% weekly return and stayed in the cumulative return forever, with nothing failing (a blind amplitude filter didn't fix it either — it just flipped which direction was wrong). I-B33 (no sector week beyond ±35%, the ruler is the exchange itself) stops the build.
- I-B31 · 364 of 865 sector-index weeks frozen: extending the series back to 2010, a sector with no company carrying a market cap that week turned into a factor of 1.0 — a flat line that the cumulative return read as 'market stood still', and the 'since 2010' return came out fictional (+527%). I-B31 fails on any week repeated to the cent.
- I-E05 · EMBRAER's 2010 P/E priced with 2025 data: the point-in-time price lookup fell forward with no ceiling whenever the current ticker had no price at balance-sheet time (ticker change, share-class migration); the multiple came out priced 15 years into the future, in 22% of annual and quarterly rows, silently. The 45-day window (and I-E05) blocks it: no session inside the deadline, no multiple computed.
- I-E04 · AZUL at R$ 1.67 quadrillion market cap: the balance sheet carried 54.7 trillion shares from the judicial recovery issuance, but the price used was already on the post-reverse-split (1:150,000) basis — two ends measured on different bases, market cap wrong by orders of magnitude. I-E04 (market cap never above Brazil's GDP) fails the build on that absurdity.
How far back each block of data goes
No asterisks here: this is coverage year by year, counted right now. Indicators (ROE, ROIC, margins, growth) come from the filings alone and cover the whole series. Multiples (P/E, P/BV, EV/EBITDA) need a price and a share count — and the share count comes from CVM's reference form, which the further back you go the fewer companies filed in a usable format. The gap between the two columns is a source limit, not an ingestion hole. If you look for an old P/E and do not find it, it is because nobody has it — not because we hid it. The same numbers as JSON: /cobertura.
| Year | Companies with indicators | Companies with multiples |
|---|---|---|
| 2025 | 441 | 290 |
| 2024 | 443 | 296 |
| 2023 | 441 | 298 |
| 2022 | 428 | 295 |
| 2021 | 422 | 296 |
| 2020 | 410 | 274 |
| 2019 | 371 | 166 |
| 2018 | 326 | 167 |
| 2017 | 317 | 165 |
| 2016 | 311 | 154 |
| 2015 | 303 | 144 |
| 2014 | 301 | 140 |
| 2013 | 292 | 131 |
| 2012 | 291 | 112 |
| 2011 | 284 | 98 |
| 2010 | 277 | 34 |
Live coverage
457 companies · 884,647 price points · 8,650 recorded restatements · last refresh 2026-11-12 01:38:24. Full live counts at /saude.
Sources: CVM (open data, ODbL) and B3 (COTAHIST). Not affiliated with B3 or the CVM. Not investment advice.
Numbers on this page are live. Data version 2026-11-09-ancora-do-fre · page generated 2026-11-12 08:09 UTC. If this does not match /saude, you are reading a cached copy.