Getting Started with the CVM Filings API
You need a CVM filings API that answers ticker-first questions: which company is this, what filings exist, and how do I download the file I picked. apicvm exposes a versioned /v1 contract for Brazilian public company documents — DFP, ITR, and FRE — without scraping CVM portals.
This guide covers authentication, company resolution, document listing with filters, pagination, and the next steps for download or text extraction.
The problem
Official CVM open data is bulk-oriented. Product workflows need:
- Resolve
PETR4→ company metadata - Filter by
type,year, anddateRef - Paginate large result sets
- Download a specific filing by
document.id
Building that on top of ZIP dumps or HTML scraping means maintaining glue code that breaks when portals change. A filings API should give you stable HTTP endpoints instead.
Authentication
Production requires an API key. Pass it on every business route:
export APICVM_KEY='apicvm_...'
export APICVM_URL='https://apicvm.dev'
curl -H "Authorization: Bearer $APICVM_KEY" \
"$APICVM_URL/v1/health-check"
GET /v1/health-check is public. All other /v1 routes used below require the key when auth is enabled.
Alternative header: X-API-Key: .
Rate limits apply per key. Check response headers:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
Max requests in the window |
X-RateLimit-Remaining |
Requests left |
X-RateLimit-Reset |
Window reset (Unix timestamp) |
Step 1: Resolve a company
Start every workflow by resolving the issuer:
curl -H "Authorization: Bearer $APICVM_KEY" \
"$APICVM_URL/v1/companies/resolve?query=PETR4&by=ticker"
Response includes id, name, cnpj, sector, and tickers[].
Ambiguity: if multiple companies match, the API returns 409 with AMBIGUOUS_RESULT and candidates[]. Narrow the query (CNPJ, exact name) — the API never silently picks one.
Supported by values: ticker, cnpj, name.
Step 2: List filings
Filter documents by ticker, type, and year:
curl -H "Authorization: Bearer $APICVM_KEY" \
"$APICVM_URL/v1/documents?ticker=PETR4&type=DFP&year=2024&perPage=20"
Each item in data[] includes:
| Field | Use |
|---|---|
id |
UUID for download or extraction |
type |
DFP, ITR, or FRE |
year |
Filing year |
dateRef |
Reference date (e.g. 2024-12-31) |
name |
Original file name as filed |
company |
Nested company with tickers |
Pagination
List endpoints accept page (1-based) and perPage (max 50):
curl -H "Authorization: Bearer $APICVM_KEY" \
"$APICVM_URL/v1/documents?ticker=PETR4&type=ITR&year=2024&page=2&perPage=50"
The response meta block includes total, currentPage, lastPage, and navigation URLs.
Default sort: year desc, dateRef desc, name asc — newest filings first.
Step 3: Download or extract
Download the original PDF:
curl -OJ -H "Authorization: Bearer $APICVM_KEY" \
"$APICVM_URL/v1/documents/<document-id>/file"
Enqueue page-level markdown extraction (async, via callback):
curl -X POST -H "Authorization: Bearer $APICVM_KEY" \
-H "Content-Type: application/json" \
-d '{"callback_url":"https://your-app.example.com/callbacks/apicvm","document":{"id":"<document-id>"}}' \
"$APICVM_URL/v1/document-text-extractions"
Returns 202 — progress arrives only through callbacks. See Extract Text from CVM PDFs for AI Agents.
Python example
import os, requests
BASE = os.environ["APICVM_URL"]
H = {"Authorization": f"Bearer {os.environ['APICVM_KEY']}"}
company = requests.get(
f"{BASE}/v1/companies/resolve",
headers=H,
params={"query": "VALE3", "by": "ticker"},
).json()
docs = requests.get(
f"{BASE}/v1/documents",
headers=H,
params={"ticker": "VALE3", "type": "DFP", "year": 2024, "perPage": 20},
).json()
print(company["name"], company["cnpj"])
for doc in docs["data"]:
print(doc["type"], doc["name"], doc["id"])
For a fuller Python walkthrough, see Access Brazilian CVM Filings with Python.
Filing types at a glance
| Type | Cadence | Typical use |
|---|---|---|
| DFP | Annual | Audited financial statements |
| ITR | Quarterly | Interim financial updates |
| FRE | Annual | Company profile, governance, risks |
Current limitations
- Corpus coverage depends on the Hold ingestion pipeline — not every B3 company or period may be available.
- No synchronous text extraction endpoint — callbacks only.
- Downloads are PDF originals, not structured XBRL or parsed line items.
- ITR means Informações Trimestrais (quarterly filings), not an income tax return.
Next steps
Ready to integrate?
Get an API key and start querying Brazilian CVM filings programmatically.