Brazil Regulatory Filings API: Access CVM Documents by Layer
If you are searching for a Brazil regulatory filings API, you usually want ticker-first HTTP access to what Brazilian public companies file with the CVM (Comissão de Valores Mobiliários) — not a stock quotes feed, and not a US EDGAR client pointed at the wrong country. apicvm exposes that workflow: resolve an issuer, list filings by native CVM type, download the original PDF, and optionally extract page-level markdown.
This guide maps the three layers most production pipelines need, shows the resolve → list → download path, and points to specialized hubs when you already know which layer you want.
The problem
Three traps show up early:
- Quotes vs filings — "Brazil financial API" SERPs mix OHLCV vendors with regulatory PDFs. Candles do not replace audited statements or material fact disclosures. apicvm is the filings side. See Brazil financial data API for the split.
- SEC mental model — Foreign developers often search "Brazil SEC filings" and expect
10-K/8-Kfilters. CVM uses its own type codes (DFP,ITR,FRE,FATO_RELEVANTE, …). apicvm rejectstype=10-K. See Brazil SEC filings API for the form map. - One-size-fits-all scraping — Portals and bulk open-data ZIPs work for one-off loads. Product pipelines need stable document IDs, pagination, and multi-ticker polling. That is what a regulatory filings API should provide.
CVM itself publishes open data and portal UIs. It does not ship a ticker-first REST product API for the resolve → list → download loop. apicvm fills that gap. It is not an official government endpoint.
Three layers of CVM filings
Most research and agent workflows touch three layers, each with different type filters:
| Layer | Native type values |
What you get | Typical use |
|---|---|---|---|
| Statements | DFP, ITR |
Annual and quarterly financial packages | Fundamentals, QoQ models, audit trail |
| Events (IPE) | FATO_RELEVANTE, COMUNICADO_AO_MERCADO, APRESENTACAO_INVESTIDORES, … |
Material facts, market communications, decks | Monitoring, news agents, compliance |
| Governance (FRE) | FRE (multi-section bundle) |
Risk factors, board, compensation, litigation | ESG screens, proxy research, risk agents |
ITR disambiguation: ITR means Brazilian quarterly Informações Trimestrais — not a US income tax return API.
On VALE3 for calendar year 2025, the demo corpus held 20 DFP, 31 ITR, 78 FRE, and 21 FATO_RELEVANTE rows (demo API, queried 2026-09-08). Counts vary by issuer and ingestion coverage.
How apicvm helps
- Resolve the issuer —
GET /v1/companies/resolve - List filings —
GET /v1/documentswithtypeor comma-separatedtypes= - Filter by
yearanddateRefwhen you know the reference window - Download the PDF —
GET /v1/documents/:id/file - Optional (Pro): page-level markdown —
POST /v1/document-text-extractions(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: Resolve the company
curl -H "Authorization: Bearer $APICVM_KEY" \
"$APICVM_URL/v1/companies/resolve?query=PETR4&by=ticker"
Confirm cnpj and tickers[]. Ambiguous name searches return 409 AMBIGUOUS_RESULT — pin down with by=ticker or by=cnpj.
Step 2: List regulatory filings by layer
Statements only (annual + quarterly):
curl -H "Authorization: Bearer $APICVM_KEY" \
"$APICVM_URL/v1/documents?ticker=PETR4&types=DFP,ITR&year=2025&perPage=50"
Event disclosures (material facts):
curl -H "Authorization: Bearer $APICVM_KEY" \
"$APICVM_URL/v1/documents?ticker=PETR4&type=FATO_RELEVANTE&year=2025&perPage=50"
Governance reference form:
curl -H "Authorization: Bearer $APICVM_KEY" \
"$APICVM_URL/v1/documents?ticker=PETR4&type=FRE&year=2025&perPage=50"
perPage maxes at 50. Paginate with page= when meta.lastPage > 1.
Step 3: Download a filing
curl -H "Authorization: Bearer $APICVM_KEY" \
-o filing.pdf \
"$APICVM_URL/v1/documents/<document-id>/file"
Download does not consume extraction credits.
Example: Python layer counts for a watchlist
import os, requests
BASE = os.environ["APICVM_URL"]
H = {"Authorization": f"Bearer {os.environ['APICVM_KEY']}"}
WATCH = ["PETR4", "VALE3", "ITUB4"]
YEAR = 2025
LAYERS = {
"statements": "DFP,ITR",
"events": "FATO_RELEVANTE",
"governance": "FRE",
}
def count_layer(ticker, types):
r = requests.get(
f"{BASE}/v1/documents",
headers=H,
params={"ticker": ticker, "types": types, "year": YEAR, "perPage": 50},
)
r.raise_for_status()
return r.json()["meta"]["total"]
for ticker in WATCH:
print(f"{ticker} ({YEAR}):")
for name, types in LAYERS.items():
print(f" {name:12} {count_layer(ticker, types):4} rows")
Many teams poll statements weekly, events daily, and FRE on an annual refresh schedule. Tune cadence to your use case and rate limits.
Layer deep dives
When you already know which layer you need, use the specialized conversion hubs:
| Layer | Hub guide | Focus |
|---|---|---|
| Statements | Brazil financial statements API | DFP + ITR, dateRef quarter semantics |
| Events | Brazil IPE disclosures API | All IPE types, multi-type types= |
| Governance | Brazil reference form API | FRE sections, name= prefix filters |
For the full SEC-form analogy map across all types, see Brazil SEC filings API. For authentication and pagination basics, see Getting started with the CVM filings API.
Statements vs events vs governance in one pipeline
A common production pattern after quarterly earnings (ITR season):
- Pull latest ITR and compare to prior quarter — statement layer
- Poll FATO_RELEVANTE and APRESENTACAO_INVESTIDORES for guidance decks — event layer
- Refresh FRE risk and governance sections annually — governance layer
Seasonal workflows that combine ITR with presentations: Track Brazil earnings season. Multi-ticker polling patterns: Build a CVM filings watchlist.
Current limitations
- Polling, not push — apicvm does not emit a webhook when CVM publishes a new filing. Poll on a schedule and diff document IDs.
- Ingestion lag — sync is not guaranteed 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 for a year does not prove the company did not file.
- No SEC form codes — use native CVM
typevalues.type=10-Kis rejected. - Demo scope —
/v1/demo/*is limited to VALE3. Other tickers need a production key.
Next steps
- Read the API docs
- Get an API key
- CVM API overview — pillar guide with full type map
Ready to integrate?
Get an API key and start querying Brazilian CVM filings programmatically.