How to Handle Base Currency Conversion in Your App
"How do I convert from EUR to GBP if my API only supports USD as the base currency?" This question appears in nearly every exchange rate API support forum. It is one of the most common developer pain points — and it is entirely avoidable with the right API or the right code.
The Base Currency Problem
Most exchange rate APIs return rates relative to a base (source) currency. When you call GET /rates?base=USD, you get something like:
{
"base": "USD",
"rates": {
"EUR": 0.9234,
"GBP": 0.7891,
"JPY": 151.42
}
} This tells you how much 1 USD buys in each currency. But what if your users are in Europe and you need EUR to GBP? Or your app serves customers in India and you need INR to AUD?
The catch: Many free API plans lock the base currency to USD. Changing the base to EUR, GBP, or any other currency requires a paid upgrade. This forces developers into workarounds.
| API | Free Base Currency | Any Base Currency |
|---|---|---|
| AllRatesToday | Any currency | All plans |
| Open Exchange Rates | USD only | Developer plan ($12/mo) |
| Fixer.io | EUR only | Basic plan ($10/mo) |
| CurrencyAPI | USD only | Pro plan |
| Frankfurter | Any (ECB set) | Limited to ~30 currencies |
The Easy Way: Use an API That Supports Any Base
The simplest solution is to use an API that lets you set any currency as the source. With AllRatesToday, just change the source parameter:
# EUR as base
curl "https://allratestoday.com/api/v1/rates?source=EUR&target=GBP" \
-H "Authorization: Bearer YOUR_API_KEY"
# INR as base
curl "https://allratestoday.com/api/v1/rates?source=INR&target=AUD" \
-H "Authorization: Bearer YOUR_API_KEY"
# JPY as base, multiple targets
curl "https://allratestoday.com/api/v1/rates?source=JPY&target=USD,EUR,KRW" \
-H "Authorization: Bearer YOUR_API_KEY" This works on all plans, including the free tier. No workarounds needed.
The Manual Way: Cross-Rate Calculation
If you are stuck with a USD-locked API, you can calculate cross-rates yourself. The math is straightforward:
Cross-rate formula: To convert from currency A to currency B when you only have USD-based rates:
A/B = (USD/B) / (USD/A)
Or equivalently: A/B = rate_B / rate_A where both rates are USD-based.
Example: EUR to GBP
Given USD-based rates:
- USD/EUR = 0.9234 (1 USD buys 0.9234 EUR)
- USD/GBP = 0.7891 (1 USD buys 0.7891 GBP)
Cross-rate: EUR/GBP = 0.7891 / 0.9234 = 0.8546
So 1 EUR = 0.8546 GBP.
JavaScript Implementation
// Cross-rate calculation when your API only returns USD-based rates
function crossRate(usdRates, from, to) {
if (from === 'USD') return usdRates[to];
if (to === 'USD') return 1 / usdRates[from];
return usdRates[to] / usdRates[from];
}
// Usage
const usdRates = {
EUR: 0.9234,
GBP: 0.7891,
JPY: 151.42,
INR: 83.45,
AUD: 1.5312
};
console.log('EUR to GBP:', crossRate(usdRates, 'EUR', 'GBP')); // 0.8546
console.log('GBP to JPY:', crossRate(usdRates, 'GBP', 'JPY')); // 191.89
console.log('INR to AUD:', crossRate(usdRates, 'INR', 'AUD')); // 0.01835 Python Implementation
def cross_rate(usd_rates: dict, source: str, target: str) -> float:
"""Calculate cross-rate from USD-based rates."""
if source == "USD":
return usd_rates[target]
if target == "USD":
return 1 / usd_rates[source]
return usd_rates[target] / usd_rates[source]
usd_rates = {
"EUR": 0.9234,
"GBP": 0.7891,
"JPY": 151.42,
"INR": 83.45,
"AUD": 1.5312,
}
print(f"EUR to GBP: {cross_rate(usd_rates, 'EUR', 'GBP'):.4f}") # 0.8546
print(f"GBP to JPY: {cross_rate(usd_rates, 'GBP', 'JPY'):.2f}") # 191.89
print(f"INR to AUD: {cross_rate(usd_rates, 'INR', 'AUD'):.5f}") # 0.01835 Converting Amounts (Not Just Rates)
Once you have the rate, converting an amount is simple multiplication. But there are common mistakes developers make:
The Rounding Problem
// Wrong: floating-point precision issues
const amount = 1999.99;
const rate = 0.9234;
const result = amount * rate; // 1846.7907659999998
// Right: round to the target currency's decimal places
function convertAmount(amount, rate, decimals = 2) {
return Number((amount * rate).toFixed(decimals));
}
console.log(convertAmount(1999.99, 0.9234)); // 1846.79
// For JPY (0 decimals)
console.log(convertAmount(1999.99, 151.42, 0)); // 302840 Currency decimal places: Most currencies use 2 decimal places, but JPY, KRW, VND use 0. BHD, KWD, OMR use 3. Always round to the correct number of decimals for the target currency.
Using the AllRatesToday SDK
The SDK handles base currency and conversion in a single call:
import AllRatesToday from '@allratestoday/sdk';
const client = new AllRatesToday('YOUR_API_KEY');
// Direct conversion - any base currency, any target
const result = await client.convert('EUR', 'GBP', 5000);
console.log(`5,000 EUR = ${result.result} GBP`);
// Get rate for any pair directly
const rate = await client.getRate('INR', 'AUD');
console.log(`1 INR = ${rate} AUD`); Handling Multiple Target Currencies
A common pattern is showing a price in the user's local currency. Here is an efficient approach:
import AllRatesToday from '@allratestoday/sdk';
const client = new AllRatesToday('YOUR_API_KEY');
// Fetch all rates from your store's base currency in one call
const rates = await client.getRates('USD');
// Convert a product price to any visitor's currency
function displayPrice(priceUSD, targetCurrency) {
const rate = rates[targetCurrency];
const converted = (priceUSD * rate).toFixed(2);
return `${converted} ${targetCurrency}`;
}
// Display for different visitors
console.log(displayPrice(99.99, 'EUR')); // "92.32 EUR"
console.log(displayPrice(99.99, 'GBP')); // "78.90 GBP"
console.log(displayPrice(99.99, 'JPY')); // "15141 JPY" Performance tip: Fetch rates once per minute and cache them. AllRatesToday updates every 60 seconds, so there is no benefit to fetching more frequently. This keeps you well within the free tier's 300 requests/month.
Summary
- The base currency is the reference point for all rates in an API response.
- Many free API plans lock you to USD — forcing manual cross-rate math.
- Cross-rate formula:
A/B = USD_rate_B / USD_rate_A - Always round to the correct decimal places for the target currency.
- The easiest solution: use an API that supports any base currency on all plans.
Any Base Currency. Any Plan.
AllRatesToday supports all 160+ currencies as the source — even on the free tier. No cross-rate workarounds needed.
Get Your Free API Key