Tutorial/JavaScript quickstart
Tutorial

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, 50,000 calls a month on the free tier.

MMexchangerate.dev·Jun 19, 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 for 31 currencies and two freshness fields, source and market_session. 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 50,000 calls a month at 30 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. One await is enough to read the EUR rate:

javascript · no keycopy
const res = await fetch("https://api.exchangerate.dev/v1/latest/USD");
const data = await res.json();

console.log(data.rates.EUR);        // 0.87531
console.log(data.source);           // ecb_daily
console.log(data.market_session);   // open

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
const API = "https://api.exchangerate.dev/v1";
const KEY = "exr_live_...";   // free key at https://exchangerate.dev/signup

async function getLatest(base = "USD") {
  const res = await fetch(`${API}/latest/${base}`, {
    headers: { Authorization: `Bearer ${KEY}` },
  });

  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    throw new Error(`exchangerate.dev ${res.status}: ${err.message ?? res.statusText}`);
  }

  return res.json();
}

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

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
const res = await fetch(`${API}/convert/USD/EUR/100`, {
  headers: { Authorization: `Bearer ${KEY}` },
});
const data = await res.json();

console.log(data.rate);       // 0.87572
console.log(data.converted);  // 87.57

The convert endpoint returns the same source and market_session fields as the latest endpoint, so you can show users exactly where the rate came from.

Understand source and market_session

Every response includes two fields that tell you the age and type of the rate. source identifies the data class: live is an aggregated spot consensus that updates through weekends, 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 tells you the current state of the trading day: open, weekend, or a named session.

Field valueWhat it meansWhen it moves
source: liveAggregated spot consensusContinuously, including weekends
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 SundayLive moves; reference fixes are frozen

The data_updated_at field tells you when the underlying rate was last written. 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 50,000 calls per month at 30 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 on your billing anniversary.

  • 50,000 calls per month
  • 30 requests per minute
  • No credit card required
  • Covers /v1/latest, /v1/convert, /v1/range, and /v1/{date}/{base}
MM
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