Integrations

Migrate from ExchangeRate-API

Move an ExchangeRate-API integration to CurrencyCore: URL key to bearer auth, latest and pair mapping, conversion_rates mapping, history depth, pricing, and caveats.


ExchangeRate-API is a clean starting integration: a latest-rates endpoint, a pair conversion endpoint, and a code list. Moving to CurrencyCore keeps the same ISO codes and the same units-per-base arithmetic. The key moves out of the URL path, the status envelope disappears, and history access follows a different plan model.

Public ExchangeRate-API pricing and coverage below were checked on 2026-11-10. Verify the vendor’s current plans before you budget.

What changes at a glance

AreaExchangeRate-APICurrencyCore
Currencies165 currencies160 fiat currencies
Free quota1,500 requests/mo, daily updates1,000 requests/mo, 60/min
Entry paid planPro, $10/moStarter, $9/mo, full history
Update cadenceDaily on Free, hourly on Pro, 5 minutes on BusinessCentral-bank reference rates polled hourly, daily fixings
History1990 for limited pairsGBP/USD and USD/INR parity from 1949, daily majors from 1971, EUR pairs from 1999
AuthAPI key in the URL path, or bearerAuthorization: Bearer or x-api-key
Rate envelopeconversion_ratesrates
Conversionconversion_resultresults[0].result

CurrencyCore does not offer a 5-minute update tier. Its published cadence is hourly polling of central-bank reference rates, with daily fixings underneath. If five-minute updates are a hard requirement, ExchangeRate-API’s Business plan is the closer fit.

1. Move the key out of the path

ExchangeRate-API puts the key in the URL:

curl "https://v6.exchangerate-api.com/v6/YOUR_KEY/latest/USD"

CurrencyCore takes a header:

curl "https://api.currency-core.com/v1/rates/USD" \
  -H "Authorization: Bearer cc_live_your_key"

Remove the key segment from the path, from logs, and from any URL that is stored or shared. Use a test key on Free while integrating. Live keys require a paid plan. See Authentication.

2. Map endpoints

ExchangeRate-API endpointCurrencyCore endpointMapping note
/v6/{key}/latest/{base}/v1/rates/{base}Base stays in the path
/v6/{key}/pair/{from}/{to}/{amount}/v1/convert?from=&to=&amount=Read results[0].result
/v6/{key}/history/{base}/{year}/{month}/{day}/v1/rates/{base}?date=YYYY-MM-DDUse /v1/history for a series
/v6/{key}/codes/v1/currenciesPublic, no key, no quota

A single historical date maps to a dated snapshot. If your code loops over dates to build a chart, replace the loop with one /v1/history call for the same window and one currency. That is fewer requests and a dense series.

3. Map the response envelope

An ExchangeRate-API latest response:

{
  "result": "success",
  "provider": "https://www.exchangerate-api.com",
  "time_last_update_utc": "Tue, 10 Nov 2026 00:02:31 +0000",
  "base_code": "USD",
  "conversion_rates": { "USD": 1, "EUR": 0.9214, "INR": 84.07 }
}

The CurrencyCore equivalent:

{
  "base": "USD",
  "date": "2026-11-10",
  "rates": { "USD": 1, "EUR": 0.9214, "INR": 84.07 }
}

base_code becomes base, conversion_rates becomes rates, and the update timestamp becomes the UTC calendar date. The numbers are still units of the target per 1 unit of base, so the arithmetic does not change.

An ExchangeRate-API pair conversion:

{
  "result": "success",
  "base_code": "USD",
  "target_code": "INR",
  "conversion_rate": 84.07,
  "conversion_result": 8407
}

becomes:

{
  "from": "USD",
  "amount": 100,
  "date": "2026-11-10",
  "results": [{ "to": "INR", "result": 8407, "rate": 84.07 }]
}

The amount is results[0].result and the rate is results[0].rate. If you send several targets in to, match by results[].to.

ExchangeRate-API fieldCurrencyCore fieldNote
resultHTTP statussuccess is not repeated in the body
base_codebaseBase is also in the request path
conversion_ratesratesSame units-per-base meaning
conversion_resultresults[0].resultConversion is an array
conversion_rateresults[0].rateEffective rate
time_last_update_utcdateUTC calendar date, not a formatted timestamp
time_next_update_utcnoneThere is no next-update promise

Errors use the common CurrencyCore envelope:

{ "error": { "code": "invalid_input", "message": "..." } }

Read the stable code. See Errors.

4. Check history and currency coverage

ExchangeRate-API advertises 165 currencies, history from 1990 for limited pairs. CurrencyCore advertises 160 fiat currencies with a different history model:

  • GBP/USD and USD/INR annual parity from 1949.
  • Daily major pairs from 1971.
  • EUR pairs from 1999.
  • Free access limited to the last 30 days.
  • Full history on Starter and above.

Do not assume a pair that starts in 1990 at ExchangeRate-API has a continuous daily series in CurrencyCore from 1949. Check your specific pair against /v1/history and the history coverage guide.

Also diff every stored code against /v1/currencies. CurrencyCore returns 165 entries, but only 160 are fiat. XAU, XAG, XPT, XPD, and XDR are reference entries, not quoted rates. There are no crypto rates.

5. Cut over

  1. Create a test key and delete the key segment from the request builder.
  2. Replace /latest/{base} with /v1/rates/{base}.
  3. Replace /pair/{from}/{to}/{amount} with /v1/convert and read results[0].
  4. Replace per-date history loops with one /v1/history call per currency.
  5. Map conversion_rates to rates and base_code to base.
  6. Shadow a sample and compare the same fixing dates. Allow for provider rounding and carry-forward dates.
  7. Switch reads, watch 401, 403, and 429, then revoke the old key.
  8. Keep the old adapter until the next billing cycle for rollback.

For the provider-neutral checklist, see Migrate an existing integration.