API reference
The complete REST contract: authentication, limits, response fields, endpoints, and errors. If you are making your first request, the quickstart is the faster place to begin.
Introduction
exchangerate.dev is a REST API for indicative foreign exchange rates — live intraday on trading days for actively traded currencies, with source, market_session, and honest freshness on every response. Try the free exchange rate API anonymously, or start with a free key — no credit card required.
market_session and source fields tell you exactly what you are looking at on every call.Quickstart
Make your first data call without signup. The standalone 60-second quickstart has the request, exact response shape, and optional API-key step.
Authentication
You can evaluate data routes without a key. Pass your key in the Authorization: Bearer header for account-tier quotas and attribution. Anonymous access is limited to 12 requests/minute and 100 requests/hour per IP. Never embed an account key in public browser JavaScript; use anonymous access or a server-side proxy. Account quota resets at 00:00 UTC on the 1st.
Rate limits
Anonymous limits are per IP; account limits are per key and calendar month. On 429 the response includes Retry-After.
Response metadata
Keep this metadata with the rate. It is the API's freshness and derivation context.
Operation registry
Every public integration operation is listed once by method and OpenAPI path. See the OpenAPI 3.1 schema or ReDoc for complete schemas.
Path and query base values must match when both are sent; conflicts return 400.
| Operation | Purpose | Parameters | Request | Response | Endpoint errors |
|---|---|---|---|---|---|
GET /v1/latest | Latest rates with USD as the default base. | base, path_base, symbols (query; optional) | /v1/latest?base=USD&symbols=EUR,GBP | LatestResponse | data and limit errors |
GET /v1/latest/{path_base} | Latest rates with a path base. | path_base (path); base, symbols (query); path/query base must match | /v1/latest/USD?symbols=EUR,GBP | LatestResponse | conflicting base, data, and limit errors |
GET /v1/{date} | Historical snapshot for a date. | date (path); base, path_base, symbols (query) | /v1/2024-01-15?base=EUR&symbols=USD,GBP | HistoricalResponse | bad date or unavailable data |
GET /v1/{date}/{path_base} | Historical snapshot with a path base. | date, path_base (path); base, symbols (query); path/query base must match | /v1/2024-01-15/EUR?symbols=USD,GBP | HistoricalResponse | conflicting base, bad date, or unavailable data |
GET /v1/convert/{from_ccy}/{to_ccy} | Convert one unit or a query-supplied amount. | from_ccy, to_ccy (path); amount (query, default 1) | /v1/convert/USD/EUR?amount=100 | ConvertResponse | invalid pair, amount, or unavailable data |
GET /v1/convert/{from_ccy}/{to_ccy}/{amount} | Convert a path-supplied amount. | from_ccy, to_ccy, amount (path) | /v1/convert/USD/EUR/100 | ConvertResponse | invalid pair, amount, or unavailable data |
POST /v1/convert | Convert several amounts in one request. | JSON body: from and pairs (required) | POST /v1/convert | ConvertBatchResponse | invalid request, amount, or unavailable data |
GET /v1/range | Daily time series with JSON, CSV, or Parquet output. | symbols, start_date, end_date required by API validation; base, cursor, format optional | /v1/range?base=USD&symbols=EUR,GBP&start_date=2024-01-01&end_date=2024-06-30 | RangeResponse | missing parameter, bad date, or unavailable data |
GET /v1/currencies | List supported currencies and their display facts. | none | /v1/currencies | CurrenciesResponse | standard endpoint errors |
GET /v1/rate/{slug} | Return one flat pair quote by slug. | slug (path) | /v1/rate/eur-usd | RateResponse | invalid pair or unavailable data |
POST /v1/account/provision | Create an account organization and first key when absent. | session auth; optional JSON body: signup_attribution, marketing_consent | POST /v1/account/provision | ApiKeyCreatedResponse | authentication or account errors |
GET /v1/account | Read account, active key, and monthly usage. | session authentication | /v1/account | AccountResponse | authentication or account errors |
GET /v1/account/usage/daily | Read daily usage for up to 90 days. | session auth; days (query, optional) | /v1/account/usage/daily?days=30 | DailyUsageResponse | authentication or account errors |
DELETE /v1/account | Cancel billing and delete account data. | session authentication | DELETE /v1/account | DeleteAccountResponse | authentication, account, or billing errors |
POST /v1/keys/rotate | Rotate the active API key with a grace period. | session authentication | POST /v1/keys/rotate | ApiKeyCreatedResponse | authentication or account errors |
DELETE /v1/keys | Revoke the active API key. | session authentication | DELETE /v1/keys | success envelope | authentication or account errors |
POST /v1/consent | Record acceptance of a policy version. | session auth; JSON body: policy_version (required) | POST /v1/consent | ConsentResponse | authentication or validation errors |
GET /v1/latest
Latest rates for all supported pairs, or a filtered subset via ?symbols=.
GET /v1/{YYYY-MM-DD}
Historical snapshot — returns the reference rate as published on that date. Published coverage starts on 1999-01-04. The historical data guide covers weekends, ranges, pagination, and downloads.
GET /v1/convert
Single or batch currency conversion. The POST form accepts multiple pairs in one call.
GET /v1/rate/{slug}
Single-pair quote by slug (e.g. eur-usd) — a flat, single-pair shape distinct from /v1/convert (which nests per-pair results under conversions[] and adds amount/converted). Slug is case-insensitive; malformed or unknown pairs return invalid_pair.
GET /v1/range
Daily time-series for a date window. JSON responses are capped at 366 rows/page with keyset pagination; pass format=csv or format=parquet to download the full window as a single file.
GET /v1/currencies
Full list of supported currencies with name, type, decimal precision, minor units, and derived flag. This endpoint takes no parameters.
GET /v1/account
Your org, active key, and current-month usage.
Errors
Every error uses the same envelope. A 429 response also includes a Retry-After header.
Data errors: invalid_pair, unsupported_base, bad_date, invalid_amount, invalid_request, missing_parameter, data_unavailable, no_data_for_date, live_unavailable, source_unavailable, and service_unavailable.
Authentication and limit errors: invalid_api_key, auth_unavailable, forbidden, rate_limited, ip_rate_limited, quota_exceeded, and quota_unavailable.
Python
Use any HTTP client. The Python integration guide has a compact production example.
Node
Use built-in fetch or another HTTP client. The JavaScript conversion guide covers server-safe use.
MCP server
Use exchangerate.dev as a tool in any MCP-compatible AI agent. The dedicated MCP quickstart has setup, authentication, and the tool table.