Access Brazil CVM Filings with Node.js
Need a Node.js CVM filings API client? apicvm speaks HTTPS JSON. On Node 18+, use native fetch (undici), a Bearer token, and /v1/* — no SDK required. For typed clients, see the TypeScript guide; this page stays on the Node runtime path.
The problem
Backend jobs and agent runtimes often need Brazilian filings without:
- Puppeteer against the CVM portal
- One-off Python sidecars just to pull a PDF
- Fragile CSV dumps that lack document UUIDs
A few fetch calls keep the pipeline inside your existing Node service.
Setup
export APICVM_URL='https://apicvm.dev'
export APICVM_KEY='apicvm_...' # from /signup
// node --env-file=.env resolve.mjs (Node 20+)
const BASE = process.env.APICVM_URL;
const H = { Authorization: `Bearer ${process.env.APICVM_KEY}` };
Resolve a ticker
const url = new URL("/v1/companies/resolve", BASE);
url.searchParams.set("query", "PETR4");
url.searchParams.set("by", "ticker");
const res = await fetch(url, { headers: H });
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${await res.text()}`);
}
const company = await res.json();
console.log(company);
List DFP documents
const listUrl = new URL("/v1/documents", BASE);
listUrl.searchParams.set("ticker", "PETR4");
listUrl.searchParams.set("type", "DFP");
listUrl.searchParams.set("year", "2024");
listUrl.searchParams.set("perPage", "20");
const docs = await fetch(listUrl, { headers: H }).then((r) => r.json());
for (const row of docs.data) {
console.log(row.id, row.name);
}
perPage max is 50. Paginate with page until meta.lastPage. See Paginate and filter.
Download a PDF
import { writeFile } from "node:fs/promises";
const docId = "..."; // UUID from list
const fileRes = await fetch(`${BASE}/v1/documents/${docId}/file`, {
headers: H,
});
if (!fileRes.ok) throw new Error(`HTTP ${fileRes.status}`);
const buf = Buffer.from(await fileRes.arrayBuffer());
await writeFile("petr4-dfp.pdf", buf);
File download does not consume extraction credits.
Optional: start async text extraction
const extractRes = await fetch(`${BASE}/v1/document-text-extractions`, {
method: "POST",
headers: { ...H, "Content-Type": "application/json" },
body: JSON.stringify({
documentId: docId,
callbackUrl: "https://example.com/hooks/apicvm",
}),
});
// 202 Accepted — progress arrives on the callback, not a sync body
Extraction is async and needs an HTTPS callback in production. Student keys get 403 for extract. Details: Async CVM PDF extraction.
Errors and rate limits
Check res.status before json(). On 429, read X-RateLimit-Reset. Guide: Handle errors and rate limits.
Current limitations
- No official npm package — bring your own fetch wrapper.
- Extraction progress is callback-only (no job polling endpoint).
- Corpus coverage depends on ingestion; always resolve before hard-coding CNPJ.
Next steps
Ready to integrate?
Get an API key and start querying Brazilian CVM filings programmatically.