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:

  1. Portal friction — the CVM website is built for humans reading one company at a time, not for polling fifty tickers every morning.
  2. Quotes vs filings — market data APIs stream prices; they do not deliver the regulatory PDF behind a dividend announcement or guidance revision.
  3. 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

  1. Resolve the issuer — GET /v1/companies/resolve
  2. List material facts — GET /v1/documents with type=FATO_RELEVANTE
  3. Filter by year and optionally dateRef to scope the polling window
  4. Download the original PDF — GET /v1/documents/:id/file (no extraction credits)
  5. Optional (Pro): page-level markdown — POST /v1/document-text-extractions with 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_RELEVANTE is a CVM native type. type=8-K is 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

Ready to integrate?

Get an API key and start querying Brazilian CVM filings programmatically.