Two honest answers, shortest first. For trying the API you need no key: latest and conversion endpoints, plus daily history for the last 30 days, answer anonymous requests at 10 requests a minute and 100 an hour per IP. For anything that runs on a schedule or ships to other people, sign up at exchangerate.dev/signup, confirm your email, and copy the key that starts with exr_live_ from the dashboard. Free tier: 5,000 calls a month, 10 requests a minute, daily history for the last 30 days, no credit card.
- Keyless latest, conversion, and 30-day history: 10 requests a minute, 100 an hour per IP.
- The free key is created at /signup, email confirmation, no credit card, and looks like
exr_live_.... - Free tier: 5,000 calls a month, 10 requests a minute, daily history for the last 30 days, live rates arriving 15 minutes late.
- Send the key as
Authorization: Bearer exr_live_..., orX-API-Keywhen a connector cannot set the Authorization header. - Never put the key in a URL or a public browser bundle, headers only, proxied server-side for front-ends.
The no-key path: try the API first
Before creating anything, call the API and look at a real payload. This works from any terminal with no signup:
# No key, no signup, works at 10 req/min, 100 req/hour per IPcurl -s https://api.exchangerate.dev/v1/latest/USD# A single pair, convertedcurl -s https://api.exchangerate.dev/v1/convert/USD/JPY/250Every response carries source and market_session, so you can see whether a rate is a live market rate or the ECB daily fix before you decide anything. You can also run the same call in the browser and read the JSON there.
A one-off script, a classroom exercise, or checking a rate by hand fits inside 100 requests an hour. If that is your whole use case, you are done, no key, nothing to store or rotate.
Get the free key
- Open exchangerate.dev/signup and register with your email. There is no credit-card step.
- Confirm the email. Your dashboard opens with an API key already provisioned.
- Copy the key, it starts with
exr_live_. This prefix is how you recognize it in configs later.
The free tier is 5,000 calls a month at 10 requests a minute, with daily history for the last 30 days and live rates arriving 15 minutes late. Paid tiers receive the same feed live; Free and keyless callers receive live rates 15 minutes late, with different quotas.
Use the key: headers, never URLs
Pass the key in a header. Authorization: Bearer is the primary form; X-API-Key exists for connectors that cannot set an Authorization header (some BI tools and no-code platforms):
# Primary formcurl -s https://api.exchangerate.dev/v1/latest/USD \ -H "Authorization: Bearer exr_live_your_key_here"# Fallback for connectors without Authorization supportcurl -s https://api.exchangerate.dev/v1/latest/USD \ -H "X-API-Key: exr_live_your_key_here"Keep the key out of query strings, out of client-side JavaScript bundles, and out of version control. In application code, read it from an environment variable; for a public front-end, route calls through a small server-side proxy so the key never reaches the browser.
Which path do you actually need?
| Situation | Anonymous | Free key |
|---|---|---|
| Trying the API, one-off checks | Yes, 10 req/min per IP | Works too, not required |
| A cron job or scheduled refresh | Fragile; shares the per-IP cap | Yes; your own 5,000/mo quota |
| A workbook or sheet others refresh | No, their IPs, their caps | Yes, quota follows the key |
| Commercial rate display | Yes, with linked credit | Yes, with linked credit; no plan allows redistribution |
Anonymous or keyed, the feed is the same: indicative mid-market data for models, analytics, and display, not a dealing quote. Every response repeats this in its notice field.