Brazil Stock Split Disclosures API: Track Splits and Reverse Splits from CVM Filings

A Brazil stock split disclosures API in the data-engineering sense is not a vendor of split-adjusted OHLCV. It is access to the CVM filings that announce desdobramento (stock split), grupamento (reverse split / share consolidation), and related holder notices — the PDFs issuers file before ex-dates and credit dates hit your database. Quote feeds apply factors; apicvm returns the regulatory document you can cite when you rebuild share counts and corporate-action tables.

This guide shows which type values to query, how to list and download split-related notices on a watchlist, and how this event layer differs from Brazil financial data API price endpoints.

The problem

Split monitoring on B3 issuers splits into two stacks that search results often confuse:

  1. Market data and adjusted prices — vendors apply split factors to historical candles. Fast for charts, opaque when you need the exact ratio, record date, or assembly approval referenced in the notice.
  2. Regulatory disclosures — avisos aos acionistas when a split or reverse split is approved and scheduled, and sometimes fatos relevantes when the event is material enough to disclose on the IPE feed.

Scraping the CVM portal works for one ticker and breaks on a multi-name watchlist. Bulk open-data ZIPs are dataset-oriented, not ticker-first. You want GET /v1/documents with stable document.id, then GET /v1/documents/:id/file for the original PDF — the same pattern as Brazil dividend disclosures API, scoped to share-count changes.

For cash payouts and JCP, use the dividend hub. For tender offers and control changes, see Brazil tender offer disclosures API. For the generic poll loop on all material facts, see Brazil material facts monitoring API.

Which filing type carries the split?

Brazilian issuers do not expose a dedicated type=SPLIT in the apicvm document list. Splits and reverse splits usually surface under:

type Role in split workflows
AVISO_AOS_ACIONISTAS Notice to shareholders — ratio, dates, assembly context, and formal terms for desdobramento or grupamento
FATO_RELEVANTE Material fact when the company discloses the split decision or milestone on the IPE layer (less common than avisos for routine splits, but worth polling on active watchlists)

Practical rule: query AVISO_AOS_ACIONISTAS first for each ticker, add FATO_RELEVANTE when you run a broad corporate-actions monitor, then filter rows by name keywords (Desdobramento, Grupamento, split, consolidacao) before downloading PDFs. After download, search PDF text for desdobramento, grupamento, proporção, or data do ex.

Reference for avisos listing: List avisos aos acionistas via API. Step-by-step material facts: List fatos relevantes via API.

On VALE3 for calendar year 2025, the demo corpus returned 21 combined FATO_RELEVANTE and AVISO_AOS_ACIONISTAS rows with no desdobramento or grupamento tokens in name (demo API, queried 2026-09-14). For 2026, the demo includes one AVISO_AOS_ACIONISTAS row illustrating the notice pattern. Other issuers with active split programs follow the same list-and-download workflow when those tokens appear. Zero rows in a given year does not prove no split occurred — see limitations below.

How apicvm helps

  1. Resolve the issuer — GET /v1/companies/resolve
  2. List shareholder notices — GET /v1/documents with type=AVISO_AOS_ACIONISTAS (optionally add FATO_RELEVANTE)
  3. Scope with year and optional dateRef; sort with field=dateRef&order=desc
  4. Download the PDF — GET /v1/documents/:id/file (no extraction credits)
  5. Optional (Pro): page-level markdown — POST /v1/document-text-extractions with async callback

Auth: Authorization: Bearer or X-API-Key. Try VALE3 without a key via the demo API.

Setup

export APICVM_KEY='apicvm_...'
export APICVM_URL='https://apicvm.dev'

Step 1: List shareholder notices (and optional material facts)

curl -H "Authorization: Bearer $APICVM_KEY" \
  "$APICVM_URL/v1/documents?ticker=VALE3&types=AVISO_AOS_ACIONISTAS,FATO_RELEVANTE&year=2025&perPage=50&field=dateRef&order=desc"

Response rows include stable id, dateRef, name, and nested company metadata. Use id as your cache key — not name, which can be long and encoding-sensitive.

Paginate with page= when meta.lastPage > 1. perPage maxes at 50.

Step 2: Narrow to split and reverse-split rows

Filename tokens on the CVM IPE feed are predictable enough for a first-pass filter:

curl -s -H "Authorization: Bearer $APICVM_KEY" \
  "$APICVM_URL/v1/documents?ticker=VALE3&types=AVISO_AOS_ACIONISTAS,FATO_RELEVANTE&year=2025&perPage=50" \
  | jq '.data[] | select(.name | test("Desdobramento|Grupamento|split|consolidacao"; "i")) | {id, type, dateRef, name}'

After download, search PDF text for proporção de desdobramento, grupamento de ações, or data de ex for validation. Extraction credits apply only if you use the text-extraction endpoint.

Step 3: Download a split notice PDF

curl -H "Authorization: Bearer $APICVM_KEY" \
  -o split-notice.pdf \
  "$APICVM_URL/v1/documents/<document-id>/file"

Download does not consume extraction credits.

Example: Python watchlist for split filings

Poll avisos across a watchlist you use for price-series hygiene. Persist seen in your database in production.

import os, time, requests, re
from datetime import datetime

BASE = os.environ["APICVM_URL"]
H = {"Authorization": f"Bearer {os.environ['APICVM_KEY']}"}
WATCH = ["VALE3", "PETR4", "ITUB4", "BBDC4", "ABEV3"]
YEAR = datetime.utcnow().year
SPLIT_RE = re.compile(
    r"desdobramento|grupamento|split|consolidacao", re.I
)
seen = set()  # load from your store on startup

def list_notices(ticker):
    r = requests.get(
        f"{BASE}/v1/documents",
        headers=H,
        params={
            "ticker": ticker,
            "types": "AVISO_AOS_ACIONISTAS,FATO_RELEVANTE",
            "year": YEAR,
            "perPage": 50,
            "field": "dateRef",
            "order": "desc",
        },
    )
    if r.status_code == 429:
        time.sleep(5)
        return list_notices(ticker)
    r.raise_for_status()
    return r.json()["data"]

for ticker in WATCH:
    for doc in list_notices(ticker):
        if doc["id"] in seen:
            continue
        if not SPLIT_RE.search(doc.get("name") or ""):
            continue
        seen.add(doc["id"])
        print(f"SPLIT {ticker} {doc['type']} {doc['dateRef']} {doc['name'][:70]}")

Wire this into GitHub Actions or extend the diff pattern from Brazil material facts monitoring API.

Where split disclosures sit in the filings stack

Layer Types Split relevance
Events AVISO_AOS_ACIONISTAS, FATO_RELEVANTE Ratio, dates, assembly approval
Statements DFP, ITR Share capital and per-share metrics after the event
Governance FRE Capital structure policies

Brazil regulatory filings API explains the full layer map. Pair this hub with Brazil financial statements API when you reconcile per-share lines after a grupamento.

Current limitations

  • Documents, not adjusted quotes — apicvm does not return split factors or retroactively adjusted OHLCV. Use filings to source terms; apply factors in your market-data layer.
  • Keyword filters are heuristic — name tokens help; false negatives are possible if issuers use unusual titles.
  • Polling, not push — no webhook when CVM publishes a new aviso. Schedule polls and diff document.id.
  • Ingestion lag — sync is not real-time. A notice may appear on the portal before it is in the corpus.
  • Corpus coverage — not every issuer or period is present. Validate against the portal for production compliance use cases.
  • Demo scope — /v1/demo/* is limited to VALE3. Other tickers need a production key.

Next steps

Ready to integrate?

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