Access Brazil CVM Filings with PHP
Need a PHP CVM filings API client for Brazilian public companies? apicvm is plain HTTPS JSON. Use cURL (or Guzzle), a Bearer token, and the /v1/* routes — there is no official PHP SDK.
The problem
PHP apps and Laravel workers often rely on fragile portal scrapers or one-off ZIP parsers. Those break when the CVM UI changes and rarely give you stable document UUIDs for caching or audit.
A thin HTTP client against a fixed contract is easier to keep in Composer packages, queue jobs, and CLI commands.
Setup
export APICVM_URL='https://apicvm.dev'
export APICVM_KEY='apicvm_...' # from /signup
PHP 8.1+ with the curl extension is enough for the examples below.
Resolve a ticker
<?php
$base = getenv('APICVM_URL');
$key = getenv('APICVM_KEY');
$ch = curl_init($base . '/v1/companies/resolve?' . http_build_query([
'query' => 'PETR4',
'by' => 'ticker',
]));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $key,
'Accept: application/json',
],
]);
$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code >= 400) {
throw new RuntimeException("HTTP $code: $body");
}
echo $body, PHP_EOL;
List DFP documents
$ch = curl_init($base . '/v1/documents?' . http_build_query([
'ticker' => 'PETR4',
'type' => 'DFP',
'year' => 2024,
'perPage' => 20,
]));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $key],
]);
$docs = json_decode(curl_exec($ch), true);
curl_close($ch);
foreach ($docs['data'] as $row) {
echo $row['id'], ' ', $row['name'], PHP_EOL;
}
perPage max is 50. Paginate with page until meta.lastPage. See Paginate and filter.
Download a PDF
$docId = '...'; // UUID from list response
$ch = curl_init($base . '/v1/documents/' . rawurlencode($docId) . '/file');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $key],
]);
$pdf = curl_exec($ch);
curl_close($ch);
file_put_contents('petr4-dfp.pdf', $pdf);
File download does not consume extraction credits.
curl cross-check
curl -H "Authorization: Bearer $APICVM_KEY" \
"$APICVM_URL/v1/companies/resolve?query=PETR4&by=ticker"
Errors and rate limits
Treat 401, 404, and 429 explicitly in your HTTP layer. When looping tickers, respect X-RateLimit-Remaining. Details: Handle errors and rate limits.
Current limitations
- Text extraction is async via HTTPS callback (
POST /v1/document-text-extractions) — not a sync PHP return string. - Student keys cannot extract markdown (
403). perPagemax is 50.- Corpus coverage depends on ingestion; empty lists mean "not in corpus yet".
Next steps
Ready to integrate?
Get an API key and start querying Brazilian CVM filings programmatically.