Stage Brazil CVM Filings Metadata with dbt

Want dbt CVM filings models? Land JSON from apicvm into raw tables, then build stg_cvm_documents and marts for coverage. dbt does not download PDFs for you — your extractor/loader does.

The problem

Analytics engineers need reproducible tables: which documents exist for which ticker/year. Copy-pasting from the CVM portal breaks lineage. API UUIDs become primary keys.

ELT sketch

loader (Prefect/Airflow) → raw.cvm_documents_json → dbt stg → marts.filing_coverage
-- models/staging/stg_cvm_documents.sql
select
  document_id,
  ticker,
  document_type,
  filing_year,
  document_name,
  loaded_at
from {{ source('apicvm', 'cvm_documents') }}

Loader side (Python):

import os, requests

BASE = os.environ["APICVM_URL"]
H = {"Authorization": f"Bearer {os.environ['APICVM_KEY']}"}
r = requests.get(
    f"{BASE}/v1/documents",
    headers=H,
    params={"ticker": "CPFE3", "type": "DFP", "year": 2024, "perPage": 50},
)
r.raise_for_status()
# upsert r.json()["data"] into raw.cvm_documents

Mart ideas

  • filing_coverage: ticker × type × year with boolean present
  • fre_sections: filtered where name ILIKE '%risco%' (landed from name query param results)
  • Never hard-code counts in YAML seeds — refresh from API

Current limitations

  • dbt does not call apicvm; you need a loader
  • Text extraction stays outside dbt (async callbacks)
  • Empty API pages are valid corpus gaps

Next steps

Ready to integrate?

Get an API key and start querying Brazilian CVM filings programmatically.