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:

  1. 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.
  2. SEC mental model — Foreign developers often search "Brazil SEC filings" and expect 10-K / 8-K filters. CVM uses its own type codes (DFP, ITR, FRE, FATO_RELEVANTE, …). apicvm rejects type=10-K. See Brazil SEC filings API for the form map.
  3. 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

  1. Resolve the issuer — GET /v1/companies/resolve
  2. List filings — GET /v1/documents with type or comma-separated types=
  3. Filter by year and dateRef when you know the reference window
  4. Download the PDF — GET /v1/documents/:id/file
  5. 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):

  1. Pull latest ITR and compare to prior quarter — statement layer
  2. Poll FATO_RELEVANTE and APRESENTACAO_INVESTIDORES for guidance decks — event layer
  3. 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 type values. type=10-K is rejected.
  • 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.