Skip to main content

bcb-data

bcb-data time-series icon

A Python client for Banco Central do Brasil's SGS API, with pandas DataFrames, raw data provenance, and 114 curated economic series.

Test status PyPI version Supported Python versions MIT license

Fetch Brazilian economic and financial time series from the Banco Central do Brasil SGS (Sistema Gerenciador de Séries Temporais) API. Read exchange rates, interest rates, inflation, GDP, employment, and more from Python without an API key.

Highlights

  • Date-indexed pandas DataFrames for individual series, recent observations, and multiple series merged into one table.
  • 114 curated series codes across 14 categories, plus keyword search and direct numeric SGS-code access.
  • Raw payloads with request metadata, retrieval time, SHA-256, and parser version for reproducible data pipelines.
  • Automatic partitioning of raw date ranges longer than SGS's 10-year single-query limit.
  • Explicit HTTP and rate-limit errors, including Retry-After when provided.

Installation

Install the bcb-data distribution; use bcb_data in Python imports.

pip install bcb-data

Or from source:

git clone https://github.com/rteoo/bcb-data.git
cd bcb-data
pip install .

Requirements

  • Python 3.10+
  • pandas
  • requests

Migrating from bcbpy

Use pip install bcb-data and replace from bcbpy ... with from bcb_data ... in new code. Starting with 2.5.0, the bcbpy compatibility distribution depends on the matching bcb-data release and preserves existing public imports, submodule paths, and exception identities. No existing PyPI release is deleted or renamed. See the migration guide.

Quick Start

from bcb_data import fetch_series, fetch_last, fetch_multiple, INTEREST_RATES, EXCHANGE_RATES

# Last 10 CDI daily rates
cdi = fetch_last(INTEREST_RATES["CDI_DAILY"], n=10)
print(cdi)

# USD/BRL exchange rate for 2024
usd = fetch_series(EXCHANGE_RATES["USD_SALE_DAILY"], start_date="2024-01-01", end_date="2024-12-31")
print(usd)

# Multiple series merged into one DataFrame
df = fetch_multiple(
    {"CDI": INTEREST_RATES["CDI_DAILY"], "SELIC": INTEREST_RATES["SELIC_DAILY"]},
    start_date="2024-01-01",
    end_date="2024-12-31",
)
print(df.tail())

API Reference

Functions

fetch_series(code, start_date=None, end_date=None)

Fetch a time series by its SGS numeric code. Returns a pandas DataFrame indexed by date.

from bcb_data import fetch_series

# Accepts YYYY-MM-DD or DD/MM/YYYY date formats
ipca = fetch_series(433, start_date="2023-01-01", end_date="2024-12-31")

Daily series (CDI, Selic, USD/BRL, …) require a start_date: BCB rejects undated daily queries with HTTP 406, which surfaces as SGSHTTPError carrying BCB's explanation.

fetch_last(code, n=10)

Fetch the last N observations of a series.

from bcb_data import fetch_last

selic = fetch_last(11, n=5)

fetch_multiple(codes_dict, start_date=None, end_date=None)

Fetch multiple series and merge them into a single DataFrame, one column per series.

from bcb_data import fetch_multiple

df = fetch_multiple({"CDI": 12, "SELIC": 11, "TR": 226}, start_date="2024-01-01")

fetch_raw(code, start_date=None, end_date=None, transport=None)

Fetch one SGS window as a RawResult (payload bytes plus request metadata). Same 10-year single-call limit as fetch_series. Does not parse the body.

from bcb_data import fetch_raw

raw = fetch_raw(12, start_date="2024-01-01", end_date="2024-01-31")
print(raw.sha256, raw.source_url, raw.params)

fetch_raw_range(code, start_date=None, end_date=None, transport=None)

Like fetch_raw, but splits ranges longer than 10 years into bounded partitions. Adjacent partitions do not share a calendar day.

from bcb_data import fetch_raw_range

parts = fetch_raw_range(433, start_date="2010-01-01", end_date="2024-12-31")

list_codes(category=None)

Print all available series codes. Pass a category name to filter.

from bcb_data import list_codes

list_codes()                        # all 114 codes across 14 categories
list_codes("INTEREST_RATES")        # only interest rate codes

search_codes(keyword)

Search codes by keyword (case-insensitive). Returns a dict of matches.

from bcb_data import search_codes

results = search_codes("IPCA")      # finds 15 IPCA-related codes
results = search_codes("USD")       # finds USD exchange rate codes

Exceptions

Exception When
SGSError Base class for every error raised by bcb-data, including malformed or non-JSON responses (e.g. an unknown series code)
SGSHTTPError Any other HTTP error status, with BCB's error text in the message. Also a requests.HTTPError.
SGSRateLimitError API returns HTTP 429 (too many requests). retry_after is set from Retry-After when present.
SGSEmptyResponseError No data returned for the given query

Network failures (timeouts, connection errors) are raised by requests unchanged.

Error Handling

from bcb_data import fetch_series, SGSRateLimitError, SGSEmptyResponseError

try:
    df = fetch_series(433, start_date="2024-01-01")
except SGSRateLimitError:
    print("Rate limited — wait and retry")
except SGSEmptyResponseError:
    print("No data for this date range")

Available Series Codes

114 curated codes organized in 14 categories:

Category Series Examples
EXCHANGE_RATES 6 USD/BRL daily sale/purchase, monthly averages
INTEREST_RATES 10 Selic, CDI, TR, TBF, TJLP
INFLATION 17 IPCA, INPC, IGP-M, IGP-DI, IPC-Fipe
IPCA_BREAKDOWN 11 Tradeable, non-tradeable, durables, services, cores
IPCA_CATEGORIES 9 Food, housing, transport, health, education
GDP 13 GDP current/constant/USD, per capita, quarterly components
EMPLOYMENT 7 Unemployment rate, labor force, income
INDUSTRIAL_PRODUCTION 6 Manufacturing, mining, capital/intermediate/consumer goods
FINANCIAL_MARKETS 7 Gold, Bovespa, IMA-B
SAVINGS 2 Savings rate and return
CONFIDENCE 4 Consumer (ICC) and business (ICEI) confidence
ECONOMIC_ACTIVITY 1 IBC-Br (GDP proxy, seasonally adjusted)
BASIC_BASKET 16 Cost of living by capital city
EXCHANGE_RATE_INDEX 5 Effective currency basket and bilateral real indices (USD, JPY, DEM, ARS)

Use any code directly by number or via the category dictionaries:

from bcb_data import INFLATION, GDP

# These are equivalent:
fetch_series(433)
fetch_series(INFLATION["IPCA"])

Migrating to 2.3

Version 2.3 renames seven registry keys to match the SGS series names. These are breaking changes to registry lookups. Update dictionary lookups and any saved key names using this table:

Category Old key (2.2 and earlier) New key (2.3) SGS code
EMPLOYMENT AVG_NOMINAL_INCOME AVG_REAL_HABITUAL_INCOME 24382
INTEREST_RATES SELIC_OVERNIGHT_ANNUAL SELIC_MONTHLY_ANNUALIZED 4189
INTEREST_RATES CDI_OVERNIGHT CDI_MONTHLY_ANNUALIZED 4392
EXCHANGE_RATE_INDEX REER_USD RER_USD 11753
EXCHANGE_RATE_INDEX REER_JPY RER_JPY 11754
EXCHANGE_RATE_INDEX REER_EUR RER_DEM 11755
EXCHANGE_RATE_INDEX REER_ARS RER_ARS 11756

The old keys are removed from the category dictionaries and ALL_CODES; lookups raise KeyError. list_codes and search_codes expose the new names. Numeric SGS codes, the 114-series count, and fetch behavior are unchanged.

Code 24382 measures real habitual income of employed people. Codes 4189 and 4392 measure Selic and CDI accumulated over the month, annualized on a 252-day basis. RER_DEM is the Deutsche mark index. The four RER_* indices are bilateral; REER_BASKET (11752) remains the effective currency-basket index. All five exchange-rate indices are IPCA-based, with June 1994 = 100.

from bcb_data import fetch_last, EMPLOYMENT, INTEREST_RATES, EXCHANGE_RATE_INDEX

income = fetch_last(EMPLOYMENT["AVG_REAL_HABITUAL_INCOME"])
selic = fetch_last(INTEREST_RATES["SELIC_MONTHLY_ANNUALIZED"])
dem = fetch_last(EXCHANGE_RATE_INDEX["RER_DEM"])

Discontinued series

These registered series have stopped updating in SGS (last observation as of September 2026). Historical data is still available; recent windows return SGSEmptyResponseError.

Series Last observation
FINANCIAL_MARKETS: GOLD_BMF_GRAM, GOLD_LONDON_OZ, BOVESPA_INDEX, BOVESPA_VOLUME Sep 2019
EMPLOYMENT["FORMAL_EMPLOYMENT_TOTAL"] Dec 2019
INFLATION["ICV_DIEESE"] Feb 2020
FINANCIAL_MARKETS: IMA_B, IMA_B5, IMA_B5_PLUS May 2023
BASIC_BASKET (all cities) Jun 2025
INFLATION: IGP_M_1ST_DECENNIAL, IGP_M_2ND_DECENNIAL, IPC_FIPE_1ST_QUAD, IPC_FIPE_2ND_QUAD, IPC_FIPE_3RD_QUAD Jul 2025

API Limits

  • Date range: max 10 years per single query (BCB restriction since March 2025). fetch_series / fetch_raw still enforce that limit. fetch_raw_range splits longer windows into bounded requests.
  • Rate limiting: HTTP 429 on excessive requests (no official limit documented). SGSRateLimitError.retry_after carries Retry-After when the API sends it; the client does not auto-retry.
  • Daily series: a start_date is mandatory; undated queries return HTTP 406.
  • Unknown series codes: SGS answers with an HTML page (HTTP 200) after about 30 seconds instead of a 404. With the client's 30-second timeout this usually surfaces as requests.ReadTimeout; when the page arrives in time it raises SGSError.
  • Date formats: the client accepts both YYYY-MM-DD and DD/MM/YYYY

Project Structure

bcb-data/
├── bcb_data/
│   ├── __init__.py      # Public API exports
│   ├── artifacts.py     # RawResult descriptor
│   ├── client.py        # API client functions and exceptions
│   ├── codes.py         # 114 curated series codes in 14 categories
│   └── constants.py     # Base URLs and API configuration
├── docs/
│   └── bcb-data-icon.svg   # Editable project icon
├── pyproject.toml       # PyPI packaging metadata
├── BCB_API_REFERENCE.md # SGS API reference and series code table
└── README.md
Library Python import Official data source
bcb-data bcb_data Banco Central do Brasil SGS
ibge-data ibge_data IBGE SIDRA, Aggregates, and Calendar
cvmbr-data cvmbr_data CVM open data and RAD/ENET filings

Each client is an independent package. Install only the libraries your project uses.

Data Source

All data is fetched from the BCB Open Data Portal under the Open Database License (ODbL).

License

MIT (see LICENSE). The BCB data accessed through this client remains under ODbL; users must comply with ODbL when redistributing data.

Releasing

The version in bcb_data/__init__.py must already be merged to main. From a clean checkout matching origin/main, run python release.py --tag vX.Y.Z --dry-run, then rerun without --dry-run and type the tag to confirm.

The release helper runs these gates locally: python -m pytest -m "not integration" -v and python -m build. It never bumps or commits main; PyPI publication remains the OIDC GitHub Actions workflow. A retry is safe only for the same tag when the existing tag points at the exact merged commit and no GitHub release exists. PyPI releases are immutable; rollback means following the package-recovery process rather than deleting or replacing a published version. The helper is platform-neutral Python, but hosted Actions behavior is not proven by local execution.

Metadata

Release files for bcb-data 2.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bcb-data 2.5.0
File Size Uploaded Provenance Actions
bcb_data-2.5.0.tar.gz 38.0 kB With provenance Details for bcb_data-2.5.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for bcb-data 2.5.0
File Interpreter ABI Platform Actions
bcb_data-2.5.0-py3-none-any.whl Python 3 none any Details for bcb_data-2.5.0-py3-none-any.whl

Total release size: 54.7 kB

Release files / bcb_data-2.5.0.tar.gz

Download URL bcb_data-2.5.0.tar.gz
Size 38.0 kB
Tags Source
SHA-256 checksum
How to use checksums
52c78defa0221e3a91fe1925f7f8f84851b98691e730d7f16bdc7a03db86c590
BLAKE2b-256 checksum
How to use checksums
1f085ba4c98848f980c9c691cd18eab11ed1bb7a983bda2585fcf36fdde4416b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Release files / bcb_data-2.5.0-py3-none-any.whl

Download URL bcb_data-2.5.0-py3-none-any.whl
Size 16.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2ca7eb37093ec440ae8bf6dfc1b3f6da911f7b8cbe558c97dbefd7064f9618ae
BLAKE2b-256 checksum
How to use checksums
eb15944e2b1f53fecb41f35138b4dbd62e9f29b55407738a4479d25f02c4fd5b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

Security for bcb-data 2.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for bcb_data-2.5.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

2.5.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page