Tutorial/JavaScript quickstart

Currency conversion in JavaScript and Node.js

Fetch live exchange rates and convert amounts in JavaScript using the global fetch API. Works in Node 18+, Deno, Bun, and modern browsers. No key to start, 10,000 calls a month on the free tier.

ERexchangerate.dev·Updated Sep 8, 2026·5 min read

The quickest path to exchange rates in JavaScript is a GET to /v1/latest/USD using fetch. The response is plain JSON with rates across the supported 31-currency catalog, with per-currency sources and effective_at metadata. No API key is required for your first call.

Key points
Global fetch works out of the box in Node 18+, Deno, Bun, and browsers with no extra dependencies.
One GET to /v1/latest/{base} returns rates for 31 currencies, plus source and market_session.
Pass your key as Authorization: Bearer exr_live_..., or use X-API-Key if your platform cannot set Authorization.
The free tier is 10,000 calls a month at 12 requests a minute, with no card required.
Rates are indicative, for reference and analytics only, not a dealing quote.

Your first call, no key needed

In Node 18 or any modern browser you already have fetch. Check the HTTP status before reading the EUR rate:

javascript · no keycopy
const response = await fetch("https://api.exchangerate.dev/v1/latest/USD?symbols=EUR,GBP", {
  signal: AbortSignal.timeout(10_000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}; Retry-After: ${response.headers.get("Retry-After")}`);
const data = await response.json();
console.log(data.rates.EUR);
console.log(data.sources.EUR, data.effective_at.EUR);
console.log(data.market_session);

Anonymous calls are capped per IP address, so move to a free key before you go past a quick test.

Add a key and error handling

Pass your key as a bearer token in the Authorization header. Check res.ok and throw on a bad status so errors surface early:

javascript · authenticated call with error handlingcopy
// Node.js server only. Never put an account key in browser code.
const KEY = process.env.EXCHANGERATE_API_KEY;
if (!KEY) throw new Error("Set EXCHANGERATE_API_KEY on your server");

async function getLatest(base = "USD") {
  const response = await fetch(`https://api.exchangerate.dev/v1/latest/${encodeURIComponent(base)}`, {
    headers: { Authorization: `Bearer ${KEY}` },
    redirect: "error",
    signal: AbortSignal.timeout(10_000),
  });
  if (!response.ok) throw new Error(`HTTP ${response.status}; Retry-After: ${response.headers.get("Retry-After")}`);
  return response.json();
}

const data = await getLatest("USD");
console.log(data.rates.GBP, data.effective_at.GBP);

The X-API-Key: exr_live_... header is also accepted, for platforms that cannot set an Authorization header (some serverless runtimes, Zapier, and similar no-code tools).

Convert an amount

For a direct conversion call /v1/convert/{from}/{to}/{amount}. The response gives you both the rate and the converted amount in one round-trip:

javascript · convert 100 USD to EURcopy
// Node.js server only.
const KEY = process.env.EXCHANGERATE_API_KEY;
if (!KEY) throw new Error("Set EXCHANGERATE_API_KEY on your server");
const response = await fetch("https://api.exchangerate.dev/v1/convert/USD/EUR/100", {
  headers: { Authorization: `Bearer ${KEY}` },
  redirect: "error",
  signal: AbortSignal.timeout(10_000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}; Retry-After: ${response.headers.get("Retry-After")}`);
const data = await response.json();
console.log(data.rate, data.converted);

The convert endpoint returns the same source and market_session fields as the latest endpoint, so you can show users the rate class and whether the interbank trading week is open.

Understand source and market_session

Use effective_at[currency] for the observation time of a displayed currency, and sources[currency] for its source. source summarizes the whole response; market_session describes the trading session rather than the age of a rate. source identifies the data class: live is an aggregated spot consensus that updates approximately every 60 seconds through the trading week, ecb_daily is the European Central Bank reference fix published once per business day around 16:00 CET, and fred_daily is the Federal Reserve daily series. market_session is open, weekend, or interbank_closed for a known non-weekend closure.

Field valueWhat it meansWhen it moves
source: liveAggregated spot consensusIntraday (~60s), trading week
source: ecb_dailyEuropean Central Bank reference fixOnce per business day (~16:00 CET)
source: fred_dailyFederal Reserve daily seriesOnce per business day
market_session: weekendSaturday or Sunday (interbank closed)Reference fixes carry Friday's value; live feed not updating

The data_updated_at field is the oldest contributing observation; it is not necessarily the age of the currency you display. timestamp records when the response was built. Together they let you decide how to cache and display the value.

Indicative rates only
These rates are published for reference, analytics, and display. They are not a dealing quote and must not be used to settle a trade or transfer. Every response states this in its notice field.

Free tier limits

A free key gives you 10,000 calls per month at 12 requests per minute. No card is required to sign up. If you exceed the per-minute limit the API returns a 429; back off and retry. The monthly quota resets at 00:00 UTC on the first day of each calendar month. Honor Retry-After on 429 responses.

  • 10,000 calls per month
  • 12 requests per minute
  • No credit card required
  • Covers /v1/latest, /v1/convert, /v1/range, and /v1/{date}/{base}
ER
exchangerate.dev
Integration guides for developers.

Keep reading

TutorialHow to get exchange rates in PythonRead GuideHistorical FX rates and time series in one callRead ReferenceReading source and market_sessionRead
More ComparisonsFixer vs exchangerate.devOpen Exchange Rates vs exchangerate.devCurrencylayer vs exchangerate.devCurrencylayer vs ExchangeRate-API
LearnReading source and market_session in your pipelineIndicative vs executable FX rates: what a rates API actually gives youECB reference rates, explained
Live RatesEUR/USDGBP/USDUSD/JPY