Integration guide

Add currency exchange rates and conversion to JavaScript and Node.js

Fetch rates or convert amounts in Node.js 18+ with built-in fetch. This server-side pattern keeps the key private and caches rates until they can change.

1. Get a free API key

Sign up at https://currencyexchangerate-api.com/auth/login, then create a key under API keys in the console. The free plan includes 3,000 requests per month with no credit card. Store the secret as CXR_API_KEY in server-side environment configuration; never expose it in browser code.

.env

shell
CXR_API_KEY=cxr_your_secret_key

2. Create a reusable client and cache rates

Use the standard HTTP client. Cache every /latest response until nextUpdateAt: rates change at most once by then, and reusing the response saves quota. The helper also exposes /convert.

rates.js

JavaScript
const API_BASE_URL = 'https://api.currencyexchangerate-api.com/api/v1';const key = process.env.CXR_API_KEY;const saved = new Map(); async function get(path) {  const response = await fetch(API_BASE_URL + path, {    headers: { Authorization: 'Bearer ' + key },  });  if (!response.ok) {    throw new Error('Rates API status ' + response.status);  }  return response.json();} export async function latest(base = 'USD', symbols = 'EUR,GBP') {  const id = base + ':' + symbols;  const hit = saved.get(id);  if (hit && Date.now() < hit.until) {    return hit.data;  }  const query = new URLSearchParams({ base, symbols });  const data = await get('/latest?' + query);  saved.set(id, { data, until: Date.parse(data.nextUpdateAt) });  return data;} export async function convert(from, to, amount) {  const query = new URLSearchParams({ from, to, amount: String(amount) });  return get('/convert?' + query);}

3. Use it in JavaScript and Node.js

Call the helper from a server route, controller, view, command, or script. Format converted values for the user’s locale.

server.js

JavaScript
import { latest, convert } from './rates.js'; const rates = await latest('USD', 'EUR,GBP');const result = await convert('EUR', 'GBP', 100);const formatter = new Intl.NumberFormat('en-GB', {  style: 'currency',  currency: 'GBP',});console.log(formatter.format(result.result));

4. Handle API errors

A 401 means the key is invalid. A 429 can mean a rate limit or quota limit; read Retry-After in seconds before retrying. Other errors use application/problem+json.

errors.js

JavaScript
// In get(), replace the generic throw with://   if (!response.ok) throw await apiError(response);async function apiError(response) {  const problem = await response.json().catch(() => ({}));  if (response.status === 401) {    return new Error('Check CXR_API_KEY');  }  if (response.status === 429) {    const retryAfter = response.headers.get('Retry-After');    return new Error('Retry after ' + retryAfter + ' seconds');  }  return new Error(problem.detail || 'Rates API status ' + response.status);}

5. Format the amount for display

Use locale-aware currency formatting instead of adding a symbol manually.

format.js

JavaScript
const formatter = new Intl.NumberFormat('en-GB', {  style: 'currency',  currency: 'EUR',});const formatted = formatter.format(85.249105);