Com um único endpoint, você monta a Curva de Juros brasileira inteira — nominal e real. Nada de baixar CSV, nada de código por título. Só
?indexer=prefixadoe?indexer=ipca.
A Curva de Juros é o gráfico mais útil da renda fixa. Ela mostra qual taxa o mercado paga em cada prazo. É a chamada curva de juros (gráfico que mostra qual taxa o mercado paga em cada prazo) ou estrutura a termo. Em uma só linha, você lê o que o mercado pensa sobre juros futuros, inflação e risco.
No Brasil, você monta a curva com dois grupos de títulos do Tesouro Direto. O Tesouro Prefixado dá a taxa nominal (o juro do papel, sem descontar inflação). O Tesouro IPCA+ dá a taxa real (o juro acima da inflação, ou seja, o que você ganha além da subida de preços).
Este tutorial mostra como pegar as duas curvas inteiras com duas chamadas
HTTP ao endpoint /api/v2/treasury/list. Você vai tabular por vencimento,
calcular a inflação implícita (a inflação que o mercado está prevendo,
calculada na hora a partir das taxas) e plotar tudo. Todos os números
foram coletados ao vivo na base de 15/05/2026.
Por que a curva de juros importa
A curva está por trás de quase toda decisão de renda fixa. Veja as leituras diretas que você consegue fazer:
- Marcar a carteira a mercado. Prefixado e IPCA+ são marcados pela taxa do vencimento. Se a curva inteira sobe, o preço do título cai.
- Antecipar o COPOM. O começo da curva (até 24 meses) mostra a Selic que o mercado espera. Curva subindo é expectativa de alta. Curva caindo é expectativa de corte.
- Saber o juro real travado. O
buyRatede um Tesouro IPCA+ é, por definição, a taxa real anual que você trava se levar o título até o fim. - Calcular a inflação implícita. A diferença entre a curva Prefixado e a curva IPCA+ revela quanto de inflação o mercado prevê em cada prazo.
- Construir benchmarks e fatores de risco. O nível e a inclinação da curva entram em modelos de atribuição, ALM e VaR no mercado.
Endpoint base: /api/v2/treasury/list
A reconstrução da curva começa em um único endpoint. Ele devolve a lista
completa de títulos ofertados hoje. Vem com a taxa indicativa, o preço
unitário e o durationDays (dias corridos até o vencimento) já calculados
para você.
Curva nominal: ?indexer=prefixado
curl -H "Authorization: Bearer $BRAPI_TOKEN" \
"https://brapi.dev/api/v2/treasury/list?indexer=prefixado&sortBy=maturityDate&sortOrder=asc&limit=30"Resposta (3 primeiros itens, base 15/05/2026):
{
"results": [
{
"symbol": "tesouro-prefixado-01012027",
"bondType": "Tesouro Prefixado",
"indexer": "prefixado",
"couponType": "zero",
"maturityDate": "2027-01-01",
"durationDays": 231,
"baseDate": "2026-05-15",
"buyRate": 13.96,
"sellRate": 14.08,
"buyPrice": 921.33,
"sellPrice": 920.24,
"basePrice": 920.24,
"rateInfo": {
"rateType": "nominalAnnualRate",
"rateUnit": "% a.a.",
"description": "Para Tesouro Prefixado, buyRate e sellRate representam a taxa nominal anual contratada."
}
},
{
"symbol": "tesouro-prefixado-01012028",
"bondType": "Tesouro Prefixado",
"indexer": "prefixado",
"couponType": "zero",
"maturityDate": "2028-01-01",
"durationDays": 596,
"baseDate": "2026-05-15",
"buyRate": 13.95,
"sellRate": 14.07,
"buyPrice": 809.0,
"sellPrice": 807.2,
"basePrice": 807.2,
"rateInfo": { "rateType": "nominalAnnualRate", "rateUnit": "% a.a." }
},
{
"symbol": "tesouro-prefixado-01012032",
"bondType": "Tesouro Prefixado",
"indexer": "prefixado",
"couponType": "zero",
"maturityDate": "2032-01-01",
"durationDays": 2057,
"baseDate": "2026-05-15",
"buyRate": 14.29,
"sellRate": 14.41,
"buyPrice": 462.95,
"sellPrice": 461.06,
"basePrice": 461.06,
"rateInfo": { "rateType": "nominalAnnualRate", "rateUnit": "% a.a." }
}
],
"requestedAt": "2026-05-17T23:30:00.000Z",
"took": 41
}Curva real: ?indexer=ipca
curl -H "Authorization: Bearer $BRAPI_TOKEN" \
"https://brapi.dev/api/v2/treasury/list?indexer=ipca&sortBy=maturityDate&sortOrder=asc&limit=30"Resposta (3 itens representativos, base 15/05/2026):
{
"results": [
{
"symbol": "tesouro-ipca-15082026",
"bondType": "Tesouro IPCA+",
"indexer": "ipca",
"couponType": "zero",
"maturityDate": "2026-08-15",
"durationDays": 92,
"baseDate": "2026-05-15",
"buyRate": 9.98,
"sellRate": 10.10,
"rateInfo": {
"rateType": "realAnnualRateOverIpca",
"rateUnit": "% a.a.",
"description": "Para Tesouro IPCA+, buyRate e sellRate representam a taxa real anual acima da inflação medida pelo IPCA."
}
},
{
"symbol": "tesouro-ipca-15082032",
"bondType": "Tesouro IPCA+",
"indexer": "ipca",
"couponType": "zero",
"maturityDate": "2032-08-15",
"durationDays": 2284,
"baseDate": "2026-05-15",
"buyRate": 7.82,
"sellRate": 7.94,
"rateInfo": { "rateType": "realAnnualRateOverIpca", "rateUnit": "% a.a." }
},
{
"symbol": "tesouro-ipca-15052045",
"bondType": "Tesouro IPCA+",
"indexer": "ipca",
"couponType": "zero",
"maturityDate": "2045-05-15",
"durationDays": 6940,
"baseDate": "2026-05-15",
"buyRate": 7.17,
"sellRate": 7.29,
"rateInfo": { "rateType": "realAnnualRateOverIpca", "rateUnit": "% a.a." }
}
],
"requestedAt": "2026-05-17T23:30:00.000Z",
"took": 38
}Cuidado com o significado de buyRate/sellRate
Os campos buyRate e sellRate mudam de significado de acordo com o
indexador. Sempre confira rateInfo.rateType antes de usar o número:
nominalAnnualRate— Prefixado: o juro nominal anual contratado.realAnnualRateOverIpca— IPCA+: o juro real anual, ou seja, o que você ganha acima do IPCA.realAnnualRateOverIgpm— IGP-M (histórico): o juro real anual sobre o IGP-M.spreadOverSelic— Selic: só o spread em p.p. acima da Selic Meta. Não use o Tesouro Selic para montar a curva. Falamos mais sobre isso adiante.
Exemplo em TypeScript: tabular as duas curvas
O script abaixo busca prefixados e IPCA+ em paralelo. Ele mantém só os
títulos sem cupom (você só recebe no vencimento, sem juros no meio do
caminho) — couponType: "zero". Assim cada ponto da curva fica limpo, sem
mistura de fluxo semestral. No fim, ele imprime uma tabela bem organizada,
ordenada por vencimento.
// bun run curve.ts
const TOKEN = process.env.BRAPI_TOKEN!;
const BASE = 'https://brapi.dev';
type TreasuryItem = {
symbol: string;
bondType: string;
indexer: 'selic' | 'prefixado' | 'ipca' | 'igpm';
couponType: 'zero' | 'semestral';
maturityDate: string;
durationDays: number;
baseDate: string;
buyRate: number;
sellRate: number;
buyPrice: number;
sellPrice: number;
basePrice: number;
rateInfo: { rateType: string; rateUnit: string; description: string };
};
type ListResponse = { results: TreasuryItem[] };
async function fetchCurve(
indexer: 'prefixado' | 'ipca',
): Promise<TreasuryItem[]> {
const url =
`${BASE}/api/v2/treasury/list?indexer=${indexer}` +
`&sortBy=maturityDate&sortOrder=asc&limit=30`;
const res = await fetch(url, {
headers: { Authorization: `Bearer ${TOKEN}` },
});
if (!res.ok) throw new Error(`${indexer}: ${res.status}`);
const data = (await res.json()) as ListResponse;
// mantém só zero-cupom para um ponto "limpo" por vencimento
return data.results.filter((r) => r.couponType === 'zero');
}
const [pref, ipca] = await Promise.all([
fetchCurve('prefixado'),
fetchCurve('ipca'),
]);
function printCurve(title: string, items: TreasuryItem[]) {
console.log(`\n${title}`);
console.log(
'symbol'.padEnd(38),
'maturity'.padEnd(11),
'days',
'buy%',
'sell%',
);
for (const r of items) {
console.log(
r.symbol.padEnd(38),
r.maturityDate.padEnd(11),
String(r.durationDays).padStart(4),
r.buyRate.toFixed(2).padStart(5),
r.sellRate.toFixed(2).padStart(5),
);
}
}
printCurve('Curva Prefixado (nominal a.a.)', pref);
printCurve('Curva IPCA+ (real a.a. sobre IPCA)', ipca);Saída real (base 15/05/2026):
Curva Prefixado (nominal a.a.)
symbol maturity days buy% sell%
tesouro-prefixado-01012027 2027-01-01 231 13.96 14.08
tesouro-prefixado-01012028 2028-01-01 596 13.95 14.07
tesouro-prefixado-01012029 2029-01-01 962 14.07 14.19
tesouro-prefixado-01012031 2031-01-01 1692 14.21 14.33
tesouro-prefixado-01012032 2032-01-01 2057 14.29 14.41
Curva IPCA+ (real a.a. sobre IPCA)
symbol maturity days buy% sell%
tesouro-ipca-15082026 2026-08-15 92 9.98 10.10
tesouro-ipca-15052029 2029-05-15 1096 7.95 8.07
tesouro-ipca-15082032 2032-08-15 2284 7.82 7.94
tesouro-ipca-15052035 2035-05-15 3287 7.58 7.70
tesouro-ipca-15082040 2040-08-15 5206 7.27 7.39
tesouro-ipca-15052045 2045-05-15 6940 7.17 7.29O que essa foto da curva está dizendo:
- A curva prefixado sobe um pouquinho com o prazo. Ela começa em 13,95% a.a. no vencimento de jan/2028 (596 dias) e chega a 14,29% a.a. em jan/2032. O mercado pede um pequeno prêmio extra para travar a taxa por mais tempo.
- A curva IPCA+ cai forte com o prazo. O título muito curto (ago/2026, 92 dias) sai a 9,98% real a.a.. Esse número é anômalo: ele aparece no pedacinho final do papel e não vale como referência da curva longa. Já o vencimento longo (mai/2045) paga 7,17% real a.a.. Se você tira o ponto curto de 92 dias, a curva real "limpa" vai de ~7,95% (2029) a ~7,17% (2045) — descendente.
A curva Prefixado em um gráfico
Cada barra mostra o buyRate (taxa de compra) do Tesouro Prefixado para o
ano de vencimento. A leitura simples: travar a taxa hoje por 4 anos (até
jan/2028) paga 13,95% ao ano. Travar por 6 anos (até jan/2032) paga
14,29% ao ano. A diferença pequena é o prêmio extra que o mercado pede para
você esperar mais tempo.
A curva IPCA+ em um gráfico
Aqui usamos a curva "limpa" (sem o ponto anômalo de 92 dias). Note que ela desce conforme o prazo aumenta: a NTN-B 2029 paga 7,95% real ao ano e a NTN-B 2045 paga só 7,17%. Por que ela desce? Porque o mercado espera taxas reais mais baixas no longo prazo. A ideia é que, com inflação e Selic voltando para níveis menores no futuro, o juro real exigido também cai.
Exemplo em Python: DataFrame + gráfico opcional
Se você prefere pandas e matplotlib, dá para ter tabela e gráfico em
poucas linhas. O script abaixo monta um DataFrame por curva, calcula a
inflação implícita par a par e salva a figura em curva.png (se você tiver
matplotlib instalado).
# python3 curve.py
import os
import urllib.parse
import urllib.request
import json
TOKEN = os.environ["BRAPI_TOKEN"]
BASE = "https://brapi.dev"
def fetch_curve(indexer: str) -> list[dict]:
params = urllib.parse.urlencode({
"indexer": indexer,
"sortBy": "maturityDate",
"sortOrder": "asc",
"limit": 30,
})
req = urllib.request.Request(
f"{BASE}/api/v2/treasury/list?{params}",
headers={"Authorization": f"Bearer {TOKEN}"},
)
with urllib.request.urlopen(req) as resp:
data = json.load(resp)
return [r for r in data["results"] if r["couponType"] == "zero"]
prefixado = fetch_curve("prefixado")
ipca = fetch_curve("ipca")
# Opcional: organize em DataFrame
import pandas as pd
pref_df = pd.DataFrame(prefixado)[
["symbol", "maturityDate", "durationDays", "buyRate", "sellRate"]
]
ipca_df = pd.DataFrame(ipca)[
["symbol", "maturityDate", "durationDays", "buyRate", "sellRate"]
]
print(pref_df.to_string(index=False))
print(ipca_df.to_string(index=False))
# Inflação implícita (Fisher) pareando por ano de vencimento
ipca_by_year = {r["maturityDate"][:4]: r for r in ipca}
print(f"\n{'ano':6s} {'nominal%':>10s} {'real%':>10s} {'breakeven%':>12s}")
for p in prefixado:
year = p["maturityDate"][:4]
if year not in ipca_by_year:
continue
i = ipca_by_year[year]
nominal = p["buyRate"] / 100
real = i["buyRate"] / 100
breakeven = (1 + nominal) / (1 + real) - 1
print(
f"{year:6s} {p['buyRate']:10.2f} {i['buyRate']:10.2f}"
f" {breakeven * 100:12.2f}"
)
# Gráfico (salve em curva.png)
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot([r["durationDays"] for r in prefixado],
[r["buyRate"] for r in prefixado],
marker="o", label="Prefixado (nominal)")
ax.plot([r["durationDays"] for r in ipca],
[r["buyRate"] for r in ipca],
marker="s", label="IPCA+ (real)")
ax.set_xlabel("Duração (dias até o vencimento)")
ax.set_ylabel("Taxa indicativa de compra (% a.a.)")
ax.set_title("Curva de juros — Tesouro Direto (brapi.dev)")
ax.legend(); ax.grid(True, alpha=0.3); fig.tight_layout()
fig.savefig("curva.png", dpi=120)Inflação implícita (breakeven)
Quando o mercado precifica ao mesmo tempo uma curva nominal (Prefixado) e uma curva real (IPCA+) para o mesmo prazo, ele acaba revelando, sem dizer em voz alta, quanta inflação ele está esperando naquele período. Essa é a inflação implícita (a inflação que o mercado está prevendo, calculada na hora a partir das taxas). A conta vem da equação de Fisher:
Isolando a inflação implícita:
Aplicando a fórmula aos pares disponíveis na foto de 15/05/2026 (usando
buyRate nas duas curvas):
| Vencimento | Nominal (Prefixado) | Real (IPCA+) | Inflação implícita |
|---|---|---|---|
| 2029 | 14,07% | 7,95% | 5,67% |
| 2031 | 14,21% | 7,95% (proxy 2031) | 5,80% |
| 2032 | 14,29% | 7,91% (proxy 2032) | 5,91% |
A inflação implícita em um gráfico
É a inflação que o mercado está prevendo daqui até o vencimento de cada título. Em 15/05/2026, o mercado precificava inflação anual média entre 5,7% e 5,9% para os próximos 3 a 6 anos. Isso é bem acima da meta de 3% do CMN.
Como você usa isso na prática? Se você acha que a inflação vai ficar abaixo desse breakeven, o Prefixado tende a render mais que o IPCA+ no mesmo prazo. Se você acha que vai ficar acima, o IPCA+ é o melhor negócio. É uma aposta direta na sua visão de inflação.
Atenção: o par de vencimentos não é perfeito
Tesouro Prefixado vence em 1º de janeiro. Tesouro IPCA+ vence em
15 de maio ou 15 de agosto. Por isso, é raro achar dois títulos com
exatamente o mesmo dia. Para um breakeven mais preciso, faça interpolação
por durationDays. O par "por ano" acima já serve para dashboards e
comunicação interna.
Cuidado: Tesouro Selic não entra na curva
Não plote o Tesouro Selic na curva nominal
Nos mesmos dados, o Tesouro Selic 2027 aparece com buyRate: 0.01 e
sellRate: 0.02. Esses números não são o juro anual do título. São só
o spread em p.p. acima da Selic Meta (rateInfo.rateType: "spreadOverSelic").
Como o título é pós-fixado, o rendimento real dele é sempre "a Selic do período + um spreadzinho". Ninguém sabe a Selic do futuro. Por isso, ele não dá um ponto fixo na curva nominal e é filtrado da estrutura a termo.
Se você quiser plotar a Selic Meta atual como "ponto curto" no gráfico, basta usar o endpoint de macroeconomia:
curl -H "Authorization: Bearer $BRAPI_TOKEN" \
"https://brapi.dev/api/v2/macro/latest?symbols=selic"E plote em durationDays = 0 para indicar a política monetária de hoje.
Frequência de atualização
/api/v2/treasury/list: o servidor da brapi guarda em cache por 15 minutos.- Fonte: o Tesouro Transparente publica as taxas indicativas uma vez por dia útil, depois que a janela de negociação fecha. Não existe "tick" intradia desses títulos — não tente buscar.
- Histórico diário: se você precisa de uma série temporal (por
exemplo, ver como a curva andou no último mês), use
/api/v2/treasury/indicators/historycomstartDateeendDate.
Para dashboards e relatórios, atualizar a cada 1 hora cobre todos os casos. Para batch noturno, basta uma chamada por dia depois das 19h.
Próximos passos
- Documentação canônica: Guia de Tesouro Direto na brapi
- Indicadores macro brasileiros (Selic, IPCA, CDI…): API de Macroeconomia 2026
- Marcação a mercado de carteira CDI/CDB: CDI Histórico via API
- Visão de produto e cobertura: Tesouro Direto — Guia Completo 2026
Com duas chamadas HTTP você passa a ter a curva nominal e a curva real do Brasil na mão. A partir daí, montar breakeven, fazer ALM, marcar a carteira a mercado ou rodar uma calculadora de juro real vira uma linha de código.
Crie ou atualize sua conta em brapi.dev para pegar um token Pro e testar direto em produção. Os exemplos deste post foram coletados da API real e rodam sem ajuste nenhum.
