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=2024for 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 partialnamevalues 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.totaland pick the rightdateRef.
Next steps
Ready to integrate?
Get an API key and start querying Brazilian CVM filings programmatically.