API Pública v1
A API pública do Futuros é dado estático versionado. O Futuros é uma plataforma somente-frontend: não há servidor de consultas por trás de /api/v1/. Tudo é assado a partir de public/data/ por scripts/bake-api.ts e servido como arquivos simples pela CDN. Um portão pós-bake (scripts/check-api.ts, executado no mesmo passo de prebuild) verifica que o bake corresponde ao corpus — as contagens de citações batem, cada célula está coberta, os dumps em massa fazem parse, generated_at é pelo menos tão novo quanto o arquivo de dados mais recente — e falha o build diante de qualquer desvio, de modo que a árvore servida não pode ficar defasada. Cada endpoint abaixo é um simples HTTP GET de um arquivo — sem auth, sem chave de API, sem rate limit, totalmente cacheável.
- URL base:
https://futuros.xyz/api/v1/ - Descoberta (catálogo DCAT):
https://futuros.xyz/data.json(na raiz do site, não sob/api/v1/) - Página de docs para humanos:
https://futuros.xyz/datos-abiertos?lang=pt
Como as respostas são arquivos estáticos, um endpoint é apenas o seu caminho. Busque um com curl, um navegador, fetch(), pandas.read_csv, R, ou qualquer cliente SDMX/DCAT.
Como a árvore é assada
bake-api.ts e depois check-api.ts rodam como os dois passos finais do prebuild (após o typecheck, a suíte de testes e os demais portões de dados), de modo que cada deploy re-assa /api/v1 a partir do public/data/ atual e prova o resultado antes que o vite build o embarque:
Invariantes do bake (scripts/bake-api.ts):
- Promoção atômica. A árvore inteira é escrita em
public/api/v1.tmp(maispublic/data.json.tmp) e trocada sobre os caminhos vivos comrenameSynccomo o último passo. Uma queda no meio do bake deixa a árvore anterior intacta — o fluxo antigo de apagar-e-repopular podia embarcar um/api/v1escrito pela metade. - Fonte da célula. Uma célula = um envelope
public/data/parameter-cache/<param>__<ISO3>.json; uma célula cujo payload não tem indicadores é pulada (o portão as conta como legitimamente ausentes, não como faltantes). - Achatamento em linhas. Uma linha CSV/SDMX por (indicador, ano). Anos duplicados dentro de uma série são descartados (a primeira ocorrência vence), e a linha da safra mais recente só é anexada quando a série ainda não contém aquele ano — um valor nunca é emitido duas vezes.
- Neutralização de injeção de fórmulas (OWASP). Qualquer célula de texto começando com
=+-@(ou tab/CR inicial) recebe o prefixo'antes de chegar ao CSV ou XLSX, para que Excel/Sheets/LibreOffice a renderizem como texto literal em vez de executá-la como fórmula. Números passam intocados. - Colunas somente anexadas. Novas colunas CSV são anexadas, nunca inseridas (
label_en,label_ptficam depois decitation_id), então parsers posicionais continuam funcionando e parsers por nome de cabeçalho captam as adições. - M49 vem assado. O mapa ISO3→M49 é uma tabela fixa de 26 entradas no baker (25 países +
LATAM=419), não um lookup em tempo de execução.
O que check-api.ts verifica (qualquer falha imprime um diff e sai com 1):
| # | Asserção | Desvio que bloqueia |
|---|---|---|
| 1 | index.json.counts.citations = comprimento de public/data/citations.json | manifesto fora de sincronia com o registro de citações |
| 2 | toda célula de cache não vazia tem seu observations/<param>__<ISO3>.json assado | células descartadas silenciosamente |
| 3 | CSV/SDMX/XLSX em massa existem, não estão vazios e fazem parse (CSV: cabeçalho + ≥1 linha; XLSX: abre) | dumps em massa corrompidos |
| 4 | mtime do arquivo index.json ≥ mtime mais novo de public/data − tolerância de 5 min | bake defasado. Comparado mtime-vs-mtime porque checkouts do git reescrevem os mtimes dos arquivos de dados — a comparação antiga por generated_at falhava falsamente em checkouts frescos |
| 5 | linhas de observação < 1.000.000 | estourar o teto de planilha única do XLSX (1.048.576 linhas) |
| 6 | toda referência a persona/caso do índice de busca resolve para um arquivo em disco | acertos de recuperação mortos (137 refs de persona mortas embarcaram em julho de 2026) |
| 7 | rótulos ES/EN/PT completos e com correspondência exata ao registro de métricas, com piso de cobertura de instâncias ≥90% | a API pública regredir a somente-espanhol, ou um join de rótulos silenciosamente dessincronizado |
Contrato de estabilidade
O manifesto o declara literalmente:
Shapes are additive-only within v1; breaking changes go to
/api/v2/.
Na prática:
- Campos podem ser adicionados a qualquer objeto dentro da v1. Não assuma um conjunto fixo de chaves — leia por chave, ignore desconhecidas.
- Nomes, tipos e significados de campos existentes não mudarão dentro da v1.
- Uma mudança incompatível (renomear/remover um campo, mudar unidades ou semântica) sai como uma nova árvore
/api/v2/;/api/v1/continua funcionando. index.jsoncarregaapi_version,generated_ate uma stringstability— leiagenerated_atpara detectar um rebuild.
CORS e cache
Definido em vercel.json para o caminho /api/v1/(.*):
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Cache-Control: public, max-age=3600, s-maxage=86400Portanto a API de leitura é legível cross-origin de qualquer app de navegador (somente GET/OPTIONS — ela é somente-leitura), com cache de borda por um dia. Não há superfície de escrita aqui. Os endpoints dinâmicos (/api/chat, /api/mcp, …) definem seus próprios cabeçalhos em código; desses, apenas /api/mcp é cross-origin (*, POST, OPTIONS) — os demais são same-origin.
Licença e atribuição
De index.json:
license_url:https://creativecommons.org/licenses/by/4.0/(CC BY 4.0)license(literal): "Datos redistribuidos de fuentes abiertas; cada observación conserva su fuente primaria (source_name,source_url,citation_id). Al reutilizar: cite la fuente primaria de cada observación y «Futuros» como agregador."
Em português: os dados são redistribuídos de fontes abertas; cada observação conserva sua fonte primária (nome, URL de deep-link e citation_id). Ao reutilizá-los, cite a fonte primária de cada observação e credite o Futuros como agregador. Nada é imputado ou sintetizado — o contrato de honestidade do baker é que todo valor no fio carrega a fonte de onde veio.
Padrões de interoperabilidade
index.json → standards declara os códigos que a API fala, para que UNSD-SDG, World Bank Data360, OECD.AI e CEPALSTAT possam ingeri-la diretamente:
| Padrão | Onde |
|---|---|
REF_AREA = M49 numérico da ONU + alpha-3 ISO 3166-1 | toda geografia e observação |
| Marco global de indicadores ODS (A/RES/71/313) | bloco sdg por indicador + sdg-crosswalk.json |
| SDMX-CSV (ISO 17369) | observations.sdmx.csv |
| DCAT (project-open-data v1.1) | /data.json |
O manifesto — index.json
Comece aqui. Ele lista cada dataset, contagens ao vivo, a licença, a declaração de estabilidade e um mapa endpoints legível por máquina (templates de caminho para o restante).
curl -s https://futuros.xyz/api/v1/index.json{
"name": "Futuros — API de datos abiertos",
"api_version": "1",
"generated_at": "2026-08-29T04:17:28.143Z",
"docs": "/datos-abiertos",
"license": "Datos redistribuidos de fuentes abiertas; …",
"license_url": "https://creativecommons.org/licenses/by/4.0/",
"delta_basis": "latest value vs mean of the prior 3 years (smooths COVID-era volatility)",
"stability": "Shapes are additive-only within v1; breaking changes go to /api/v2/.",
"languages": ["es", "en", "pt"],
"label_fields": { "parameters": ["name_es", "name_en", "name_pt"],
"geographies": ["name_es", "name_en", "name_pt"],
"observations": ["label_es", "label_en", "label_pt"] },
"standards": {
"ref_area": "UN M49 numeric (REF_AREA) + ISO 3166-1 alpha-3",
"sdg": "UN SDG global indicator framework (A/RES/71/313); see /api/v1/sdg-crosswalk.json",
"sdmx": "SDMX-CSV (ISO 17369) at /api/v1/observations.sdmx.csv",
"catalog": "DCAT (project-open-data v1.1) at /data.json"
},
"counts": {
"parameters": 10, "geographies": 26, "cells": 260,
"observations": 397898, "sdg_tagged_indicator_instances": 2848,
"citations": 15098, "signal_files": 260, "governance_datasets": 3, "contributions": 0
},
"bulk": {
"observations_csv": { "path": "/api/v1/observations.csv", "bytes": 170533700, "rows": 397898 },
"observations_sdmx_csv": { "…": "…" }, "workbook_xlsx": { "…": "…" }
},
"endpoints": { "openapi": "/api/v1/openapi.json", "schemas": "/api/v1/schemas/",
"parameters": "/api/v1/parameters.json", "…": "…" }
}counts.geographies é 26 porque os 25 países incluem o agregado regional LATAM (M49 419). Uma célula é um parâmetro × uma geografia; uma observação é uma linha indicador-ano.
O bloco bulk carrega bytes + contagens de linhas de cada dump em massa — atualmente cerca de 171 MB (observations.csv), 111 MB (observations.sdmx.csv) e 91 MB (futuros-data.xlsx), ~398 mil linhas cada — então consulte-o antes de iniciar um download em massa. languages + label_fields (o substituto legível por máquina da antiga nota em prosa language_coverage) declaram que todo parâmetro e geografia carrega name_es/name_en/name_pt e toda observação label_es/label_en/label_pt. label_es é o rótulo canônico do payload e nunca é renomeado; os irmãos EN/PT são unidos a partir de public/data/metrics/registry.json por indicator_id e são null (JSON) / vazios (CSV) para ids que o registro ainda não cobre. Contagens e tamanhos aqui são ilustrativos; o manifesto ao vivo é o autoritativo.
Contrato legível por máquina — openapi.json e schemas/
O próprio contrato da v1 é publicado como dado, listado primeiro em index.json → endpoints:
/api/v1/openapi.json— spec OpenAPI 3.1.0 cobrindo 15 caminhos centrais de leitura (sdg-crosswalk.json,citations.csve o catálogo DCAT/data.jsonainda não estão na spec)./api/v1/schemas/{manifest,parameter,geography,observation-cell,citation}.schema.json— JSON Schema para cada forma de resposta.
Aponte uma ferramenta de codegen ou validação para eles em vez de transcrever formas à mão a partir desta página.
Parâmetros — parameters.json
Os 10 pilares do Futuros, em ordem de exibição, cada um com seus ODS primários/secundários.
curl -s https://futuros.xyz/api/v1/parameters.json[
{ "slug": "salud", "name_es": "Salud", "name_en": "Salud",
"display_order": 1, "sdg_primary": [3], "sdg_secondary": [2, 6] },
{ "slug": "educacion", "name_es": "Educación", "…": "…" }
]Use slug (por exemplo salud, educacion, cohesion-social-inclusion) como o segmento <param> nos caminhos de observações.
Geografias — geographies.json
Os 25 países mais a região LATAM, cada um com ISO3 e M49.
curl -s https://futuros.xyz/api/v1/geographies.json[
{ "iso3": "LATAM", "m49": "419", "slug": "latam",
"name_es": "América Latina y el Caribe", "name_en": "Latin America and the Caribbean",
"level": "region", "sub_region": null, "population_2024": null },
{ "iso3": "ARG", "m49": "032", "slug": "arg", "level": "country", "…": "…" }
]Os slugs de países são o ISO3 em minúsculas (arg, mex, bra; a região é latam). Use iso3 (por exemplo MEX, ARG, BRA) como o segmento <ISO> nos caminhos de observações. Códigos M49 são strings com zeros à esquerda ("032", "484").
Observações — uma célula
O dataset central. Um arquivo por parâmetro × país, endereçado como observations/<param>__<ISO3>.json (note o separador de underscore duplo).
JSON
curl -s https://futuros.xyz/api/v1/observations/salud__MEX.json{
"api_version": "1",
"generated_at": "2026-08-29T04:17:28.143Z",
"parameter": { "slug": "salud", "label_es": "Salud" },
"geography": { "iso3": "MEX", "m49": "484", "name_es": "México",
"name_en": "México", "level": "country" },
"confidence": "high",
"last_refreshed": "2026-06-15T16:20:52.364Z",
"indicators": [
{
"indicator_id": "sp_dyn_le00_in",
"label_es": "Esperanza de vida al nacer",
"label_en": "Life expectancy at birth",
"label_pt": "Expectativa de vida ao nascer",
"unit": "años",
"latest": { "year": 2024, "value": 75.264 },
"delta_pct": 3.199,
"delta_basis": "latest value vs mean of the prior 3 years (smooths COVID-era volatility)",
"good_direction": "up",
"coverage": "primary",
"benchmark": { "oecd": 80.39, "world": 73.48, "sea_peers": 73.87, "oecd_vintage": 2024 },
"sdg": { "code": "3", "level": "goal",
"indicator_name": "Ensure healthy lives and well-being …", "goal": 3 },
"source": {
"name": "World Bank Open Data",
"url": "https://data.worldbank.org/indicator/SP.DYN.LE00.IN?locations=MX",
"citation_id": "wb-sp-dyn-le00-in-mex-2024"
},
"series": [ { "year": 2000, "value": 72.562 }, { "year": 2001, "value": 72.912 }, "…" ]
}
]
}Cada indicador carrega latest (ano + valor), a series completa até ~2000, sua source (nome + deep-link para a fonte primária + citation_id), um código sdg oficial quando existe (level é indicator, target ou goal) e delta_pct (veja delta_basis: valor mais recente vs. a média dos 3 anos anteriores). sdg é null quando nenhum código ODS oficial se aplica — nunca fabricado.
CSV
A mesma célula achatada em uma linha por indicador-ano:
curl -s https://futuros.xyz/api/v1/observations/salud__MEX.csvCabeçalho:
parameter,iso3,m49,indicator_id,label_es,unit,year,value,delta_pct_latest,
good_direction,coverage,vintage_year,sdg_code,sdg_level,source_name,source_url,citation_id,
label_en,label_ptlabel_en,label_pt ficam no final da linha — a ordem das colunas faz parte do contrato CSV, então adições são sempre anexadas, nunca inseridas.
Observações — em massa
Todas as células concatenadas em um único CSV — o corpus inteiro em um só download (~164 mil linhas):
curl -s https://futuros.xyz/api/v1/observations.csv -o futuros-observations.csvMesmo cabeçalho do CSV por célula. Carregue diretamente:
import pandas as pd
df = pd.read_csv("https://futuros.xyz/api/v1/observations.csv")Observações — SDMX-CSV
Os dados em massa como SDMX-CSV (ISO 17369), com REF_AREA chaveado no M49 da ONU para casar com as convenções da UNSD-SDG / Data360:
curl -s https://futuros.xyz/api/v1/observations.sdmx.csvDATAFLOW,FREQ,REF_AREA,INDICATOR,TIME_PERIOD,OBS_VALUE,UNIT_MEASURE,
SDG_INDICATOR,REF_AREA_ISO3,FUTUROS_PARAMETER,SOURCE,SOURCE_URL,CITATION_ID
FUTUROS:DF_OBSERVATIONS(1.0),A,032,si_pov_gini,2000,51,índice,10,ARG,
cohesion-social-inclusion,World Bank Open Data,https://data.worldbank.org/…,wb-si-pov-gini-arg-2024DATAFLOW é FUTUROS:DF_OBSERVATIONS(1.0), FREQ é A (anual).
Pasta de trabalho Excel — futuros-data.xlsx
Uma pasta de trabalho com cinco planilhas — README (licença + base do delta_pct), parameters, geographies, observations (todas as linhas) e citations:
curl -s https://futuros.xyz/api/v1/futuros-data.xlsx -o futuros-data.xlsxCitações — citations.json / citations.csv
O registro completo de fontes contra o qual todo citation_id resolve.
curl -s https://futuros.xyz/api/v1/citations.json
curl -s https://futuros.xyz/api/v1/citations.csvColunas do CSV: id,source,title,url,year,retrieved_at. Faça o join do citation_id de observations.* com o id de citations.* para anexar metadados completos de fonte a qualquer valor.
Livro-razão de atualidade — freshness.json
Cadência de atualização por fonte — quando cada indicador foi puxado pela última vez e quando vence o próximo. Um passthrough do refresh-meta.json do build. Chaves de nível superior: generated_at, total_indicators, indicators, mais um bloco sources.
curl -s https://futuros.xyz/api/v1/freshness.json{
"generated_at": "2026-06-15T16:20:52.364Z",
"total_indicators": 48,
"indicators": {
"SI.POV.GINI": {
"source": "World Bank Open Data",
"source_url": "https://data.worldbank.org/indicator/SI.POV.GINI",
"cadence_months": 12,
"last_refreshed": "2026-06-15T16:20:52.364Z",
"next_refresh_due": "2027-08-15T20:11:16.364Z",
"countries_with_data": 0, "total_countries": 25
}
}
}Crosswalk ODS — sdg-crosswalk.json
O mapa verificado de pilares e indicadores para códigos ODS oficiais (goals, pillars, indicators). Faça o join por indicator_id.
curl -s https://futuros.xyz/api/v1/sdg-crosswalk.jsonSinais — signals/<param>__<ISO3>.json
Sinais de "o que está se movendo" por célula, extraídos por LLM e citados (presentes porque a camada multi-fonte é assada). Mesmo endereçamento <param>__<ISO3> das observações, e desde o assamento de 2026-08-05 a cobertura é total: as 260 células têm arquivo (counts.signal_files no manifesto). As 10 células do agregado regional (<param>__LATAM), que a colheita de sinais não escreve, são assadas como array vazio []; antes não tinham arquivo e respondiam HTTP 404. Trate um [] como "esta célula não tem sinais", não como um erro; um 404 sob signals/ agora indica de fato um caminho digitado errado.
curl -s https://futuros.xyz/api/v1/signals/salud__ARG.jsonContribuições — contributions.json
Dados contribuídos por meio do Fundo Fiduciário de Dados (Pilar 1), com portão de licença, publicados apenas para posturas que permitem republicar valores. Atualmente count: 0.
curl -s https://futuros.xyz/api/v1/contributions.jsonMotor de Governança — governance/*.json
Os datasets do Motor de Governança (Pilar 3) fazem parte do contrato versionado desde o assamento de 2026-08-05 (antes só eram acessíveis via MCP ou como arquivo sem versionamento). Cada um é um passthrough do arquivo que a UI consome, servido com o mesmo contrato de estabilidade aditivo, CORS e cache do resto da v1:
| Caminho | O que é |
|---|---|
/api/v1/governance/resilience.json | Índice de Resiliência Democrática: subíndices + composto, citado por país |
/api/v1/governance/regulation-index.json | Observatório Regulatório: instrumentos por país e pilar |
/api/v1/governance/scores.json | Índice composto goalpost por geografia (séries 2010-2024) |
curl -s https://futuros.xyz/api/v1/governance/resilience.jsonA via MCP continua disponível: get_dataset com dataset_id: "democracy-resilience" no servidor MCP retorna o mesmo índice de resiliência com cômputo determinista. O arquivo sem versionamento GET /data/democracy/resilience.json também continua existindo, mas sem contrato de estabilidade; prefira os caminhos /api/v1/governance/ acima.
Descoberta — catálogo DCAT em /data.json
Um catálogo DCAT / project-open-data v1.1 na raiz do site (não sob /api/v1/) para que portais de dados e crawlers descubram os datasets automaticamente:
curl -s https://futuros.xyz/data.jsonEle anuncia os datasets em massa CSV, SDMX-CSV, XLSX, citações, crosswalk ODS e atualidade, cada um com downloadURL, mediaType e licença CC BY 4.0.
Feeds RSS · /feeds/
Os sinais citados também são publicados como 267 feeds RSS 2.0 estáticos sob /feeds/ (na raiz do site, não sob /api/v1/), feitos para leitores RSS e monitoramento institucional. Mesmo regime da API de leitura: GET estático, sem auth, cacheável.
| Caminho | O quê |
|---|---|
/feeds/futuros.xml | Mestre regional: todos os sinais da região em um só feed |
/feeds/<ISO3>.xml | Por país: união de seus 10 feeds de pilar, máximo 50 itens |
/feeds/<param>__<ISO3>.xml | Por célula (pilar × país): sinais citados com deep-link para a fonte |
/feeds/index.json | Manifesto: total_feeds, cells_written, cells_skipped_empty, countries_written, forecasts_included, forecasts_skipped_unverifiable, e feeds[] com título, caminho, tipo e contagem de itens |
curl -s https://futuros.xyz/feeds/salud__BRA.xmlOs feeds não estão mais congelados: scripts/bake-feeds.ts roda dentro da cadeia de prebuild (junto a bake-data-health, bake-source-ledger e bake-api, logo antes de check-api), então são re-assados a cada deploy a partir do corpus de sinais vigente. O manifesto é explícito sobre o que não publicou: cells_skipped_empty conta as células sem sinal — nenhum feed vazio é emitido para simular cobertura — e forecasts_skipped_unverifiable conta as previsões deixadas de fora por não serem verificáveis.
Backlog de lacunas de dados — GET /api/backlog
Diferente de tudo acima, este não é um arquivo assado sob /api/v1/: é uma função ao vivo (api/backlog.ts), porque o que ela serve é gerado em tempo de requisição e não no assado. É documentado aqui porque é público, sem autenticação e somente leitura, como o resto desta página.
Sempre que o assistente consulta o corpus e uma ferramenta do corpus volta vazia, o servidor abre um ticket estruturado em vez de deixar o sinal morrer. Este endpoint é como esse backlog se torna visível — para a SPA (/vacios), para a linha de ingestão que decide o que buscar em seguida, e para quem quiser conferir que um "não temos esse dado" é seguido de algo.
Parâmetros
| Parâmetro | Padrão | O que faz |
|---|---|---|
limit | 100 (máx. 500) | Quantos tickets devolver |
country | — | Filtra por ISO3 (normalizado para maiúsculas) |
pillar | — | Filtra por slug de eixo |
Limite de taxa: 60 requisições por minuto e por IP; ao exceder responde 429 com Retry-After. Cache: s-maxage=60, stale-while-revalidate=300.
Resposta
{
"ok": true,
"configured": true,
"count": 2,
"gaps": [
{
"id": "gap-ecu-medio-ambiente-clima-1a2b3c4d",
"created_at": "2026-08-16T09:12:44.031Z",
"lang": "es",
"country": "ECU",
"pillar": "medio-ambiente-clima",
"route": "/atlas",
"empty": ["get_dataset:regulation", "get_dataset:signals"],
"candidate_sources": [
{ "title": "SIMAS", "url": "https://ambiente.gob.ec/simas", "source": "ambiente.gob.ec", "date": "2026" }
],
"missing_indicators": ["Área com concessão de mineração"],
"hits": 7
}
]
}configured: falsesignifica que o armazenamento durável (Upstash) não está cabeado naquele ambiente:gapsé então o anel em memória daquela instância, nem compartilhado nem persistente. Isso é declarado em vez de fingir que existe um backlog comum.hitsé quantas vezes essa mesma lacuna foi levantada. O id deduplica pela forma do vazio (país + eixo + ferramentas vazias), não pelo texto, então a mesma lacuna perguntada de duas maneiras incrementa um único ticket. Essa ordem por demanda é a fila de ingestão.candidate_sourcescontém apenas URLs que uma ferramenta externa devolveu naquele mesmo turno. Nunca uma fonte que o modelo nomeou de memória.
Sem texto do usuário, por desenho
Um ticket descreve a lacuna, não quem a encontrou. Leva o país, o eixo, a rota, as ferramentas que voltaram vazias e os indicadores ausentes; todos esses campos saem de vocabulário controlado pela plataforma (códigos ISO3, slugs de eixo, chaves de ferramenta, rótulos assados de indicador).
O ticket não persiste nem serve a pergunta do usuário. É lida apenas para estabelecer que houve um turno real, e então descartada. Como este endpoint é público e sem autenticação, qualquer coisa que o ticket conservasse seria algo que quem perguntou publicou sem pretender — e a postura de consentimento do Fideicomisso de Dados tem que valer para quem usa o chat, não só para as instituições que contribuem.
O texto é guardado, mas em outro lugar e sob outras regras: o registro privado de perguntas vive sob uma chave diferente (chat:questions:v1, nunca backlog:gaps:v1) e só é legível com Authorization: Bearer $QUESTION_LOG_TOKEN — sem token, GET /api/questions recusa tudo. Nenhum caminho público o alcança: o backlog reconstrói cada ticket campo a campo, então a garantia deste endpoint fica exatamente a mesma.
A garantia é aplicada na leitura além da escrita: os tickets escritos antes desta regra seguem no armazenamento, então readGaps reconstrói cada linha campo a campo contra uma lista de permitidos e descarta todo o resto. Um campo novo também não pode chegar à superfície pública por acidente: tem que ser adicionado lá de propósito.
Não há superfície de escrita. Os tickets são escritos pelo servidor de chat, no mesmo processo que observou a recuperação vazia; não existe rota de escrita alcançável pelo navegador.
Referência de endpoints
| Caminho | O quê |
|---|---|
/api/v1/index.json | Manifesto: datasets, contagens, tamanhos em massa, licença, padrões |
/api/v1/openapi.json | Spec OpenAPI 3.1 da API de leitura (15 caminhos centrais) |
/api/v1/schemas/*.schema.json | JSON Schema: manifesto, parâmetro, geografia, célula de observação, citação |
/api/v1/parameters.json | 10 pilares + ODS primários/secundários |
/api/v1/geographies.json | 25 países + LATAM, ISO3 + M49 |
/api/v1/observations/<param>__<ISO3>.json | Uma célula: indicadores, séries, citações, ODS |
/api/v1/observations/<param>__<ISO3>.csv | Mesma célula, uma linha por indicador-ano |
/api/v1/observations.csv | Em massa: todas as células concatenadas |
/api/v1/observations.sdmx.csv | Em massa, SDMX-CSV (ISO 17369), REF_AREA = M49 |
/api/v1/futuros-data.xlsx | Pasta de trabalho (README/parameters/geographies/observations/citations) |
/api/v1/citations.json · .csv | Registro completo de citações |
/api/v1/freshness.json | Livro-razão de atualização por fonte |
/api/v1/sdg-crosswalk.json | Pilar → ODS + indicador → código ODS oficial |
/api/v1/signals/<param>__<ISO3>.json | Sinais citados por célula (260/260 células; as 10 regionais __LATAM são []) |
/api/v1/governance/{resilience,regulation-index,scores}.json | Motor de Governança: resiliência democrática, observatório regulatório, índice composto |
/api/v1/contributions.json | Dados contribuídos com portão de licença |
/data.json | Catálogo DCAT (raiz do site) |
/feeds/futuros.xml · /feeds/<ISO3>.xml · /feeds/<param>__<ISO3>.xml | Feeds RSS 2.0 estáticos de sinais, re-assados a cada deploy por bake-feeds dentro de prebuild |
/feeds/index.json | Manifesto dos 267 feeds RSS, com as contagens do que foi omitido |
GET /api/backlog | Backlog de lacunas de dados (função ao vivo, não assada) — ver acima |
GET /api/env-levers | Postura pública das 15 alavancas de produção que falham fechadas: por alavanca, seu id, as variáveis que a compõem, opens (o que habilita) e probe (como verificá-la de fora), mais um booleano set. Nunca devolve valores de segredos; Cache-Control: no-store. É a superfície legível por máquina por trás de /confianza — ver auto-hospedagem |
Para acesso agêntico, baseado em ferramentas, ao mesmo corpus (com cálculo determinístico e citações), veja o servidor MCP.
Política de rastreamento (crawling)
Os dados são abertos por design, então o rastreamento não é bloqueado — mas é declarado e observado:
robots.txt(https://futuros.xyz/robots.txt) permite tudo exceto/admin/e um caminho-armadilha interno. Os rastreadores de treinamento de IA (GPTBot, ClaudeBot, CCBot, Bytespider, etc.) estão explicitamente permitidos hoje; a política por bot muda com uma linha nesse arquivo (a lista de tokens é mantida emserver/scrape/known-agents.ts).- Raspar o HTML é inútil: cada rota da app devolve o mesmo shell de SPA sem conteúdo. As superfícies para máquinas são esta API, o servidor MCP e o catálogo DCAT (
/data.json) — use-as. - O acesso é observado, nunca bloqueado: um middleware somente-observação (
middleware.ts+server/scrape/, runbook emserver/scrape/README.md) marca padrões de raspagem em massa e de cópia-por-IA como eventos internos. Nenhuma requisição é atrasada ou recusada por esta camada.