You need the Brazil SELIC target rate inside your software with reliable timestamps and a clean JSON schema. By the end of this article, you will query, cache, and compute with SELIC from the Interest Rates API, covering seven endpoints (symbols, latest, historical, timeseries, fluctuation, OHLC, and convert), and wire the result into dashboards, loan calculators, and risk models.
SELIC in context: what it is and how it’s expressed
SELIC (symbol: SELIC) is the Banco Central do Brasil’s policy target rate and the anchor for BRL monetary policy. In the Interest Rates API, SELIC is a central bank benchmark with frequency “monthly” and currency “BRL.” The API returns SELIC as a percentage per annum (p.a.), not a decimal. For example, a JSON field of 13.75 means 13.75% per annum.
Effective dates matter. Monthly symbols represent the last day in the month with data. When you query a specific date within a month, the SELIC value corresponds to the most recent effective date within that month. The API also provides a top-level “date” and a per-symbol “dates” map to identify the precise effective date for each symbol in multi-symbol responses.
Typical use cases include:
- Loan pricing engines in lending and mortgage platforms that benchmark BRL credit spreads to SELIC.
- Corporate treasury dashboards that monitor BRL interest carry and hedge effectiveness.
- Macro and rates research notebooks that require auditable historical time series for policy rates.
- Risk models that stress spreads relative to SELIC across multiple scenarios.
All examples below use the Interest Rates API at https://interestratesapi.com. Every request is a GET and authenticates with the api_key query parameter. Explore capabilities in the MCP and Interest Rates API MCP, and Register for an API key. You can also Get started with Interest Rates API and Register for Interest Rates API.
1) Discoverability: /symbols for SELIC
Use the symbols catalogue to programmatically confirm the availability and metadata for SELIC. You can filter by category and base (currency).
cURL
curl -s "https://interestratesapi.com/api/v1/latest?api_key=YOUR_API_KEY&symbols=SELIC"
JSON response (example)
{
"success": true,
"date": "2026-09-30",
"base": "BRL",
"rates": {
"SELIC": 13.75
},
"dates": {
"SELIC": "2026-09-30"
},
"currencies": {
"SELIC": "BRL"
},
"base_filter_note": null
}
Field notes:
symbol,name,category: identifiers and classification.currency_codeandfrequency: key for unit conversions and downstream sampling logic.- Filter by
base=BRLto focus on BRL-denominated rates such as SELIC.
Python (requests)
import requests
resp = requests.get(
'https://interestratesapi.com/api/v1/symbols',
params=dict(category='central_bank', base='BRL', api_key='YOUR_KEY')
)
catalog = resp.json()
# Find SELIC
selic = next((s for s in catalog.get('symbols', []) if s.get('symbol') == 'SELIC'), None)
print(selic)
JavaScript (fetch)
const response = await fetch(
'https://interestratesapi.com/api/v1/symbols?category=central_bank&base=BRL&api_key=YOUR_KEY'
);
const data = await response.json();
const selic = (data.symbols || []).find(s => s.symbol === 'SELIC');
console.log(selic);
PHP
<?php
$url = 'https://interestratesapi.com/api/v1/symbols?category=central_bank&base=BRL&api_key=YOUR_KEY';
$json = file_get_contents($url);
$data = json_decode($json, true);
$selic = null;
if (isset($data['symbols'])) {
foreach ($data['symbols'] as $s) {
if ($s['symbol'] === 'SELIC') { $selic = $s; break; }
}
}
print_r($selic);
?
2) Latest SELIC value: /latest
Use the latest endpoint to retrieve the most recent SELIC reading and effective date. Remember: SELIC is monthly; the date reflects the last effective date with data in the month.
Official cURL sample (copy-paste)
Official JSON sample (verbatim)
How to read this:
rates.SELICis the policy rate in percent per annum.dateis the overall response date;dates.SELICis the SELIC-effective date (important in multi-symbol queries).currencies.SELICconfirms the benchmark’s currency (BRL).
Python (requests)
import requests
response = requests.get(
'https://interestratesapi.com/api/v1/latest',
params=dict(symbols='SELIC', api_key='YOUR_KEY')
)
data = response.json()
selic_rate = data['rates']['SELIC'] # percent per annum
selic_effective_date = data['dates']['SELIC']
print(selic_rate, selic_effective_date)
JavaScript (fetch)
const response = await fetch(
'https://interestratesapi.com/api/v1/latest?symbols=SELIC&api_key=YOUR_KEY'
);
const data = await response.json();
const rate = data.rates.SELIC; // p.a. percent
const effDate = data.dates.SELIC;
console.log(rate, effDate);
PHP
<?php
$url = 'https://interestratesapi.com/api/v1/latest?symbols=SELIC&api_key=YOUR_KEY';
$json = file_get_contents($url);
$data = json_decode($json, true);
$rate = $data['rates']['SELIC'] ?? null;
$effDate = $data['dates']['SELIC'] ?? null;
echo "SELIC: {$rate}% (effective {$effDate})";
?
3) Point-in-time SELIC: /historical
Retrieve the rate as of a specific date. For monthly symbols, the endpoint returns the value on the last available day within that month.
cURL
JSON response (example)
Field notes:
dateechoes your request. For monthly SELIC, the value corresponds to the last effective day in June 2025.rates.SELICis a percent p.a. value. Treat as illustrative where shown in examples.
Python (requests)
import requests
resp = requests.get(
'https://interestratesapi.com/api/v1/historical',
params=dict(date='2025-06-15', symbols='SELIC', api_key='YOUR_KEY')
)
hist = resp.json()
value = hist['rates']['SELIC']
print('Historical SELIC:', value)
JavaScript (fetch)
const r = await fetch(
'https://interestratesapi.com/api/v1/historical?date=2025-06-15&symbols=SELIC&api_key=YOUR_KEY'
);
const hist = await r.json();
console.log('SELIC on 2025-06-15:', hist.rates.SELIC);
PHP
<?php
$url = 'https://interestratesapi.com/api/v1/historical?date=2025-06-15&symbols=SELIC&api_key=YOUR_KEY';
$data = json_decode(file_get_contents($url), true);
echo $data['rates']['SELIC'];
?
4) Time series for SELIC: /timeseries
Request a sequence between two dates to chart, backtest, or compute realized stats. Monthly symbols appear as either stepwise constants across relevant business days or as monthly points depending on the provider’s structure and the API’s daily grid.
cURL
JSON response (example)
Field notes:
rates.SELICis a date-indexed map of p.a. values.frequenciesinforms your resampling (e.g., monthly close or end-of-month).
Python (requests)
import requests
resp = requests.get(
'https://interestratesapi.com/api/v1/timeseries',
params=dict(start='2025-10-16', end='2026-10-16', symbols='SELIC', api_key='YOUR_KEY')
)
ts = resp.json()
series = ts['rates']['SELIC'] # dict of "YYYY-MM-DD" -> percent p.a.
# Example: convert to (date, rate_decimal) tuples for modeling
points = [(d, v / 100.0) for d, v in series.items()]
print(len(points), 'points')
JavaScript (fetch)
const res = await fetch(
'https://interestratesapi.com/api/v1/timeseries?start=2025-10-16&end=2026-10-16&symbols=SELIC&api_key=YOUR_KEY'
);
const ts = await res.json();
const entries = Object.entries(ts.rates.SELIC).map(([d, v]) => [d, v / 100]);
console.log('First point:', entries[0]);
PHP
<?php
$url = 'https://interestratesapi.com/api/v1/timeseries?start=2025-10-16&end=2026-10-16&symbols=SELIC&api_key=YOUR_KEY';
$data = json_decode(file_get_contents($url), true);
$series = $data['rates']['SELIC'] ?? [];
foreach ($series as $date => $pct) {
$asDecimal = $pct / 100.0;
// do something with $date and $asDecimal
}
echo count($series);
?
5) Change statistics: /fluctuation
Compute start/end levels, absolute and percent change, and the range (high/low) for SELIC across a period. These fields are ideal for summary cards and regression targets.
cURL
JSON response (example)
Field notes:
start_value,end_value: percent p.a. values.changeis in percentage points;change_pctis a percent relative tostart_value.high,loware extrema over the requested range, useful for dashboards.
Python (requests)
import requests
resp = requests.get(
'https://interestratesapi.com/api/v1/fluctuation',
params=dict(start='2025-10-16', end='2026-10-16', symbols='SELIC', api_key='YOUR_KEY')
)
fx = resp.json()['rates']['SELIC']
spread_bps = (fx['end_value'] - fx['start_value']) * 100 # percentage points -> basis points
print('Change (bps):', spread_bps)
JavaScript (fetch)
const r = await fetch(
'https://interestratesapi.com/api/v1/fluctuation?start=2025-10-16&end=2026-10-16&symbols=SELIC&api_key=YOUR_KEY'
);
const fx = (await r.json()).rates.SELIC;
const changeBps = (fx.end_value - fx.start_value) * 100;
console.log('Change (bps):', changeBps);
PHP
<?php
$url = 'https://interestratesapi.com/api/v1/fluctuation?start=2025-10-16&end=2026-10-16&symbols=SELIC&api_key=YOUR_KEY';
$fx = json_decode(file_get_contents($url), true)['rates']['SELIC'];
$change_bps = ($fx['end_value'] - $fx['start_value']) * 100.0;
echo $change_bps;
?
6) SELIC OHLC candlesticks: /ohlc
Create OHLC aggregates (open, high, low, close) for charting and exploratory analysis. OHLC is computed on the fly from daily data; there is no separate OHLC store.
cURL
JSON response (example)
Field notes:
open,high,low,close: percent p.a. over the aggregation period.data_pointscounts the number of daily observations contributing to that candle.
Python (requests)
import requests
resp = requests.get(
'https://interestratesapi.com/api/v1/ohlc',
params=dict(symbols='SELIC', period='monthly', start='2025-10-16', end='2026-10-16', api_key='YOUR_KEY')
)
ohlc = resp.json()['rates']['SELIC']
# Example: last close
last_close = ohlc[-1]['close'] if ohlc else None
print('Last monthly close:', last_close)
JavaScript (fetch)
const res = await fetch(
'https://interestratesapi.com/api/v1/ohlc?symbols=SELIC&period=monthly&start=2025-10-16&end=2026-10-16&api_key=YOUR_KEY'
);
const o = await res.json();
const candles = o.rates.SELIC || [];
console.log('First candle:', candles[0]);
PHP
<?php
$url = 'https://interestratesapi.com/api/v1/ohlc?symbols=SELIC&period=monthly&start=2025-10-16&end=2026-10-16&api_key=YOUR_KEY';
$data = json_decode(file_get_contents($url), true);
$candles = $data['rates']['SELIC'] ?? [];
if ($candles) {
$first = $candles[0];
echo "Period {$first['period']} close={$first['close']}";
}
?
7) Compare loan interest costs: /convert
Use the convert endpoint to compare simple loan interest costs using the latest rates of two symbols. This is helpful to quantify a spread’s monetary impact. Although the endpoint outputs totals for a simple interest model, you can also compute amortized payments locally using the returned annual rates.
cURL
JSON response (example)
Field notes:
rate_spreadis the absolute spread in percentage points.total_interestandtotal_paymentare computed for a simple interest model at the latest rate for each symbol.
Python (requests)
import requests
resp = requests.get(
'https://interestratesapi.com/api/v1/convert',
params=dict(from='SELIC', to='ECB_MRO', amount='100000', term_months='12', api_key='YOUR_KEY')
)
cmp = resp.json()
spread = cmp['difference']['rate_spread'] # percentage points
print('Spread (pp):', spread)
JavaScript (fetch)
const r = await fetch(
'https://interestratesapi.com/api/v1/convert?from=SELIC&to=ECB_MRO&amount=100000&term_months=12&api_key=YOUR_KEY'
);
const cmp = await r.json();
console.log('Interest saved:', cmp.difference.interest_saved);
PHP
<?php
$url = 'https://interestratesapi.com/api/v1/convert?from=SELIC&to=ECB_MRO&amount=100000&term_months=12&api_key=YOUR_KEY';
$data = json_decode(file_get_contents($url), true);
echo $data['difference']['rate_spread'];
?
Practical implementation details
Publication frequency and business days
SELIC is monthly. Many integration teams cache SELIC until a new monthly observation is published. For date-specific queries, the API uses the last day with data inside the queried month. Time series may display daily rows reflecting a step function for unchanged target values; you can downsample to month-end if you prefer discrete monthly points.
Dates vs. dates map
- Single-symbol calls: the top-level
dateoften suffices. - Multi-symbol calls: read
dates.SYMBOLfor the exact effective date per symbol (e.g., SELIC vs. interbank rates with different calendars).
Units and transforms
- Rates are returned as percent per annum (e.g., 13.75 means 13.75% p.a.). Divide by 100 to convert to decimals.
- To compute a monthly rate approximation for amortized payments, convert to decimal and divide by 12 (or use exact day-count conventions in your model if required).
Caching and rate limits
- Cache SELIC daily or until the API’s rate limit headers indicate reset:
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset
- Respect
429responses and theRetry-Afterheader. - For dashboards, query
/latestonce per run and share the result via your internal cache rather than calling per-widget.
Error handling
- 401: Missing/invalid
api_key. - 403: Account not active.
- 404: No symbols matched or no data in the requested period (may include
detailswith available ranges). - 422: Validation error such as malformed dates.
- 429: Quota exhausted; check rate limit headers for the reset schedule.
Computing spreads and monthly payments (without hardcoding numbers)
Spreads in percentage points: spread_pp = rate_a - rate_b. In basis points: spread_bps = 100 × spread_pp. For an amortized loan, convert SELIC from percent to decimal and derive a monthly rate r = (selic_percent / 100) / 12. Payment for principal P over n months:
- If r = 0: payment = P / n
- Else: payment = P × r × (1 + r)^n / ((1 + r)^n − 1)
To compute a floating-rate installment indexed to SELIC, update r when a new SELIC observation is published (monthly). For dashboards, show both the current SELIC-indexed payment and the delta vs. last month using the fluctuation endpoint. If your product pricing is SELIC + X%, compute the effective annual rate as selic_decimal + (X / 100), then translate to monthly as needed.
Integration patterns
- Data ingestion: Use
/timeseriesnightly to refresh your BRL rates warehouse. Normalize into a date, symbol, rate_percent schema. - Analytics: Use
/fluctuationfor summary cards, then drill down with/ohlcfor visualization. - User journeys: Provide a “Benchmark selector” but default to SELIC for BRL. Add per-symbol effective dates in tooltips sourced from the
datesmap to avoid ambiguity.
For reference documentation and additional examples, browse interestratesapi.com and the MCP.
Operational checklist for SELIC-based apps
- Authentication: Always append
?api_key=YOUR_KEYto the request URL. Do not use headers for auth. - HTTP method: GET for all endpoints.
- Base URL:
https://interestratesapi.com/api/v1/. - Symbol correctness: Use exactly
SELICfor the Brazil policy rate. - Time zone: Store
dateanddates.SELICas ISO strings; treat them as effective dates for financial logic and display. - Caching: Cache monthly; invalidate when a new effective date is published.
- UI: Always display units (“% p.a.”) and the effective date.
End-to-end example: building a SELIC card
To render a single “SELIC today” card:
- Call
/latest?symbols=SELIC. - Read
rates.SELICanddates.SELIC. - Format as “SELIC 13.75% (effective 2026-09-30).”
- Optionally, compute the spread to a BRL loan’s reference rate or add an amortized monthly payment using the formulas above.
- Cache the JSON response in your app for the session and revalidate on schedule.
To power a “What changed this year?” summary, call /fluctuation with your YTD range and show start_value, end_value, change, change_pct, and highs/lows. For charts, request /ohlc monthly and render candlesticks to highlight tightening and easing cycles.
FAQ
Q1: Is SELIC returned as a percentage or decimal?
A1: Percentage per annum. Convert to decimal by dividing by 100 before modeling.
Q2: How do effective dates work for monthly SELIC?
A2: The rate is effective on the last day with data in the month. When querying a specific day within a month, SELIC corresponds to that month’s last effective date. Use the dates.SELIC field to display and audit the exact effective date.
Q3: What happens on weekends or holidays?
A3: For monthly symbols, there may be no new observations on non-business days. Time series may present repeated values across adjacent business days. Use month-end sampling if your model is monthly.
Q4: How should I cache SELIC?
A4: Cache aggressively until the next monthly update. Respect 429s and the rate limit headers, and consider a shared cache layer so your UI doesn’t call the API redundantly.
Q5: How can I compute a monthly loan payment from SELIC?
A5: Convert the annual percent to a decimal, divide by 12 for a monthly rate, then apply the standard amortization formula. If you need simple interest totals instead, call /convert for a quick comparison between SELIC and another benchmark.
Build your SELIC-powered features today. Explore the MCP, then Register to get your API key. For quick links, visit interestratesapi.com or Get started with Interest Rates API.


