Brazil SEC Filings API: Access CVM Documents

If you are searching for a Brazil SEC filings API, you usually want EDGAR-style access for Brazilian public companies: resolve an issuer, list filings, download the PDF. Brazil's regulator is the CVM, not the US SEC. apicvm is a product API for that CVM workflow. It is not EDGAR, and it is not an official government endpoint.

This guide maps SEC form names to CVM type filters and shows the resolve → list → download path.

The problem

EDGAR covers US issuers. Pointing an EDGAR client at Brazilian tickers fails. CVM publishes filings through portals and open-data bulk exports; those paths are not a ticker-first REST product API with PDF download and optional text extraction.

Two extra traps:

  • Aggregators sometimes relabel Brazilian filings with SEC form names (10-K, 8-K). Those labels are theirs. On apicvm the native types are DFP, ITR, FRE, FATO_RELEVANTE, and sibling IPE codes.
  • "Brazil stock data API" searchers often want quotes. Filings are a different layer. See Brazil financial data API.

For the full mental-model comparison, read Brazil EDGAR? CVM vs SEC filings. For the product surface named CVM API, see CVM API overview.

SEC form name → CVM type (analogy only)

Role analogy for orientation — not an official SEC equivalence.

You know from EDGAR Use on apicvm Notes
10-K (annual financials) DFP Demonstrações Financeiras Padronizadas
10-Q (quarterly) ITR Informações Trimestrais — Brazilian quarterly filings, not an income tax return
10-K narrative / proxy-like items FRE Formulário de Referência
8-K (material events) FATO_RELEVANTE Plus sibling IPE types when needed

There is no type=10-K, type=10-Q, or type=8-K on GET /v1/documents.

On PETR4 for calendar year 2025, the corpus held 14 DFP, 53 ITR, 78 FRE, and 20 FATO_RELEVANTE rows (Hold Postgres, queried 2026-08-26). Counts vary by issuer and sync coverage.

How apicvm helps

  1. Resolve the issuer — GET /v1/companies/resolve
  2. List filings — GET /v1/documents with type or types
  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'

New accounts can poke the scoped demo API (VALE3 FRE 2025 risk factors). For PETR4 and full type coverage, 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 matches return 409 AMBIGUOUS_RESULT with candidates — tighten with by=ticker or by=cnpj.

Step 2: List filings (CVM types, not SEC form codes)

perPage maxes out at 50. Example: annual package for PETR4.

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

Each data[] item includes id (UUID), type, year, name, dateRef, and nested company with tickers. Persist the UUID.

Multi-type watchlist

curl -H "Authorization: Bearer $APICVM_KEY" \
  "$APICVM_URL/v1/documents?ticker=PETR4&types=DFP,ITR,FATO_RELEVANTE&year=2025&perPage=50&field=dateRef&order=desc"

Empty data for a large issuer is usually a corpus gap for that filter, not an unsupported type.

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. Bytes are the original filing (usually application/pdf).

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": "DFP",
        "year": 2025,
        "perPage": 20,
        "field": "dateRef",
        "order": "desc",
    },
    headers=H,
    timeout=60,
)
docs.raise_for_status()

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

Which filing type next?

Need Guide
Annual financials like a 10-K List Brazil DFP (10-K equivalent)
Quarterly numbers like a 10-Q List Brazil ITR (10-Q equivalent)
Governance / risk narrative (FRE) List Formulário de Referência via API
Material events like an 8-K List Brazil material facts (8-K equivalent)

Section filters (document-prefixes, name=) apply to DFP / ITR / FRE bundles — not to single-PDF IPE items. Onboarding walkthrough: Getting started.

Getting text out of the PDF

List endpoints return metadata + path to the original file, not XBRL statements or English summaries in JSON.

  • Parse the PDF yourself after download, or
  • On Pro, enqueue POST /v1/document-text-extractions (async HTTPS callback; no job-status GET; Free/Student get 403 FORBIDDEN)

See Extract text from CVM PDFs.

Current limitations

  • GET /v1/documents does not accept SEC form codes as type.
  • EDGAR analogy is for orientation only — not official equivalence, and not "Brazil's EDGAR."
  • Coverage depends on the ingestion sync. Empty results can be a gap.
  • No push feed; clients poll GET /v1/documents.
  • Do not expect real-time delivery.
  • apicvm is a filings API, not a quotes / stock-data API.
  • Demo routes are scoped to VALE3 FRE risk-factor samples.
  • US issuers stay on EDGAR; apicvm covers Brazilian CVM filings in the corpus.

Next steps

Ready to integrate?

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