Local HTTP API for Fundamentus asset details and dividend events. It uses direct public HTML requests, FastAPI, Pydantic v2, async httpx, selectolax, in-memory cache and optional SQLite persistence.
The service is designed for local consumption by portfolio tools, data pipelines and research scripts. It binds to 127.0.0.1 by default and does not use Selenium, Playwright or a headless browser.
API version is resolved from package metadata at runtime. Release artifacts use the pushed Git tag as the build version.
- Exposes a typed HTTP API for asset details and dividend events from Fundamentus.
- Preserves raw table values while also returning normalized Brazilian dates, numbers, percentages and monetary values.
- Supports stocks, banks, FIIs, BDRs and other asset classes by preserving all parsed detail sections.
- Classifies B3 ETFs and exposes quotes and market data through brapi.
- Resolves multi-year fundamentals, including profitability, liquidity, cash flow, debt maturity and share counts, from CVM open data.
- Resolves normalized quality facts for bounded stock, listed-fund and ETF batches with field-level availability and provenance.
- Exposes profiles, holdings and fundamentals for international ETFs and stocks through Alpha Vantage, with SEC EDGAR CompanyFacts as the keyless official filing source when an issuer is SEC-covered.
- Keeps BDR identity separate from its foreign issuer and routes quality facts through a verified underlying ticker; unresolved BDRs return an actionable unavailable reason instead of querying the local code abroad.
- Filters dividends by
all,past,futureandupcoming_ex_date. - Uses local caching to reduce repeated upstream requests.
- Provides OpenAPI docs, Prometheus-compatible metrics and consistent JSON errors.
- Ships fixture-based tests that do not require internet access.
This is an alpha release. The API is usable for local development and research workflows, but Fundamentus HTML can change without notice. Parser behavior, normalized fields and cache semantics may still evolve before a stable 1.0.0 release.
This project is not affiliated with, endorsed by or sponsored by Fundamentus. Data returned by this API is not investment advice.
- Python 3.12+
uvfor local development- Docker, optional
git clone https://github.com/pedrorigon/fundamentus-data-API.git
cd fundamentus-data-API
uv sync --python 3.12 --extra dev
cp .env.example .env
uv run uvicorn app.main:app --host 127.0.0.1 --port 8000Open:
- Swagger UI:
http://127.0.0.1:8000/docs - ReDoc:
http://127.0.0.1:8000/redoc - Health:
http://127.0.0.1:8000/health - Metrics:
http://127.0.0.1:8000/metrics
docker compose up --buildThe compose file publishes the service only on 127.0.0.1:8000 and stores the SQLite cache in a named Docker volume.
| Endpoint | Description |
|---|---|
GET /health |
Runtime status, version and basic configuration checks. |
GET /metrics |
Prometheus-compatible process and application metrics. |
GET /v1/assets/{ticker} |
Combined asset details and dividends. |
GET /v1/assets/{ticker}/details |
Details page fields and preserved sections. |
GET /v1/assets/{ticker}/dividends |
Dividend events with optional period filtering. |
GET /v1/assets/{ticker}/opportunity |
Current valuation metrics with source and reference date. |
GET /v1/assets/{ticker}/fundamentals |
Multi-year financial statements resolved from CVM open data. |
POST /v1/quality/facts:resolve |
Batched, normalized quality evidence for stocks, listed funds and ETFs. |
GET /v1/instruments/{ticker} |
B3 instrument classification, including funds outside Fundamentus. |
GET /v2/instruments/{ticker} |
ETF and stock data from B3, brapi and Alpha Vantage. |
GET /v1/assets |
Batch query for multiple tickers. |
POST /v1/cache/invalidate |
Invalidate one ticker or the full local cache. |
See docs/API.md for the full endpoint reference.
Combined asset response:
curl 'http://127.0.0.1:8000/v1/assets/ITUB4?period=all'Details only:
curl 'http://127.0.0.1:8000/v1/assets/WEGE3/details'Future dividend payments:
curl 'http://127.0.0.1:8000/v1/assets/ITUB4/dividends?period=future&as_of=2026-07-05'Upcoming ex-date events:
curl 'http://127.0.0.1:8000/v1/assets/ITUB4/dividends?period=upcoming_ex_date'Batch query:
curl 'http://127.0.0.1:8000/v1/assets?tickers=WEGE3,ITUB4&include_dividends=false'Domestic ETF data:
curl 'http://127.0.0.1:8000/v2/instruments/BOVA11?instrument_type=etf'International ETF data:
curl 'http://127.0.0.1:8000/v2/instruments/VOO?instrument_type=etf'Quality facts:
curl -X POST 'http://127.0.0.1:8000/v1/quality/facts:resolve' \
-H 'Content-Type: application/json' \
-d '{"assets":[{"ticker":"ITUB4","kind":"stock"},{"ticker":"HGLG11","kind":"real_estate_fund"},{"ticker":"VOO","kind":"etf"}]}'Force refresh:
curl 'http://127.0.0.1:8000/v1/assets/ITUB4?force_refresh=true'Cache invalidation:
curl -X POST 'http://127.0.0.1:8000/v1/cache/invalidate' \
-H 'Content-Type: application/json' \
-d '{"ticker":"ITUB4"}'With token protection:
curl -X POST 'http://127.0.0.1:8000/v1/cache/invalidate' \
-H 'Content-Type: application/json' \
-H 'X-Cache-Token: your-token' \
-d '{"ticker":"ITUB4"}'Every setting uses the FUNDAMENTUS_API_ prefix. Start from .env.example.
| Setting | Default | Description |
|---|---|---|
BIND_HOST |
127.0.0.1 |
Interface used by the local server. |
BIND_PORT |
8000 |
Port used by the local server. |
MARKET_DATA_TTL_SECONDS |
300 |
Short TTL for market-sensitive data. |
FUNDAMENTALS_TTL_SECONDS |
3600 |
TTL for fundamentals. |
DIVIDENDS_TTL_SECONDS |
21600 |
TTL for dividend events. |
OPPORTUNITY_CACHE_TTL_SECONDS |
900 |
In-memory TTL for B3 and Status Invest complements. |
INSTRUMENT_DATA_TTL_SECONDS |
86400 |
In-memory TTL for ETF and international instrument data. |
BRAPI_TOKEN |
empty | brapi backend token required for production coverage of B3 symbols. |
ALPHA_VANTAGE_API_KEY |
empty | Alpha Vantage key for international ETF profiles and stock fundamentals. |
SEC_EDGAR_BASE_URL |
https://data.sec.gov |
Public SEC CompanyFacts endpoint. |
SEC_COMPANY_TICKERS_URL |
https://www.sec.gov/files/company_tickers.json |
Official SEC ticker-to-CIK directory. |
SEC_USER_AGENT |
USER_AGENT |
Optional descriptive SEC User-Agent; no secret is required. |
SEC_REQUEST_TIMEOUT_SECONDS |
10 |
Timeout for SEC directory and CompanyFacts requests. |
SEC_COMPANYFACTS_TTL_SECONDS |
86400 |
Local TTL for CompanyFacts payloads. |
SQLITE_CACHE_ENABLED |
true |
Enables persistent local cache. |
SQLITE_CACHE_PATH |
.cache/fundamentus_cache.sqlite3 |
SQLite cache path. |
BATCH_LIMIT |
20 |
Maximum tickers accepted by /v1/assets. |
UPSTREAM_CONCURRENCY |
4 |
Maximum concurrent Fundamentus requests. |
UPSTREAM_MIN_INTERVAL_SECONDS |
0.15 |
Minimum interval between upstream requests. |
CACHE_INVALIDATE_TOKEN |
empty | Optional token for cache invalidation. |
Fundamentus serves market data and fundamentals in the same details page. The API uses the lower value between MARKET_DATA_TTL_SECONDS and FUNDAMENTALS_TTL_SECONDS for that full document.
The instrument endpoint uses the B3 public instrument files for classification, brapi for Brazilian market data and Alpha Vantage for international ETF profiles and company fundamentals. SEC-covered issuers are resolved from the official EDGAR CompanyFacts API, then the existing public HTML statements are tried as a bounded fallback. Keep provider keys on the server and review their terms before production use.
GET /v2/instruments/search?q=... searches only the bounded in-process directory of instruments already resolved through the B3 provider; it never makes a live per-keystroke request. BDR metadata includes underlying_ticker, underlying_name, underlying_exchange, underlying_country and explicit resolution provenance when B3 publishes those fields or a reviewed alias is available.
Each preserved details field includes normalized and raw data:
{
"label": "Valor de mercado",
"key_normalized": "valor_de_mercado",
"value": "471288000000",
"raw_value": "471.288.000.000",
"value_type": "money"
}Null-like visual values such as empty text, - and unavailable markers are returned as null.
Dividend event:
{
"ex_date": "2026-06-19",
"payment_date": "2027-03-10",
"value": "0.1044",
"type": "JRS CAP PROPRIO",
"is_future_payment": true,
"is_future_ex_date": false,
"raw": {
"date": "19/06/2026",
"value": "0,1044",
"payment_date": "10/03/2027",
"type": "JRS CAP PROPRIO",
"shares_ratio": "1"
}
}make install
make checkEquivalent commands:
uv run ruff format .
uv run ruff check .
uv run mypy app
uv run pytestRun the API locally:
make runRun the API first, then:
uv run python scripts/benchmark.py --ticker ITUB4 --hot-runs 10The script performs one cold request with force_refresh=true and then measures hot cached responses.
Releases follow semantic versioning:
- Patch releases fix bugs without changing the public API contract.
- Minor releases add backwards-compatible endpoints, fields or configuration.
- Major releases may include breaking API, parser or cache changes.
Release notes live in CHANGELOG.md. The release process is documented in RELEASING.md.
Pushing a tag such as vMAJOR.MINOR.PATCH runs the release pipeline, injects that tag version into the build, creates a GitHub Release from the matching changelog section and uploads build artifacts.
This project performs direct HTTP requests against public HTML. It does not bypass CAPTCHA, rate limits, authentication walls or other protection mechanisms.
If Fundamentus becomes unavailable or returns unexpected HTML, the API fails with a structured error instead of exposing raw HTML, cookies, sensitive headers or stack traces.
MIT. See LICENSE.