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"

Same contract as Node.js and curl.

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).
  • perPage max 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.