Aprovação, presidente (1º e 2º turno) e governadores em JSON
A Índice CNN API entrega as séries do Índice CNN em JSON pronto para GC, dashboard ou template: aprovação do presidente, intenção de voto para presidente no 1º e no 2º turno, e para governador em cada estado. Cada rota devolve a lista de candidatos (com partido) e a série histórica de percentuais.
Base: https://indice-cnn.api.insyde.one — todas as rotas de dados exigem ?key=.
empresa:hash e vai na query
string: ?key=cnn:xxxxxxxxxx. É individual por cliente — não publique em repositório,
front-end aberto ou template compartilhado. Sem chave (ou com chave inválida) a resposta é
401. Só /health é aberta.
| Rota | Retorna |
|---|---|
GET /aprovacao-lula | Série de aprovação e desaprovação |
GET /presidente | Intenção de voto p/ presidente — 1º turno |
GET /presidente-2t | Intenção de voto p/ presidente — 2º turno, por cenário |
GET /governadores | Intenção de voto p/ governador, por estado |
GET /health | Status do serviço — sem chave, sem cache |
A barra final é tolerada (/presidente = /presidente/). CORS é liberado,
então dá para chamar direto do browser. Rota inexistente → 404.
/aprovacao-lula
Duas visões da mesma história: pesquisas traz cada levantamento individual com o
instituto que assina, e indiceCNN traz a série mensal consolidada — use esta para a
linha do gráfico e aquela para citar a fonte.
GET /aprovacao-lula?key=cnn:xxxxxxxxxx
{
"aprovacao_lula": {
"pesquisas": [
{ "Instituto": "PoderData", "Data": "31/01/2023", "Aprovação": 52, "Desaprovação": 39 },
{ "Instituto": "IPESPE", "Data": "14/02/2023", "Aprovação": 51, "Desaprovação": 36 }
// ~198 registros desde jan/2023
],
"indiceCNN": [
{ "Data": "jan.-23", "Aprovação": 52, "Desaprovação": 39 },
{ "Data": "fev.- 23", "Aprovação": 54, "Desaprovação": 32 }
// ~47 pontos mensais
]
}
}
last_updated — a referência temporal é o
último ponto da série. E atenção ao formato da data: pesquisas usa
DD/MM/AAAA, indiceCNN usa mês-AA.
/presidenteGET /presidente?key=cnn:xxxxxxxxxx
{
"last_updated": "2026-08-20T20:04:34.145Z",
"presidente": {
"candidates": [
{ "name": "Lula", "party": "PT" },
{ "name": "Flávio Bolsonaro", "party": "PL" },
{ "name": "Ronaldo Caiado", "party": "PSD" }
// 15 candidatos, em ordem
],
"indiceCNN": [
{ "Data": "06/07/2026", "Lula": 41, "Flávio Bolsonaro": 31, "Ronaldo Caiado": 4 /* … */ }
// um objeto por data de apuração
]
}
}
indiceCNN são os nomes dos candidatos, não IDs. Para
montar o gráfico, percorra candidates (que define a ordem e o partido) e busque
ponto[candidate.name].
/presidente-2tO 2º turno é organizado por cenário de confronto. Cada cenário é independente: tem sua própria dupla de candidatos e sua própria série.
| Param | Padrão | Descrição |
|---|---|---|
key | — | Obrigatório. |
cenarios | todos | Filtra os cenários. Vários separados por vírgula; não diferencia maiúsculas/minúsculas. |
GET /presidente-2t?key=cnn:xxxxxxxxxx // todos os cenários
GET /presidente-2t?cenarios=lula_zema&key=… // só um
GET /presidente-2t?cenarios=lula_zema,lula_caiado&key=… // dois
| Chave | Confronto |
|---|---|
lula_flavio | Lula (PT) x Flávio Bolsonaro (PL) |
lula_caiado | Lula (PT) x Ronaldo Caiado (PSD) |
lula_zema | Lula (PT) x Romeu Zema (Novo) |
lula_renan | Lula (PT) x Renan Santos (Missão) |
// GET /presidente-2t?cenarios=lula_zema&key=…
{
"last_updated": "2026-08-20T20:04:36.422Z",
"segundo_turno": {
"cenarios": {
"lula_zema": {
"label": "Lula x Romeu Zema",
"candidates": [
{ "name": "Lula", "party": "PT" },
{ "name": "Romeu Zema", "party": "Novo" }
],
"indiceCNN": [
{ "Data": "12/08/2026", "Lula": 47, "Romeu Zema": 37 }
]
}
}
}
}
Use label direto como título do GC — ele já vem no formato
"Lula x Romeu Zema".
200 com "cenarios": {}. O last_updated
é sempre preservado, mesmo com filtro.
/governadoresMesma estrutura do presidente, replicada por UF.
| Param | Padrão | Descrição |
|---|---|---|
key | — | Obrigatório. |
estados | todos | Filtra por UF. Várias separadas por vírgula; não diferencia maiúsculas/minúsculas. |
GET /governadores?estados=MG,SP&key=cnn:xxxxxxxxxx
{
"last_updated": "2026-08-20T18:27:24.744Z",
"governadores": {
"MG": {
"candidates": [
{ "name": "Cleitinho", "party": "Republicanos" },
{ "name": "Alexandre Kalil", "party": "PDT" }
// … demais candidatos
],
"indiceCNN": [
{ "Data": "23/06/2026", "Cleitinho": 34, "Alexandre Kalil": 14 /* … */ }
]
}
// … demais estados
}
}
26 UFs disponíveis: AC AL AM AP BA CE DF ES GO MA MG MS MT PA PB PE PI PR RJ RN RO RS SC SE SP TO
RR) ou sigla inválida é omitida da resposta, sem erro — pedir
só siglas inexistentes retorna 200 com "governadores": {}.
JavaScript (fetch):
const BASE = 'https://indice-cnn.api.insyde.one';
const KEY = 'cnn:xxxxxxxxxx';
// um cenário de 2º turno, pronto para o GC
const res = await fetch(`${BASE}/presidente-2t?cenarios=lula_zema&key=${KEY}`);
if (!res.ok) throw new Error((await res.json()).error);
const { last_updated, segundo_turno } = await res.json();
const cenario = segundo_turno.cenarios.lula_zema;
const ultimo = cenario.indiceCNN.at(-1);
// título + barras, na ordem oficial dos candidatos
const titulo = cenario.label; // "Lula x Romeu Zema"
const barras = cenario.candidates.map(c => ({
nome: c.name, partido: c.party, pct: ultimo[c.name]
}));
Python (requests):
import requests
BASE = "https://indice-cnn.api.insyde.one"
KEY = "cnn:xxxxxxxxxx"
r = requests.get(f"{BASE}/governadores", params={"estados": "MG,SP", "key": KEY})
r.raise_for_status()
for uf, dados in r.json()["governadores"].items():
ultimo = dados["indiceCNN"][-1]
print(uf, ultimo["Data"])
for c in dados["candidates"]:
print(f" {c['name']} ({c['party']}): {ultimo[c['name']]}%")
| HTTP | Corpo | Quando |
|---|---|---|
401 | {"error":"unauthorized"} | ?key= ausente ou inválida |
404 | {"error":"not found"} | Rota inexistente |
502 | {"error":"upstream fetch failed"} | Origem indisponível ou timeout (8 s) |
502 | {"error":"invalid upstream response"} | Origem respondeu algo que não é JSON válido |
public, max-age=60, s-maxage=180 —
a CDN revalida a cada 3 min, o navegador a cada 60 s. Erros e /health nunca são
cacheados. O cache é por URL completa, então
?cenarios=lula_zema e ?cenarios=lula_caiado são entradas distintas:
filtrar no servidor é mais barato que baixar tudo e filtrar no cliente.
Os dados mudam algumas vezes ao dia. Consultar mais de uma vez por minuto não traz informação nova — a CDN devolve a mesma resposta.