exchange-api: currency rates as static files on a CDN
Free Currency Exchange Rates API with 200+ Currencies & No Rate Limits
At a glance
- What is it?
- A free currency exchange rate service published as dated JSON on jsDelivr with a Cloudflare Pages mirror, covering 200+ currencies including cryptocurrencies and metals, with no API key and no rate limit.
- Who is it for?
- This API is the right answer when you need a currency rate in a script, a static site build or a side project, and you do not want an account, a key or a quota conversation. It is the wrong answer for anything that bills, settles or hedges, because the data is daily and there is no intraday refresh to depend on.
- Can I use it commercially?
- Yes. CC0-1.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 53 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A URL pattern instead of a client library
There is no SDK to install and no key to obtain. The entire interface is one URL template:
https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@{date}/{apiVersion}/{endpoint}Three slots, and each one is documented. The date is either `latest` or a specific `YYYY-MM-DD`. The API version sits in the path as `{apiVersion}`, currently `v1`. The endpoint is what you want, and every endpoint is available with an HTTP GET in two formats: `/{endpoint}.json` for prettified output and `/{endpoint}.min.json` for the minified version.
That design has one consequence worth naming early, because it decides whether this fits your project. The data is published as a package on npm and served from a CDN, so a response is a static file with an HTTP cache header and a content hash. That is why the feature list can claim free and fast responses with no rate limits: there is no application server doing per-request work on your behalf. It also means the freshness ceiling is one day, since the README lists the data as daily updated.
For a currency display on a marketing page, a data pipeline that joins prices at build time, or a script that converts an amount once, that trade is excellent. For a live trading screen or an invoice that has to settle today, it is not.
Fetching rates, and the fallback the README insists on
A request is an ordinary GET. The example the README leads with returns the currency list with EUR as base currency:
https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/eur.jsonThere is a second host for the same content, described as an additional fallback URL on Cloudflare, using the date in place of the package version slot:
https://{date}.currency-api.pages.dev/{apiVersion}/{endpoint}So the same file is reachable at `https://latest.currency-api.pages.dev/v1/currencies/eur.json` and, for a pinned date, at `https://2024-03-06.currency-api.pages.dev/v1/currencies/eur.json`.
The README does not treat this as optional. Its warning says to include the fallback mechanism in your code, giving the example of fetching from `currency-api.pages.dev` if the `cdn.jsdelivr.net` link fails, and it points at a specific issue for the details. Both endpoints carry a date slot, so implementing the fallback is a matter of swapping the hostname and leaving the rest of the path alone.
The README is short on what a failure looks like, and that is the main thing to design around. It does not document status codes, retry guidance, or an error body, so a client that assumes a 200 with valid JSON should decide for itself what to do when the CDN serves an HTML error page or npm has not published the date it asked for.
Choosing a base currency, including bitcoin
The base currency is part of the path, not a query parameter. `currencies/eur.json` returns everything priced against EUR, and `currencies/btc.json` returns the same set priced against BTC. The README shows both, plus the dated variant:
https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@2024-03-06/v1/currencies/eur.jsonThe feature list puts the coverage at 200+ currencies, including common cryptocurrencies and metals, and the topic tags on the repository list bitcoin, cryptocurrency, currency-conversion, forex and forex-api. Whether bitcoin is a first class base or a line item among many is worth checking against the `currencies` endpoint before you design around it, because a crypto base pulls in a second volatility source that a fiat base does not.
The full inventory is available on its own. `/currencies` lists everything available in prettified JSON, and `/currencies.min.json` is the minified version of the same thing, both at `https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/`. That endpoint is the one to cache first if you are writing a converter, since it tells you which codes exist before you start requesting pairs.
What the repository actually contains
The tree explains the pipeline more clearly than the README does. There is `allcurrencies.min.json` and `country.json` at the root, both of which read like generated output committed to the repository. There is `currscript.js`, which is presumably where rates get fetched and reshaped, and `semver-date.js`, which is where the date-in-the-version-slot trick is probably implemented, since npm versions have to be valid semver and a date is a workable version number. `package.json` confirms the toolchain: dependencies on `fs-extra`, `playwright` and `semver`, with `wrangler` as a dev dependency, which is the Cloudflare Pages CLI. The presence of `package-lock.json` and `skeleton-package.json` suggests the published npm package is generated from a template.
There is also an `other/` directory and a `money.jpg` used as the README banner. The `money.jpg` is decoration. `other/` is undocumented in the README, which is the one part of the tree you cannot evaluate from what is written here.
The build badge in the README points at a workflow called Publish-Currencies, which is the generation step that produces the package the CDN serves. In other words, the repository is not the API. The API is the npm package, and this repository is the tool that publishes it. That distinction matters when something looks wrong: you cannot fix a bad rate here, you can only open an issue and wait for the next run.
There is also a `MIGRATION.md` at the root, and the README links it under a heading about migrating from a previous currency API. If you arrive at this service from an older URL shape, that file is the one to read before debugging your own code.
CC0 licensing and the limits of a daily snapshot
The licence is CC0-1.0, which is about as permissive as a data licence gets: the repository is in the public domain, so there is no attribution requirement and nothing to negotiate. There is no contributor licensing agreement and no commercial restriction in what the README documents. For a rate table you want to vendor into a commercial product, that removes an entire category of legal review.
The repository language is listed as Python even though the visible toolchain in `package.json` is Node, which is a small inconsistency in the metadata worth ignoring rather than inferring from.
On accuracy, the README claims daily updates and nothing more specific: no source is named, no refresh time is given, no method is described. So the honest position is that the numbers are as fresh as a day-old snapshot from an unstated upstream. For anything that reports money to a customer, that is a documented assumption rather than a verified one, and the sensible engineering response is to treat the value as indicative and label it accordingly in your own UI.
The last push was on 2026-08-20 on the `main` branch, and the repository is not archived. There is no release history to read, which is consistent with the npm-tag-and-publish model: the meaningful version history lives in the package tags on the CDN, not in GitHub releases.
Where this sits against a paid or key-based feed
The comparison that matters is with a commercial rate feed, and the difference is not accuracy so much as the shape of the failure. A keyed feed gives you an SLA, a support contact, a documented error contract and usually intraday updates. It also gives you a signup, a quota and a bill. This API gives you none of the first four and all of the cost savings of the fifth.
Between those two extremes sit the free tier of a major provider and a self-hosted reference table such as the one the European Central Bank publishes. A provider's free tier is closer to this API in price and closer to a commercial feed in reliability, with the difference usually being request quotas and a requirement to send the base currency as a query string against a rate-limited endpoint. The ECB route is free and authoritative but covers fiat only, so cryptocurrency bases are out of reach there.
The design choice that sets this project apart from all of them is immutability. Because the date is part of the path and the underlying object is a published package, a URL for a specific day is stable forever. A rate you recorded on 2024-03-06 can be fetched again later and will return the same bytes. That property is genuinely useful for audit trails, backfills and reproducible data pipelines, and it is not something a live rate endpoint offers.
The cost of that choice is that `latest` is a moving target while a dated URL is frozen. If you cache aggressively, you need a policy for when you refresh, and the README's daily update line is the only guidance on the cadence. Pin the date, cache the response, and let a scheduled job advance the pin.
Editorial conclusion
This API is the right answer when you need a currency rate in a script, a static site build or a side project, and you do not want an account, a key or a quota conversation. It is the wrong answer for anything that bills, settles or hedges, because the data is daily and there is no intraday refresh to depend on. The one thing you must implement is the fallback: if `cdn.jsdelivr.net` fails, fetch `currency-api.pages.dev`, which the README asks for explicitly and which is why both hostnames are documented rather than one. Start with `https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/eur.json`, pin a date instead of `latest` if you need reproducibility, and read `MIGRATION.md` if you are coming from the older endpoint shape.
Frequently asked questions
Is the fawazahmed0 exchange API free and does it need a key?
Yes on both counts. The feature list says free with no rate limits, and the whole interface is a public URL on jsDelivr or the Cloudflare Pages mirror, so there is no API key, no account and no signup.
How do I get a specific currency base from fawazahmed0 exchange-api?
Put the code in the path. `currencies/eur.json` returns rates with EUR as base and `currencies/btc.json` returns the same set priced against bitcoin, both at the `latest` or a `YYYY-MM-DD` date in the version slot.
What should I do if cdn.jsdelivr.net fails?
Fetch from the Cloudflare Pages mirror instead, which serves the same paths with the date as the subdomain. The README explicitly asks callers to implement this fallback and links an issue describing it.
How often are the exchange rates updated?
The feature list says daily. The README does not name the upstream source or a refresh time, so a response is a snapshot that is at best a day old rather than a live rate.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/fawazahmed0-exchange-api)