How Currency Exchange APIs Work: A Technical Overview
Every currency converter on the internet — including this one — is ultimately a thin UI on top of an exchange-rate API. But where does that data actually come from, and why do "live" rates from different services often disagree by half a percent or more? This piece is a slightly more technical walkthrough for developers and curious users of how the sausage gets made.
Where exchange-rate data actually comes from
For fiat currencies, there's no single global "price" feed. Rates are derived from a few overlapping sources:
- The interbank market. Large banks trade currencies with each other 24 hours a day across electronic platforms (EBS, Refinitiv, CLS). This is the deepest, most liquid layer and is the ultimate source of "true" wholesale prices.
- Central bank reference rates. The European Central Bank, the Bank of England, and others publish daily reference rates derived from a snapshot of the interbank market (the ECB uses 14:15 CET).
- Aggregators. Companies like Refinitiv, Bloomberg, XE, OANDA, and newer API-first providers consume interbank feeds (often via paid licensing) and republish them as REST APIs.
Mid, bid, ask, and dealer rates
Any currency pair has two simultaneous prices in a live market:
- Bid: the price at which buyers are willing to buy.
- Ask: the price at which sellers are willing to sell.
- Mid-market: the midpoint between bid and ask.
- Dealer rate: what a retail bank or exchange actually quotes a customer — typically the mid-market rate plus a markup of 1-5% (or more at airports).
Most consumer-facing converters display mid-market rates, including xchangepro.app. For more depth on this distinction, see our mid-market exchange rates explainer.
Real-time vs delayed data
True real-time interbank data is expensive — Bloomberg terminals start at around $25,000/year per seat, and Refinitiv enterprise feeds cost six figures. Most "free" currency APIs sit downstream: they pull from a paid feed and republish it with a delay (anywhere from a few seconds to 24 hours), and/or with reduced update frequency.
For practical purposes — checking what your bank should be charging, budgeting a trip, sizing a remittance — even hourly-refreshed data is more than accurate enough. Truly real-time data only matters for active FX trading.
The major API provider landscape
- ECB feeds (free, official). Published once a day on business days. Excellent for daily reference, useless for intraday.
- Open exchange rates / Fixer / CurrencyLayer / ExchangeRate-API. Tiered freemium APIs with hourly or per-minute refresh on paid plans.
- UniRateAPI, Frankfurter, fawazahmed0/currency-api. Newer or community-maintained APIs offering generous free tiers, typically with 15-60 minute refresh.
- Bloomberg, Refinitiv, S&P Capital IQ. Enterprise-tier real-time interbank feeds. Used by banks, hedge funds, and trading desks.
Crypto is a different world. Because crypto trades on hundreds of independent exchanges with no consolidated tape, the standard is to use an aggregator like CoinGecko, CoinMarketCap, or Kaiko that computes a volume-weighted average price across many venues. See our piece on why Bitcoin prices vary across exchanges for why this matters.
How xchangepro.app sources data
xchangepro.app uses two upstream feeds:
- Fiat:
UniRateAPIas the primary feed, withfawazahmed0/currency-apias a fallback if the primary is unreachable. Both deliver USD-pivot rates for 150+ currencies refreshed at least every 15 minutes. - Crypto:
CoinGecko'spublic/simple/priceendpoint, which returns volume-weighted USD prices for the 15 cryptocurrencies we support.
Both responses are cached client-side in localStoragewith a TTL — 5 minutes for fiat, 1 minute for crypto — so repeat visits and rapid input changes don't hammer the upstream APIs. A freshness indicator in the UI shows when rates were last updated.
Caching and refresh strategy
For a converter UI, a short TTL with optimistic display of cached rates is the right pattern. The flow:
- On mount, render immediately from cache if it exists.
- Kick off a background refresh; if it succeeds, update state and re-render.
- Re-fetch when the tab regains visibility (
visibilitychange) and on a recurring interval. - Mark rates as "stale" or "offline" in the UI if a fetch fails, rather than blocking the entire experience.
Why "live" can mean different things
Two converters showing "live USD/EUR" can disagree by 0.2% because they pull from different upstreams with different update intervals and different aggregation methodologies. This is normal and rarely consequential — a 0.2% gap on a $1,000 conversion is $2. What matters far more is whether the displayed rate is mid-market or already marked up.
The takeaway
Currency exchange APIs look simple from the outside but rest on a layered ecosystem of interbank feeds, central bank publications, and commercial aggregators. For a free consumer converter, a 5-15 minute refresh on a USD-pivot fiat feed plus a volume-weighted crypto aggregator is plenty. Try it yourself on the xchangepro.app converter, or read more on the stablecoin layer that increasingly bridges crypto and fiat in our piece on USDT vs USDC vs DAI.