Peça a cinco serviços diferentes a cotação EUR/USD agora mesmo e você vai receber cinco números ligeiramente diferentes. Não drasticamente diferentes — mas diferentes na quarta casa decimal, às vezes na terceira. Se o seu time financeiro já abriu um chamado porque o checkout mostrava 1,0847 enquanto o extrato bancário dizia 1,0821, você já sabe que isso não é uma questão acadêmica.
Então, de onde as APIs de câmbio tiram seus dados? A resposta honesta é que nenhuma API "sabe" a taxa de câmbio, porque não existe uma taxa de câmbio única a ser sabida. O mercado de câmbio é um mercado de balcão sem bolsa central e sem sino de fechamento — apenas milhares de instituições cotando preços umas às outras pelo mundo. Toda API que você pode chamar é um pipeline que amostra esse mercado, limpa os dados e entrega um número. Este guia percorre esse pipeline camada por camada, explica exatamente por que dois provedores discordam e mostra como auditar uma fonte antes de construir lógica de faturamento em cima dela.
A resposta curta: três camadas entre o mercado e o seu JSON
Toda API de câmbio — gratuita ou paga, a nossa inclusive — é construída sobre as mesmas três camadas:
- Aquisição. Preços brutos são obtidos de fontes upstream: feeds institucionais de FX, publicações de bancos centrais e cotações de corretoras ou do varejo.
- Normalização. Esses preços são validados, outliers são descartados, várias fontes são combinadas e uma taxa de referência única por par é derivada.
- Entrega. A taxa derivada é capturada em uma cadência definida, cacheada e servida via HTTP com um timestamp.
Diferenças em qualquer uma dessas três camadas produzem um número diferente no seu corpo de resposta. A maioria dos desenvolvedores presume que a divergência vem da camada 1. Na prática, as camadas 2 e 3 causam tanto quanto.
Camada 1 — De onde os preços brutos realmente vêm
Feeds interbancários e institucionais
O mais próximo de uma taxa de câmbio "real" é o mercado interbancário: os preços pelos quais grandes bancos e provedores de liquidez negociam entre si. Esses preços chegam como fluxos contínuos de cotações bid e ask vindos de plataformas de negociação, prime brokers e fornecedores de dados de mercado.
Feeds assim são a fonte de maior fidelidade disponível. Também são os mais caros, o que explica por que APIs gratuitas raramente os usam como fonte primária. Quando um provedor diz oferecer taxas "em tempo real" ou "abaixo do minuto", quase sempre é porque há feeds institucionais no topo do seu pipeline.
Note que um feed interbancário entrega dois preços, não um — um bid e um ask. A taxa única que você vê em uma resposta de API costuma ser o ponto médio entre eles. Se essa distinção é nova para você, nosso guia sobre o spread bid-ask no câmbio cobre o tema em detalhe.
Taxas de referência de bancos centrais
A segunda grande fonte são as publicações oficiais de bancos centrais. O exemplo mais conhecido é o Banco Central Europeu, que publica taxas de referência do euro em cada dia útil TARGET por volta das 16h00 CET, com base em um procedimento de concertação entre bancos centrais europeus. Dezenas de outros bancos centrais publicam taxas diárias equivalentes para suas próprias moedas.
Taxas de banco central têm duas vantagens enormes: são gratuitas e têm autoridade. Muitas autoridades fiscais e normas contábeis as aceitam explicitamente para reporte. É por isso que boa parte do ecossistema de APIs gratuitas é construído sobre elas. O Frankfurter, um projeto open source bastante usado nesse espaço, acompanha taxas diárias de 84 bancos centrais cobrindo 201 moedas, com histórico que vai até 1948 — tudo isso dado público, redistribuído.
Elas também têm duas limitações sérias:
- São instantâneos diários, não preços ao vivo. Uma taxa de referência das 16h00 CET não diz nada sobre o que aconteceu às 09h00 ou às 22h00.
- Elas param nos fins de semana e feriados. Se sua API não retorna dados para um sábado, ou repete o número de sexta, uma fonte derivada do BCE costuma ser a explicação.
Cotações de varejo e de corretoras
A terceira fonte é o preço voltado ao cliente final: o que um banco, bandeira de cartão, adquirente ou serviço de transferência vai de fato dar a um cliente. Essas taxas já incluem um spread — uma margem embutida no preço acima da taxa de mercado.
É por isso que uma taxa vista em um site comparador de consumo não bate com a do seu extrato bancário. Não é erro em nenhum dos dois; eles medem coisas diferentes. Sites voltados ao consumidor normalmente mostram a taxa mid-market, enquanto seu banco cota a taxa mid-market mais o spread dele. Para a maioria dos casos de uso em software, você quer o número mid-market e quer aplicar sua própria margem explicitamente, onde você consegue vê-la e auditá-la.
Camada 2 — Como provedores transformam feeds em uma taxa única
Assim que os preços brutos chegam, o provedor precisa decidir qual número publicar. Quatro decisões acontecem aqui, e cada uma delas é um ponto onde provedores divergem.
Blending. A maioria das APIs comerciais não depende de uma única fonte upstream. A Open Exchange Rates, por exemplo, descreve seus dados como coletados de múltiplos provedores e combinados algoritmicamente. O blending suaviza um tick ruim isolado, mas os pesos da combinação são proprietários — e é exatamente por isso que dois feeds combinados nunca coincidem exatamente.
Rejeição de outliers. Uma cotação ruim de uma plataforma pode estar errada em uma ordem de grandeza. Provedores aplicam filtros que descartam preços fora de uma banda de tolerância ao redor do consenso. Filtragem agressiva significa taxas estáveis, mas reação mais lenta a movimentos genuínos. Filtragem frouxa significa reação rápida, mas ruído ocasional.
Derivação do mid. Se o feed upstream é bid/ask, o provedor publica um mid. O ponto médio simples (bid + ask) / 2 é o padrão, mas abordagens ponderadas por volume produzem um resultado ligeiramente diferente.
Triangulação de cruzados. Nenhum provedor obtém diretamente todos os mais de 30.000 pares de moedas possíveis. Em vez disso, a maioria dos pares é calculada por meio de uma moeda pivô — geralmente USD ou EUR:
GBP/JPY = (USD/JPY) / (USD/GBP)Isso significa que a taxa obtida para um par exótico herda o arredondamento e o timing de outros dois pares. Provedores que pivotam em USD e os que pivotam em EUR chegarão a números diferentes para o mesmo cruzado. Cobrimos a mecânica em taxas de câmbio cruzadas explicadas.
Camada 3 — Como a taxa chega ao seu código
A camada final é a que os desenvolvedores mais controlam e menos pensam a respeito.
A cadência de atualização é o maior diferencial isolado entre provedores e entre planos. Planos gratuitos normalmente atualizam uma ou duas vezes por dia. Planos pagos atualizam de hora em hora, a cada dez minutos ou a cada 60 segundos. Duas APIs com dados idênticos vão divergir simplesmente porque uma capturou às 14h00 e a outra às 14h47.
Cache agrava isso. A maioria das APIs fica atrás de um CDN, e a maioria dos clientes bem construídos cacheia localmente por cima. Some um cache de borda de 15 minutos a um refresh de 10 minutos e sua aplicação pode estar trabalhando com uma taxa de 25 minutos atrás. Isso é aceitável para exibir preços e inaceitável para liquidar uma operação — a pergunta prática é sempre quão velho é velho demais para esta operação específica. Nosso guia sobre cache e tratamento de erros em APIs de câmbio explica como dimensionar essas janelas.
Timestamps são sua defesa. Toda API séria retorna o momento em que a taxa foi capturada. Leia esse campo. Não presuma que o momento em que você recebeu a resposta é o momento em que a taxa era verdadeira:
const MAX_AGE_SECONDS = 900; // 15 minutes
async function getRate(base, symbol) {
const res = await fetch(
`https://api.finexly.com/v1/latest?base=${base}&symbols=${symbol}`,
{ headers: { Authorization: `Bearer ${process.env.FINEXLY_API_KEY}` } }
);
const data = await res.json();
const ageSeconds = Math.floor(Date.now() / 1000) - data.timestamp;
if (ageSeconds > MAX_AGE_SECONDS) {
throw new Error(`Rate is ${ageSeconds}s old — refusing to price on stale data`);
}
return { rate: data.rates[symbol], ageSeconds };
}Esta é a requisição subjacente e um formato representativo de resposta:
curl "https://api.finexly.com/v1/latest?base=USD&symbols=EUR,GBP,JPY" \
-H "Authorization: Bearer YOUR_API_KEY"{
"success": true,
"base": "USD",
"timestamp": 1755244800,
"rates": {
"EUR": 0.9241,
"GBP": 0.7863,
"JPY": 147.2150
}
}Todos os detalhes de parâmetros e endpoints estão na documentação da API Finexly.
Por que duas APIs retornam números diferentes para o mesmo par
Juntando as três camadas, aqui estão as seis causas de divergência, aproximadamente em ordem de estrago causado:
- Momentos de captura diferentes. A causa mais comum de longe. Nenhum dos feeds está errado; eles simplesmente olharam em momentos distintos.
- Misturas de fontes diferentes. Uma taxa derivada de banco central e uma derivada do interbancário medem duas coisas distintas por definição.
- Mid-market versus taxa com margem. Um provedor entrega o ponto médio de mercado, outro entrega um preço ao consumidor com o spread já embutido.
- Moedas pivô diferentes para cruzados. Triangulação via USD e via EUR produzem resultados diferentes para o mesmo par não-USD.
- Precisão e arredondamento. Seis casas truncadas para quatro, ou taxas publicadas como pares inversos e reinvertidas, ambos introduzem desvio.
- Camadas de cache que você esqueceu. Seu CDN, o cache HTTP do seu framework e sua própria camada Redis somam idade.
Uma regra prática útil: para pares principais, uma diferença de alguns pontos-base (0,01% = 1 pb) entre duas fontes mid-market respeitáveis é normal e esperada. Uma diferença de 50 pb ou mais significa que uma das duas está desatualizada, com margem embutida ou quebrada — e você deve descobrir qual antes de ir para produção.
Como auditar uma API de câmbio antes de confiar nela
Não aceite as promessas de precisão de um provedor por fé. Rode esta verificação por uma semana contra a fonte que seu time financeiro considera autoritativa:
import os
import requests
from datetime import datetime, timezone
FINEXLY_URL = "https://api.finexly.com/v1/latest"
HEADERS = {"Authorization": f"Bearer {os.environ['FINEXLY_API_KEY']}"}
def get_rate(base: str, symbol: str) -> dict:
r = requests.get(
FINEXLY_URL,
headers=HEADERS,
params={"base": base, "symbols": symbol},
timeout=5,
)
r.raise_for_status()
data = r.json()
return {
"rate": data["rates"][symbol],
"captured_at": datetime.fromtimestamp(data["timestamp"], tz=timezone.utc),
}
def basis_points(a: float, b: float) -> float:
"""Difference between two rates, in basis points."""
return abs(a - b) / ((a + b) / 2) * 10_000
primary = get_rate("EUR", "USD")
reference = 1.0839 # whatever your accounting source published
diff = basis_points(primary["rate"], reference)
print(f"Finexly: {primary['rate']} captured {primary['captured_at']:%H:%M UTC}")
print(f"Reference: {reference}")
print(f"Delta: {diff:.1f} bp -> {'OK' if diff < 25 else 'INVESTIGATE'}")Três coisas para observar nos resultados:
- A diferença é estável ou está derivando? Um desvio constante sugere uma margem sistemática. Um desvio aleatório sugere timing.
- A diferença dispara em determinados horários? Isso aponta para o momento de captura, geralmente em torno de uma janela de publicação de banco central.
- O que acontece nos fins de semana? Se sua fonte congela na sexta à tarde e volta na segunda, ela é derivada de banco central — planeje sua conciliação de segunda-feira em torno disso.
Você também pode checar a triangulação buscando um cruzado diretamente e calculando-o via USD; os dois devem coincidir dentro de um ou dois pontos-base.
Escolhendo uma fonte de dados para o seu caso de uso
Não existe fonte universalmente "melhor" — apenas a fonte certa para o que você está construindo.
| Caso de uso | O que você precisa | Defasagem aceitável |
|---|---|---|
| Exibir preços a compradores | Taxa mid-market, com sua própria margem por cima | Horas |
| Faturamento de assinaturas SaaS | Mid-market, um snapshot por ciclo de cobrança, salvo com a fatura | Horas, mas precisa ficar registrado |
| Contabilidade e reporte fiscal | Taxa de referência do banco central para a data específica | Diária, por definição |
| Analytics e dashboards | Série histórica consistente de uma única fonte | Diária |
| Pagamentos e remessas | Mid-market fresco com banda de tolerância explícita | Minutos |
| Trading e hedge | Bid/ask real de um feed institucional | Segundos |
Se você ainda está avaliando opções, nossa comparação de APIs de câmbio gratuitas versus pagas detalha o que muda ao subir de plano, e a página de planos e preços mostra onde ficam a frequência de atualização e os limites de requisições. Para uma checagem manual rápida de qualquer par, o conversor de moedas usa o mesmo feed subjacente da API.
Perguntas frequentes
De onde as APIs de câmbio gratuitas tiram seus dados?
Quase sempre de publicações de bancos centrais, mais comumente as taxas de referência diárias do euro do Banco Central Europeu, às vezes combinadas com um punhado de outras fontes públicas. É por isso que planos gratuitos normalmente atualizam uma vez por dia, pulam fins de semana e cobrem menos moedas exóticas do que os pagos.
Por que a taxa de câmbio da minha API é diferente da do Google?
O Google exibe uma taxa de referência mid-market, que é um instantâneo e não um preço contínuo ao vivo, e não é necessariamente amostrada no mesmo momento da sua chamada de API. Uma diferença pequena é normal. Uma grande geralmente significa que uma das duas é uma taxa de varejo com margem, e não uma taxa mid-market.
Qual taxa de câmbio devo usar para contabilidade e fisco?
Use a taxa de referência oficial publicada pelo banco central competente para a data da transação — é o que a maioria das autoridades fiscais espera. Busque-a em um endpoint histórico com data explícita, em vez de reaproveitar uma taxa ao vivo, e armazene-a com o registro da transação.
Uma API de câmbio em tempo real é realmente tempo real?
Raramente no sentido literal. "Tempo real" normalmente significa que o provedor atualiza em um intervalo curto — 60 segundos é comum no plano mais alto — não que ele transmita tick a tick. Verifique o timestamp na resposta e o intervalo de atualização documentado, não o texto de marketing.
Posso simplesmente fazer scraping de taxas de câmbio em vez de usar uma API?
Pode, mas você herda todos os modos de falha da página que raspa: mudanças de layout, rate limiting, ausência de timestamps, ausência de histórico e, com frequência, violação dos termos de uso. Cobrimos o trade-off completo em API de câmbio versus web scraping.
Construa sobre um feed que você pode auditar
Saber de onde vêm seus dados de câmbio é a diferença entre um bug de moeda que você explica em uma frase e um que consome uma semana de engenharia. Faça três perguntas a qualquer provedor antes de integrar: quais são as fontes, com que frequência atualiza, e toda resposta traz um timestamp de captura?
Pronto para integrar taxas de câmbio que você realmente consegue auditar? Pegue sua chave gratuita da API Finexly — sem cartão de crédito. Comece com 1.000 requisições gratuitas por mês em mais de 170 moedas, com respostas timestampadas e dados históricos desde o primeiro dia.
Explore More
Vlado Grigirov
Senior Currency Markets Analyst & Financial Strategist
Vlado Grigirov is a senior currency markets analyst and financial strategist with over 14 years of experience in foreign exchange markets, cross-border finance, and currency risk management. He has wo...
View full profile →