Python client for the BCB SGS (Sistema Gerenciador de Series Temporais) API from the Banco Central do Brasil.
Fetch Brazilian economic and financial time series as pandas DataFrames with a simple, Pythonic interface. Includes 114 curated series codes covering exchange rates, interest rates, inflation, GDP, employment, and more.
pip install bcbpyOr from source:
git clone https://github.com/rteoo/bcbpy.git
cd bcbpy
pip install .- Python 3.10+
- pandas
- requests
from bcbpy 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())Fetch a time series by its SGS numeric code. Returns a pandas DataFrame indexed by date.
from bcbpy 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 the last N observations of a series.
from bcbpy import fetch_last
selic = fetch_last(11, n=5)Fetch multiple series and merge them into a single DataFrame, one column per series.
from bcbpy import fetch_multiple
df = fetch_multiple({"CDI": 12, "SELIC": 11, "TR": 226}, start_date="2024-01-01")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 bcbpy 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)Like fetch_raw, but splits ranges longer than 10 years into bounded partitions. Adjacent partitions do not share a calendar day.
from bcbpy import fetch_raw_range
parts = fetch_raw_range(433, start_date="2010-01-01", end_date="2024-12-31")Print all available series codes. Pass a category name to filter.
from bcbpy import list_codes
list_codes() # all 114 codes across 14 categories
list_codes("INTEREST_RATES") # only interest rate codesSearch codes by keyword (case-insensitive). Returns a dict of matches.
from bcbpy import search_codes
results = search_codes("IPCA") # finds 15 IPCA-related codes
results = search_codes("USD") # finds USD exchange rate codes| Exception | When |
|---|---|
SGSError |
Base class for every error raised by bcbpy, 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.
from bcbpy 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")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 | Real effective exchange rate (USD, EUR, JPY, ARS) |
Use any code directly by number or via the category dictionaries:
from bcbpy import INFLATION, GDP
# These are equivalent:
fetch_series(433)
fetch_series(INFLATION["IPCA"])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 |
- Date range: max 10 years per single query (BCB restriction since March 2025).
fetch_series/fetch_rawstill enforce that limit.fetch_raw_rangesplits longer windows into bounded requests. - Rate limiting: HTTP 429 on excessive requests (no official limit documented).
SGSRateLimitError.retry_aftercarriesRetry-Afterwhen the API sends it; the client does not auto-retry. - Daily series: a
start_dateis 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 raisesSGSError. - Date formats: the client accepts both
YYYY-MM-DDandDD/MM/YYYY
bcbpy/
├── bcbpy/
│ ├── __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
├── pyproject.toml # PyPI packaging metadata
├── BCB_API_REFERENCE.md # SGS API reference and series code table
└── README.md
All data is fetched from the BCB Open Data Portal under the Open Database License (ODbL).
MIT (see LICENSE). The BCB data accessed through this client remains under ODbL; users must comply with ODbL when redistributing data.