Access Brazil CVM Filings with Elixir
Need an Elixir CVM filings API client for Brazilian public companies? apicvm is plain HTTPS JSON. Use Req or HTTPoison with Bearer auth — there is no official Hex package.
The problem
Phoenix apps and Oban workers that archive Brazil filings often scrape the CVM portal or unpack yearly ZIPs. That breaks CI and loses document identity. A fixed /v1 contract is easier to supervise.
Setup
export APICVM_URL='https://apicvm.dev'
export APICVM_KEY='apicvm_...'
Add {:req, "~> 0.5"} (or HTTPoison) to mix.exs.
Resolve a ticker
base = System.fetch_env!("APICVM_URL")
key = System.fetch_env!("APICVM_KEY")
{:ok, %{body: body}} =
Req.get(base <> "/v1/companies/resolve",
headers: [{"authorization", "Bearer " <> key}],
params: [query: "PETR4", by: "ticker"]
)
IO.inspect(body)
List documents
{:ok, %{body: docs}} =
Req.get(base <> "/v1/documents",
headers: [{"authorization", "Bearer " <> key}],
params: [ticker: "VALE3", type: "ITR", year: "2024", perPage: 20]
)
Enum.each(docs["data"], fn d -> IO.puts("#{d["id"]} #{d["name"]}") end)
Download a PDF
doc_id = hd(docs["data"])["id"]
{:ok, %{body: pdf}} =
Req.get(base <> "/v1/documents/#{doc_id}/file",
headers: [{"authorization", "Bearer " <> key}],
decode_body: false
)
File.write!("vale3-itr.pdf", pdf)
Oban sketch
Enqueue a job per ticker watchlist item: resolve → list new IDs since last run → download → store UUID. Do not invent push webhooks from CVM — apicvm list endpoints are pull-based.
Current limitations
- Text extraction is async via HTTPS callback (Pro), not a sync Req return
perPagemax 50- Empty
dataarrays mean corpus gap, not "ticker invalid" — always resolve first
Next steps
Ready to integrate?
Get an API key and start querying Brazilian CVM filings programmatically.