Brazil IPE Disclosures API: Access Event-Driven CVM Filings

Quarterly DFP and ITR packages tell you what a Brazilian issuer reported last quarter. They do not tell you what happened this week — a guidance update, a buyback, a dividend notice, or a new investor deck. If you need a Brazil IPE disclosures API, you want the CVM's event-driven feed: fatos relevantes and sibling IPE categories, listable by ticker through apicvm.

The problem

Many Brazil pipelines stop at DFP, ITR, and FRE. That misses the IPE layer — the documents companies file when something material happens between reporting cycles. Scraping the CVM portal works for one ticker and breaks at scale. Bulk open-data ZIPs are dataset-oriented, not ticker-first, and they do not give you a stable document ID to download a specific PDF on the next poll.

Event monitors, news agents, and compliance teams need:

  1. All IPE-related types for a watchlist, not one category at a time
  2. Filters by year and dateRef to scope a polling window
  3. A download path for the original PDF when something new appears

What IPE means on CVM

IPE (Informações Periódicas e Eventuais and related categories) is how developers talk about CVM's event-driven disclosures — material facts, market communications, presentations, shareholder notices, and assembly minutes. It is not a literal SEC Form 8-K clone. Brazil has its own taxonomy.

For definitions and regulatory context, see IPE filing type and What is a fato relevante?.

Five IPE types on apicvm

GET /v1/documents accepts these IPE-related type values (alongside DFP, ITR, and FRE):

type What it covers
FATO_RELEVANTE Material facts — guidance, M&A, production updates
COMUNICADO_AO_MERCADO Market communications (excluding presentations filed separately)
APRESENTACAO_INVESTIDORES Investor presentations and earnings decks
AVISO_AOS_ACIONISTAS Notices to shareholders — dividends, rights issues
ATA_ASSEMBLEIA Assembly minutes

IPE items are whole PDFs. Section-level prefixes (GET /v1/document-prefixes) apply only to DFP, ITR, and FRE.

On VALE3 for calendar year 2026, the demo corpus held 13 FATO_RELEVANTE, 55 COMUNICADO_AO_MERCADO, 14 APRESENTACAO_INVESTIDORES, 1 AVISO_AOS_ACIONISTAS, and 2 ATA_ASSEMBLEIA rows (demo API, queried 2026-09-05). Counts vary by issuer and ingestion coverage.

How apicvm helps

The IPE workflow mirrors other filing types:

  1. Resolve the company — GET /v1/companies/resolve
  2. List IPE documents — GET /v1/documents with type or comma-separated types
  3. Download the PDF — GET /v1/documents/:id/file
  4. 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 issuer

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 IPE disclosures (single or multi-type)

List material facts only:

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

List the full IPE cluster in one call with types (comma-separated, no spaces):

curl -H "Authorization: Bearer $APICVM_KEY" \
  "$APICVM_URL/v1/documents?ticker=VALE3&types=FATO_RELEVANTE,COMUNICADO_AO_MERCADO,APRESENTACAO_INVESTIDORES,AVISO_AOS_ACIONISTAS,ATA_ASSEMBLEIA&year=2026&perPage=50"

perPage maxes at 50. Paginate with page= when meta.lastPage > 1. Sort by dateRef descending to surface the newest events first.

For IPE rows, dateRef behaves like a publication date (when the document appeared on the feed), unlike ITR where dateRef is the quarter-end reference date.

Step 3: Download a filing

curl -H "Authorization: Bearer $APICVM_KEY" \
  -o filing.pdf \
  "$APICVM_URL/v1/documents/<document-id>/file"

Example: Python IPE poll for a watchlist

import os, requests

BASE = os.environ["APICVM_URL"]
H = {"Authorization": f"Bearer {os.environ['APICVM_KEY']}"}
IPE_TYPES = (
    "FATO_RELEVANTE,COMUNICADO_AO_MERCADO,APRESENTACAO_INVESTIDORES,"
    "AVISO_AOS_ACIONISTAS,ATA_ASSEMBLEIA"
)
WATCH = ["PETR4", "VALE3", "ITUB4"]
YEAR = 2026

def list_ipe(ticker):
    r = requests.get(
        f"{BASE}/v1/documents",
        headers=H,
        params={"ticker": ticker, "types": IPE_TYPES, "year": YEAR, "perPage": 50},
    )
    r.raise_for_status()
    return r.json()["data"]

for ticker in WATCH:
    docs = list_ipe(ticker)
    print(f"{ticker}: {len(docs)} IPE rows in {YEAR}")
    for d in docs[:3]:
        print(f"  {d['type']}  {d['dateRef']}  {d['name'][:60]}")

In production, persist seen document.id values and diff on each poll. See Build a multi-ticker CVM filings watchlist for rate-limit-aware scheduling.

Per-type deep dives

Each IPE category has a focused guide with edge cases and examples:

During earnings season, combine IPE types with ITR — see Track Brazil earnings season with the CVM filings API.

Current limitations

  • Polling, not push — apicvm does not emit a webhook when CVM publishes a new IPE document. Poll on a schedule and diff IDs.
  • Ingestion lag — sync is not guaranteed real-time. A document may appear on the portal before it is in the corpus.
  • Corpus coverage — not every issuer or period is present. Counts depend on the ingestion pipeline.
  • No SEC form codes — type=8-K is rejected. Use FATO_RELEVANTE and siblings.
  • 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.