Brazil Material Facts Monitoring API: Track Fatos Relevantes on a Watchlist
Quarterly DFP and ITR packages age quickly. Between reporting cycles, Brazilian issuers file fatos relevantes — material facts that can move a stock: guidance updates, buybacks, dividends, M&A, litigation, and management changes. If you need a Brazil material facts monitoring API, you want a repeatable loop: poll FATO_RELEVANTE for each ticker on a watchlist, detect new documents, download the PDF, and route alerts into Slack, email, or an agent pipeline.
apicvm supports that workflow with GET /v1/documents and stable document IDs. It is not a live CVM firehose and it is not an official government endpoint.
The problem
Event monitors for B3 issuers hit three blockers early:
- Portal friction — the CVM website is built for humans reading one company at a time, not for polling fifty tickers every morning.
- Quotes vs filings — market data APIs stream prices; they do not deliver the regulatory PDF behind a dividend announcement or guidance revision.
- No native push — apicvm does not ship a "new filing" webhook. Monitoring means scheduled polling and diffing document IDs against your last run.
Scraping the portal breaks when layouts change. Bulk open-data ZIPs are dataset-oriented, not ticker-first. A material facts monitoring API should give you resolve → list → download with pagination — the same pattern as Brazil IPE disclosures, scoped to the highest-signal event type.
What is a fato relevante?
A fato relevante is Brazil's CVM category for material information that could influence an investor's decision — roughly analogous to a US Form 8-K item, but with Brazil's own taxonomy. On apicvm the native type filter is FATO_RELEVANTE.
For regulatory context and examples, see What is a fato relevante?. For a one-shot list query (not a monitoring loop), see List Brazil material facts via API.
The monitoring loop
Production monitors follow the same four steps:
1. Load watchlist tickers
2. GET /v1/documents?type=FATO_RELEVANTE&year=...&ticker=...
3. Diff document.id against a persisted seen-set
4. For new ids: download PDF → optional text extract → alert
On VALE3 for calendar year 2025, the demo corpus held 21 FATO_RELEVANTE rows (demo API, queried 2026-09-09). Active issuers can file multiple material facts per month during earnings season or corporate actions.
Cadence guidance
| Scenario | Suggested poll interval | Notes |
|---|---|---|
| Earnings season | Every 4–6 hours | Clusters around ITR publication and presentations |
| Normal watchlist | Daily | Enough for most research and compliance use cases |
| High-priority ticker | Hourly | Stay within rate limits |
Tune throttle across tickers. A 20-ticker daily pass is roughly 20 list calls plus downloads for new items only.
How apicvm helps
- Resolve the issuer —
GET /v1/companies/resolve - List material facts —
GET /v1/documentswithtype=FATO_RELEVANTE - Filter by
yearand optionallydateRefto scope the polling window - Download the original PDF —
GET /v1/documents/:id/file(no extraction credits) - Optional (Pro): page-level markdown —
POST /v1/document-text-extractionswith async callback
Auth: Authorization: Bearer or X-API-Key. Try VALE3 without a key via the demo API.
Setup
export APICVM_KEY='apicvm_...'
export APICVM_URL='https://apicvm.dev'
Step 1: List material facts for one ticker
curl -H "Authorization: Bearer $APICVM_KEY" \
"$APICVM_URL/v1/documents?ticker=PETR4&type=FATO_RELEVANTE&year=2025&perPage=50"
Response rows include stable id, dateRef, name, and nested company metadata. Use id as your diff key — not name, which can be long and encoding-sensitive.
Paginate with page= when meta.lastPage > 1. perPage maxes at 50.
Step 2: Download a new material fact
When your diff finds a document ID you have not seen:
curl -H "Authorization: Bearer $APICVM_KEY" \
-o material-fact.pdf \
"$APICVM_URL/v1/documents/<document-id>/file"
Download does not consume extraction credits.
Example: Python watchlist monitor
This pattern polls a watchlist, diffs IDs, and prints new material facts. Persist seen in Redis or a database in production.
import os, time, requests
from datetime import datetime
BASE = os.environ["APICVM_URL"]
H = {"Authorization": f"Bearer {os.environ['APICVM_KEY']}"}
WATCH = ["PETR4", "VALE3", "ITUB4", "BBDC4", "ABEV3"]
YEAR = datetime.utcnow().year
seen = set() # load from your store on startup
def list_material_facts(ticker):
r = requests.get(
f"{BASE}/v1/documents",
headers=H,
params={
"ticker": ticker,
"type": "FATO_RELEVANTE",
"year": YEAR,
"perPage": 50,
},
)
if r.status_code == 429:
time.sleep(5)
return list_material_facts(ticker)
r.raise_for_status()
return r.json()["data"]
def download(doc_id, path):
r = requests.get(f"{BASE}/v1/documents/{doc_id}/file", headers=H)
r.raise_for_status()
path.write_bytes(r.content)
new_items = []
for ticker in WATCH:
for doc in list_material_facts(ticker):
if doc["id"] not in seen:
seen.add(doc["id"])
new_items.append(doc)
for doc in new_items:
print(f"NEW {doc['company']['tickers'][0]['ticker']} "
f"{doc['dateRef']} {doc['name'][:60]}")
# download(doc["id"], Path(f"{doc['id']}.pdf"))
For a scheduled runner, wire this into GitHub Actions or your orchestrator. For multi-type IPE monitoring (presentations, market communications), extend type or use types= — see Brazil IPE disclosures API.
Material facts vs other IPE types
FATO_RELEVANTE is the core event type for price-sensitive news. Related IPE categories often appear in the same monitoring window:
type |
When to include |
|---|---|
FATO_RELEVANTE |
Default — guidance, dividends, M&A, litigation |
APRESENTACAO_INVESTIDORES |
Earnings decks alongside quarterly results |
COMUNICADO_AO_MERCADO |
Routine market communications |
A focused material facts monitoring API pipeline usually starts with FATO_RELEVANTE only, then expands. Earnings-season workflows that combine ITR + presentations + material facts: Track Brazil earnings season.
Where this fits in the filings stack
Material facts are the event layer in a three-layer CVM model. Statement and governance layers run on different cadences:
| Layer | Types | Monitoring cadence |
|---|---|---|
| Events | FATO_RELEVANTE, IPE siblings |
Daily or hourly |
| Statements | DFP, ITR |
Weekly or post-earnings |
| Governance | FRE |
Annual refresh |
See Brazil regulatory filings API for the full layer map and Build a multi-ticker watchlist for generic polling across all types.
Current limitations
- Polling, not push — apicvm does not notify you when CVM publishes a new fato relevante. Schedule polls and diff
document.id. - Ingestion lag — sync is not real-time. A filing may appear on the portal before it is in the corpus.
- Corpus coverage — not every issuer or period is present. Zero rows does not prove no filing occurred.
- Not SEC 8-K —
FATO_RELEVANTEis a CVM native type.type=8-Kis rejected. See List Brazil material facts (8-K equivalent) for the analogy map. - Demo scope —
/v1/demo/*is limited to VALE3. Other tickers need a production key.
Next steps
- Read the API docs
- Get an API key
- What is a fato relevante? — pillar guide with regulatory context
Ready to integrate?
Get an API key and start querying Brazilian CVM filings programmatically.