Filter CVM Filings by Section Name with the apicvm API

Brazilian CVM filings are not always a single PDF. A FRE (Formulário de Referência) for one company and year can arrive as dozens of separate files — risk factors, board composition, compensation policy, each with its own internal document name. The same pattern appears in DFP and ITR bundles: financial statements, notes, management reports, and audit committee opinions filed as distinct catalog entries.

If you only need one section, downloading the entire bundle wastes bandwidth and complicates extraction. apicvm exposes section-level document names in the catalog. Use the name filter on GET /v1/documents to narrow results before download or text extraction.

The problem

Developers building governance screens, risk dashboards, or footnote parsers face a catalog problem:

  • Listing type=FRE&year=2024 for a large issuer returns many documents — not one monolithic filing
  • Open-data ZIP dumps include everything; you still parse filenames manually
  • Scraping the CVM portal means clicking through Portuguese section labels with no stable API

What you want is closer to EDGAR exhibit filtering: ticker + type + year + section name → one document ID → download or extract.

How CVM section names work

When companies file with the CVM, each uploaded file gets an internal document name in the regulatory catalog. apicvm indexes these names as the name field on each document record.

Examples from FRE filings:

Section theme Example name values
Risk factors DescricaoFatoresRisco-4_1, Descricao5PrincipaisFatoresRisco-4_2
Market risks DescricaoRiscosMercado-4_3
Risk management DescricaoGerenciamentoRiscos-5_1
Internal controls DescricaoControlesInternos-5_2
Board information InformacoesConselhoAdm-7_2
Compensation policy PoliticaPraticaRemuneracao-8_1
Stock-based pay PlanoRemuneracaoBaseadoAcoes-8_4
Related parties PercentualPartesRelacionadas-8_17

Names are partial-match filters — you do not need the full string including the section suffix.

How apicvm helps

The name query parameter on GET /v1/documents filters by partial document name. Combine it with ticker, type, and year to target a specific section.

Example: FRE risk factors for PETR4

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

curl -H "Authorization: Bearer $APICVM_KEY" \
  "$APICVM_URL/v1/documents?ticker=PETR4&type=FRE&year=2024&name=DescricaoFatoresRisco&perPage=20"

Response items include the matched name, id, dateRef, and nested company:

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "type": "FRE",
      "year": 2024,
      "name": "DescricaoFatoresRisco-4_1",
      "dateRef": "2024-12-31",
      "company": {
        "name": "PETROBRAS",
        "tickers": [{ "ticker": "PETR4" }]
      }
    }
  ],
  "meta": { "total": 1, "perPage": 20, "currentPage": 1 }
}

Pick the id explicitly, then download or extract:

# Download the section PDF
curl -OJ -H "Authorization: Bearer $APICVM_KEY" \
  "$APICVM_URL/v1/documents/550e8400-e29b-41d4-a716-446655440000/file"

# Or queue page-level markdown extraction
curl -X POST -H "Authorization: Bearer $APICVM_KEY" \
  -H "Content-Type: application/json" \
  -d '{"callback_url":"https://your-server.example/callbacks/apicvm","document":{"id":"550e8400-e29b-41d4-a716-446655440000"}}' \
  "$APICVM_URL/v1/document-text-extractions"

Example: Python helper

import os, requests

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

def find_section(ticker: str, doc_type: str, year: int, name: str) -> list[dict]:
    resp = requests.get(
        f"{BASE}/v1/documents",
        params={
            "ticker": ticker,
            "type": doc_type,
            "year": year,
            "name": name,
            "perPage": 50,
        },
        headers=H,
    )
    resp.raise_for_status()
    return resp.json()["data"]

risk_docs = find_section("PETR4", "FRE", 2024, "DescricaoFatoresRisco")
for doc in risk_docs:
    print(doc["id"], doc["name"])

Combining filters

The name filter works alongside all other document list parameters:

Parameter Use with name
ticker Scope to one issuer
type / types FRE, DFP, ITR
year Fiscal or reference year
dateRef Exact reference date when multiple versions exist
search Broader text search across name and type
perPage Up to 50 results per page

Typical workflow:

1. GET /v1/companies/resolve?query=RADL3&by=ticker
2. GET /v1/documents?ticker=RADL3&type=FRE&year=2025&name=PoliticaPraticaRemuneracao
3. Choose document.id from results
4. GET /v1/documents/:id/file  OR  POST /v1/document-text-extractions

When section filtering saves the most work

Scenario Without name filter With name filter
ESG risk review List 70+ FRE files, grep filenames One query for DescricaoFatoresRisco
Board composition screen Download full FRE bundle Target InformacoesConselhoAdm
Footnote extraction Parse multi-PDF DFP package Filter by notes annex name
Agent tool call Large context from full filing Small PDF, faster extraction

Current limitations

  • Catalog names, not page labels — apicvm filters by CVM document name in the catalog, not by page classification inside a PDF. Your pipeline still segments text within extracted pages when needed.
  • Naming varies by issuer — section suffixes (-4_1, -8_4) follow CVM templates but exact strings can differ. Use partial name values and inspect list results.
  • Coverage depends on ingestion — only documents already ingested by Hold appear. Verify with a list call before assuming a section exists.
  • No automatic section picker — the API does not choose a document when filters are ambiguous; you must select an explicit id.
  • Multiple matches possible — some sections file as several documents; review meta.total and pick the right dateRef.

Next steps

Ready to integrate?

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