List Fatos Relevantes (Brazil Material Facts) via API

If you need a fato relevante API — or a Brazil material facts API — for event-driven research, scrape-the-portal is the wrong default. CVM fatos relevantes and sibling IPE categories are listable on apicvm with the same resolve → filter → download flow you already use for DFP, ITR, and FRE.

New to the concept? Start with What is a fato relevante?. This guide shows how to list FATO_RELEVANTE (and related types), pick a document UUID, and download the original PDF.

The problem

Event pipelines care about when something was disclosed, not only annual packages:

  • Compliance monitors want fatos relevantes next to quarterly ITR filings
  • Agents summarizing “what changed this week” need market communications, not only FRE risk chapters
  • Due diligence checklists ask for material facts alongside financial statements

The CVM portal and bulk open-data dumps can answer that, but they are awkward for HTTP agents: brittle HTML, ZIP unpacking, and no stable per-document API shape. You want typed filters (type, ticker, year) and a UUID you can download later.

What “material facts” means here

In Brazil, fato relevante is the issuer disclosure category for material information under CVM rules. Developers often group it with other eventual / periodic IPE-style filings:

API type Role
FATO_RELEVANTE Material facts from the IPE feed
COMUNICADO_AO_MERCADO Market communications (excluding investor presentations)
APRESENTACAO_INVESTIDORES Investor presentations filed as market communications
AVISO_AOS_ACIONISTAS Notices to shareholders
ATA_ASSEMBLEIA Assembly minutes

These are not a literal SEC Form 8-K clone. The analogy helps orientation; the taxonomy and filing cadence are Brazilian.

On apicvm, IPE-style documents are single PDFs. Section prefixes (GET /v1/document-prefixes) still apply only to DFP, ITR, and FRE.

How apicvm helps

  1. Resolve the issuer — GET /v1/companies/resolve
  2. List material facts — GET /v1/documents?type=FATO_RELEVANTE
  3. Download the PDF — GET /v1/documents/:id/file
  4. Optional (Pro): enqueue page-level markdown — POST /v1/document-text-extractions

Auth: Authorization: Bearer or X-API-Key.

Setup

export APICVM_KEY='apicvm_...'
export APICVM_URL='https://apicvm.dev'

Prefer the demo API only for VALE3 evaluation — demo download/markdown scope is FRE risk factors, not IPE types. For material facts, use a real key.

Step 1: Resolve the company

curl -H "Authorization: Bearer $APICVM_KEY" \
  "$APICVM_URL/v1/companies/resolve?query=PETR4&by=ticker"

Confirm cnpj and tickers[]. Ambiguous name queries return 409 AMBIGUOUS_RESULT with candidates — tighten with by=ticker or by=cnpj.

Step 2: List fatos relevantes

Filter by ticker, type, and year. perPage max is 50.

curl -H "Authorization: Bearer $APICVM_KEY" \
  "$APICVM_URL/v1/documents?ticker=PETR4&type=FATO_RELEVANTE&year=2024&perPage=20&field=dateRef&order=desc"

Each data[] item includes id (UUID), type, year, name, dateRef, and nested company. Pick an id explicitly before downloading.

Watchlist pattern: multiple IPE types

Use types (comma-separated) when the agent should see material facts and market communications together:

curl -H "Authorization: Bearer $APICVM_KEY" \
  "$APICVM_URL/v1/documents?ticker=PETR4&types=FATO_RELEVANTE,COMUNICADO_AO_MERCADO&year=2024&perPage=50"

For pagination patterns (page, field, order), see Paginate and filter CVM documents.

Step 3: Download the PDF

curl -OJ -H "Authorization: Bearer $APICVM_KEY" \
  "$APICVM_URL/v1/documents/<document-id>/file"

File download does not consume extraction credits. Empty list results can mean a corpus gap for that issuer/year — not that the type is unsupported.

Example: Python

import os
import requests

BASE = os.environ["APICVM_URL"]
H = {"Authorization": f"Bearer {os.environ['APICVM_KEY']}"}

company = requests.get(
    f"{BASE}/v1/companies/resolve",
    params={"query": "PETR4", "by": "ticker"},
    headers=H,
    timeout=60,
)
company.raise_for_status()

docs = requests.get(
    f"{BASE}/v1/documents",
    params={
        "ticker": "PETR4",
        "type": "FATO_RELEVANTE",
        "year": 2024,
        "perPage": 20,
        "field": "dateRef",
        "order": "desc",
    },
    headers=H,
    timeout=60,
)
docs.raise_for_status()

for row in docs.json()["data"]:
    print(row["id"], row.get("dateRef"), row.get("name"))

Store the UUID, not the display name — names can be long subject lines from the IPE feed.

Optional: extract text for agents (Pro)

IPE filings are PDFs. If an agent needs searchable markdown, enqueue async extraction with an HTTPS callback — same contract as DFP/FRE. There is no synchronous “return full text now” route, and Student keys get 403 on extraction. Details: Extract text from CVM PDFs and async callbacks.

When to use DFP/ITR/FRE instead

Need Prefer
Annual standardized financials DFPfiling type
Quarterly numbers ITRfiling type
Governance / risk narrative sections FREfiling type
Event disclosures / material facts FATO_RELEVANTE (+ sibling IPE types)

Many research workflows combine both: ITR for the quarter, then material facts around the release window. See compliance monitoring.

Current limitations

  • Coverage depends on the ingestion sync — empty results can be a gap, not an API error
  • Not a push/webhook feed for “new filing arrived”; clients poll GET /v1/documents
  • Do not claim real-time delivery; latency follows the sync pipeline
  • /v1/document-prefixes does not catalog IPE section trees — IPE items are whole PDFs
  • Demo routes do not expose IPE download/markdown for evaluation beyond the VALE3 FRE demo scope

Next steps

Ready to integrate?

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