Currency & FX API
The Currency & Exchange Rates API returns live and historical FX data as clean JSON.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
The primary latest endpoint returns a base currency's rates against every symbol with the ECB reference timestamp, and you can convert an amount, pull historical and timeseries rates, measure fluctuation and list supported currencies. It is built for fintech apps, pricing tools and finance dashboards that need reliable exchange-rate data from one endpoint. One ReefAPI key, one shared credit pool, the standard envelope.
Which currency codes resolve, and which only work in the past
The rate source is the European Central Bank's daily reference fixing, so the currency list is the ECB's list — not a universal FX feed. Several codes in the enum are retired and resolve only for dates before they were discontinued. Anything outside the set is reported back to you rather than throwing.
| Group | Codes | When they resolve |
|---|---|---|
| Current ECB set | EUR · USD · JPY · GBP · CHF · AUD · CAD · CNY · HKD · NZD · SEK · NOK · DKK · CZK · HUF · PLN · RON · BGN · TRY · ISK · ILS · INR · IDR · KRW · MYR · PHP · SGD · THB · ZAR · MXN · BRL | any date the ECB published a fixing |
| Retired euro joiners | GRD · CYP · EEK · LTL · LVL · MTL · SIT · SKK | historical dates only — before that country adopted the euro |
| Discontinued | HRK · RUB · ROL · TRL | historical dates only — before the ECB stopped publishing them |
| Crypto, metals, anything else | BTC · ETH · XAU · … | never. A measured request for BTC came back in unavailable["BTC"] alongside the rates that did resolve — not an error, not a null rate. |
Three actions, three precisions, measured in one session: latest returned USD→TRY as 48.117319 (6 decimals), convert returned a rate of 48.06547568 (8 decimals), and timeseries returned EUR→USD as 1.1681 (4 decimals). Do not compare a value from one action against a value from another for equality, and do the rounding for display at the very end.
Real request and response JSON
Captured from the indexed primary action, latest, on .
{
"method": "POST",
"url": "https://api.reefapi.com/currency/v1/latest",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"base": "EUR"
}
}{
"ok": true,
"meta": {
"api": "currency",
"endpoint": "latest",
"mode": "live",
"latency_ms": 274.1,
"record_count": 29,
"bytes": 1547,
"cache_hit": false,
"completeness_pct": 100,
"requests": 1,
"attribution": "Data source: European Central Bank (ECB) euro foreign-exchange reference rates, freely available at https://www.ecb.europa.eu. Published for information purposes only; not intended for transaction/settlement use.",
"unavailable": null
},
"data": {
"base": "EUR",
"date": "[redacted-phone]",
"timestamp": 1784296800,
"rates": {
"USD": 1.1435,
"JPY": 185.65,
"CZK": 24.205,
"DKK": 7.4756,
"GBP": 0.85098,
"HUF": 363.53,
"PLN": 4.3473,
"RON": 5.2406,
"SEK": 11.0405,
"CHF": 0.9228,
"ISK": 143.4,
"NOK": 11.039,
"TRY": 53.907,
"AUD": 1.6394,
"BRL": 5.8499,
"CAD": 1.6035,
"CNY": 7.7501,
"HKD": 8.9653,
"IDR": 20519.71,
"ILS": 3.4843,
"INR": 110.102,
"KRW": 1698.46,
"MXN": 19.9926,
"MYR": 4.6826,
"NZD": 1.9609,
"PHP": 70.441,
"SGD": 1.4765,
"THB": 38.462,
"ZAR": 18.8768
},
"amount": 1,
"source": "ECB"
}
}What the Currency & FX API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| latest | latest reference rates for a base (default EUR) → all or selected target currencies (+ unix timestamp) | Fintech apps call latest to get latest reference rates for a base (default EUR) → all or selected target currencies (+ unix t…. | base, symbols |
| convert | convert an amount from→to at the latest rate (or a given historical date); returns rate + result | Portfolio dashboards call convert to convert an amount from→to at the latest rate (or a given historical date);. | from, to, amount, date |
| historical | reference rates on a past date (YYYY-MM-DD; weekend/holiday → last working day) since 1999-01-04 | Analysts call historical to get reference rates on a past date (YYYY-MM-DD; weekend/holiday → last working day) since 1999-01-04. | date, base, symbols |
| timeseries | rates over a date range (working days) for a base → selected/all targets; {date:{CUR:val}} | Data teams call timeseries to get rates over a date range (working days) for a base → selected/all targets; {date:{CUR:val}}. | start, end, base, symbols |
| fluctuation | per-currency change over a date range: {CUR:{start_rate,end_rate,change,change_pct}} (derived from the range endpoints) | Fintech apps call fluctuation to get per-currency change over a date range. | start, end, base, symbols |
| currencies | the current ECB reference currency set (code → name) | Portfolio dashboards call currencies to get the current ECB reference currency set (code → name). | none |
Call latest from your stack
curl -X POST https://api.reefapi.com/currency/v1/latest \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"base":"EUR"}'import requests
r = requests.post(
"https://api.reefapi.com/currency/v1/latest",
headers={"x-api-key": REEF_KEY},
json={
"base": "EUR"
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/currency/v1/latest", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"base": "EUR"
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.currency.latest with {"base":"EUR"}.Who uses this API and why
- Fintech and pricing tools call convert to show product prices in a user's local currency.
- Finance dashboards use timeseries and fluctuation to chart and monitor rate movements.
- Accounting workflows use historical to book transactions at the correct dated exchange rate.
Questions developers ask before integrating
I asked for a weekend date and got a different one back. Why?
Because the ECB does not publish on weekends or TARGET holidays, and inventing a rate for a day that had none would be worse than telling you. A measured conversion requested for 2026-08-23, a Sunday, returned date 2026-08-21 — the previous Friday's fixing — with requested_date 2026-08-23 echoed back so the substitution is visible. Always read date, not the value you sent. The same roll-back happens in fluctuation: a range starting 2026-08-01 reported start 2026-08-01 alongside start_date 2026-08-03, the first day with a published rate.
Why does my time series have gaps?
Missing days are simply absent from the rates object rather than present with null. A measured timeseries from 2026-08-20 to 2026-08-26 returned exactly five keys — 08-20, 08-21, 08-24, 08-25 and 08-26 — because the 22nd and 23rd were a weekend. If you are drawing a chart or joining against a calendar table, iterate the keys you got rather than the dates you asked for, and decide deliberately whether to carry the last value forward across the gap.
Are these live rates I can trade on?
No. They are the ECB's reference rates, published once per business day at 16:00 CET/CEST — the timestamp field is that publication instant as Unix seconds (measured 1787752800). Between publications the value does not move no matter how often you call. They are the right rates for accounting, invoicing, price normalization and reporting, and the wrong ones for anything that needs a live bid and ask. There is no spread here because there is no market quote.
The ECB publishes rates against the euro — how does base=USD work?
The set is re-expressed against the base you asked for. A measured call with base USD returned EUR 0.856971, GBP 0.733679 and TRY 48.117319, all derived from that day's euro fixings. The arithmetic is exact but it does pass through euro, so a USD→TRY figure and a EUR→TRY figure are consistent by construction rather than independently sourced. For accounting where a tiny difference matters, pick one base and stay on it rather than mixing.
What happens if I ask for a currency that is not covered?
It comes back in unavailable[] and everything else still resolves. A measured request for EUR, GBP, TRY and BTC returned rates for the first three and unavailable ["BTC"]. That is deliberate: one unrecognized symbol in a list of twenty should not fail the call. Check unavailable on every response — a symbol silently missing from rates is the single easiest way to end up computing with a zero.
How do I get the change between two dates without pulling every day?
fluctuation does it in one call. A measured EUR-based range from 2026-08-01 to 2026-08-26 returned, per currency, start_rate, end_rate, change and change_pct — TRY moved 54.8333 to 56.1481, a change of 1.3148 or 2.3978 percent. It also reports the actual start_date and end_date it used after rolling to published days. That is the cheap way to answer 'how much did our supplier currency move this month' without walking a series.
Can I convert an amount rather than reading a rate?
Yes — convert takes from, to and amount and returns the rate alongside result, which is simply amount times rate. A measured 100 USD to TRY at the 2026-08-21 fixing returned rate 48.06547568 and result 4806.547568. Note it returns the unrounded product: rounding to currency minor units is your decision, because the correct rule differs between invoicing, tax and accounting, and TRY, JPY and ISK do not all have two decimal places.
What is the Currency & FX API?
Currency & FX API is a ReefAPI endpoint group for exchange rates, conversion and historical rates. It returns live JSON through POST requests under /currency/v1.
Is the Currency & FX API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. Currency & FX calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Currency & FX login or account?
No login to Currency & FX is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Currency & FX data?
The page example is captured from a live latest call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Currency & FX API use?
Currency & FX actions currently cost 1-2 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Currency & FX from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call currency actions with the same key, credit pool and JSON envelope used by normal REST requests.
Is the Currency & FX API a Currency & FX scraper?
It is the managed alternative to a DIY Currency & FX scraper. Instead of building and maintaining your own scraper — proxies, headless browsers, captcha and constant breakage — you call one ReefAPI endpoint and get the same exchange rates, conversion and historical rates back as clean JSON.