Home Documentation Pricing API Status Blog About FAQ Support

Open Exchange Rates Conversion Endpoint Is Paid-Only

Reviewed by Madhushan, Fintech Developer — April 2026

Open Exchange Rates has a dedicated conversion endpoint — GET /api/convert/{value}/{from}/{to} — that returns the converted amount in one call. Convenient, except for one thing: it's paid plans only.

Call it on the free tier and you get:

{
  "error": true,
  "status": 403,
  "message": "not_allowed",
  "description": "The requested feature is not available on your current plan."
}

AllRatesToday ships conversion on every plan, including the free tier — as both an API endpoint and as a one-liner in the official SDKs. This article explains the gap and the three ways to work around it (or avoid it entirely).

What the conversion endpoint does

Both providers expose something equivalent to: "convert 1,000 USD to EUR, return the amount."

Open Exchange Rates (Developer plan and up):

GET https://openexchangerates.org/api/convert/1000/USD/EUR?app_id=YOUR_APP_ID

Returns:

{
  "request": { "query": "/convert/1000/USD/EUR", "amount": 1000, "from": "USD", "to": "EUR" },
  "meta": { "timestamp": 1713702122, "rate": 0.9234 },
  "response": 923.4
}

AllRatesToday (every plan):

Via SDK:

const result = await client.convert('USD', 'EUR', 1000);
// { from: 'USD', to: 'EUR', amount: 1000, rate: 0.9234, result: 923.4 }

Via HTTP:

GET https://allratestoday.com/api/v1/convert?source=USD&target=EUR&amount=1000
Authorization: Bearer YOUR_API_KEY

Why the conversion endpoint matters

You can always fetch the rate and multiply in application code. That's what OXR free-tier users end up doing. So why is a dedicated endpoint useful?

Three reasons:

  1. One round trip instead of two. Some apps fetch rates only when they need to convert a specific amount.
  2. Consistent rounding. Server-side conversion uses a canonical multiplication, avoiding floating-point drift between clients.
  3. Clean call sites. convert(amount, from, to) reads more clearly than a rate fetch followed by a multiplication.

For a checkout flow, an invoicing system, or a remittance quote, this is the natural shape.

How to work around the OXR free-tier lock

If you're on Open Exchange Rates' free tier and need conversion, you have three options:

Option 1: Fetch rate, multiply client-side

async function convertOXR(amount, from, to) {
  // Note: free tier is USD-base only, so if `from !== 'USD'` you need cross-rate math
  const res = await fetch(`https://openexchangerates.org/api/latest.json?app_id=${APP_ID}&symbols=${to}`);
  const data = await res.json();
  const rate = data.rates[to];
  return amount * rate;
}

Downsides: two issues compound here — no conversion and USD-only base. For non-USD sources, you end up with cross-rate inversions.

Option 2: Upgrade to Developer plan

$12/month unlocks conversion along with non-USD base and a larger quota. If that's the only feature you need, it's an expensive upgrade.

Option 3: Switch to AllRatesToday

Free tier, conversion endpoint included, no upgrade required.

import AllRatesToday from '@allratestoday/sdk';
const client = new AllRatesToday(process.env.ALLRATES_API_KEY);
const { result } = await client.convert('USD', 'EUR', 1000);

Where AllRatesToday's conversion shines

Multi-currency invoicing

const quote = await Promise.all([
  client.convert('USD', 'EUR', 12000),
  client.convert('USD', 'GBP', 12000),
  client.convert('USD', 'INR', 12000),
]);

console.table(quote);
// [
//   { from: 'USD', to: 'EUR', amount: 12000, rate: 0.9234, result: 11080.80 },
//   { from: 'USD', to: 'GBP', amount: 12000, rate: 0.7891, result:  9469.20 },
//   { from: 'USD', to: 'INR', amount: 12000, rate: 83.42,  result: 1001040.00 }
// ]

Cross-border checkout

const settleCurrency = 'USD';
const displayCurrency = detectUserCurrency(req);
const { result: displayPrice, rate } = await client.convert(settleCurrency, displayCurrency, productPrice);
// display: show displayPrice in displayCurrency
// settle:  record settleCurrency amount for payment processor
// audit:   log `rate` + timestamp for reconciliation

Remittance quotes

async function quoteRemittance(amount, from, to) {
  const { rate, result } = await client.convert(from, to, amount);
  const fee = computeFee(amount, from);
  return {
    sendAmount: amount,
    sendCurrency: from,
    receiveAmount: result - fee,
    receiveCurrency: to,
    rate,
    fee,
    quotedAt: new Date().toISOString(),
  };
}

What if I'm on Unlimited anyway?

If you're already paying Open Exchange Rates for Unlimited ($97/mo), you have conversion access. That's fine — the migration calculus is whether the other AllRatesToday wins (60-second updates, free historical ranges, official SDKs, MCP integration) are worth the switch.

For teams building AI-assisted applications, the MCP server alone is usually the tipping point. Your coding assistant can call convert_currency as a tool, without you writing any integration glue.

Conversion rounding: one subtle note

Both providers compute result = amount × rate server-side. Both are exposed to floating-point representation issues for very large amounts. If you're in a context where exact decimal arithmetic matters (payments, accounting), you should always round to the target currency's minor unit (usually 2 decimal places):

const { result } = await client.convert('USD', 'EUR', 1000);
const euros = Math.round(result * 100) / 100;

The conversion endpoint doesn't exempt you from doing this — it just saves the round trip.

Stop paying $12/month for conversion

Conversion endpoint, any base currency, 60-second rates. No credit card required.

Get your free API key