Free Historical Exchange Rate API
Find a free historical exchange rate API for a date or date range, compare the limits that matter, and integrate validated JSON data without confusing history with live conversion.
Historical exchange rate API free: quick answer
A useful free historical currency API returns rates for a specified date or range, identifies the base and quote currencies, and documents its source, coverage, update schedule, limits, and licensing. “Free” may mean a public endpoint, a quota-limited plan, or a trial—verify the current terms rather than relying on the label.
| Need | Check | Why it matters |
|---|---|---|
| Single date | YYYY-MM-DD endpoint or parameter | Accounting and invoice conversion |
| Date range | from, to, pagination | Charts and time-series analysis |
| Free access | Key, quota, attribution, CORS | Determines production fit |
What developers want from a free historical exchange rate API
Query a historical exchange rate by date
The central task is to supply a base currency such as USD, one or more quote currencies such as EUR or CNY, and a past date. The response should identify the observation date because weekends and holidays may use the previous available fixing.
Request a historical exchange rate date range
For charting, reconciliation, and research, users want daily observations between two dates. Check maximum range per request, result ordering, pagination, grouping, and whether missing days are omitted or filled.
Receive a consistent historical exchange rates JSON API response
A dependable response model should represent ISO 4217 currency codes, base and quote currencies, daily reference rates, observation timestamps, time-series dates, quota metadata, and source attribution consistently. Normalize these fields before storing data from more than one provider.
Understand historical exchange rate data before choosing an API
Two APIs can return different values for the same currency pair and date without either response being technically broken. The difference may come from the source, fixing time, market convention, base-currency rule, calculation method, or later revision. Define the rate you need before comparing endpoint features.
Base currency, quote currency, and inversion
A USD/EUR rate commonly means the number of euros for one US dollar, but naming conventions vary. Store the base, quote, value, and provider convention together. If you invert a rate, retain enough decimal precision and record that the value was derived rather than supplied directly.
Reference rates vs market rates
Official daily reference rates are designed for statistical or reporting use. Market feeds may expose bid, ask, midpoint, open, high, low, or close at a specific timestamp. Neither should be presented as the other, and neither automatically includes bank spreads or card fees.
Weekends, holidays, time zones, and revisions
Daily series often omit non-business days or carry the previous observation forward. Providers can also revise past values. Decide whether your system should preserve gaps, use the previous fixing, or reject a missing date, and keep both the requested date and the actual observation date.
Worked non-business-day example: requested date is not observation date
Suppose an application requests USD/EUR for Sunday, 2025-01-05, and the provider returns 0.9700 using the last published fixing from Friday, 2025-01-03. Converting a $10,000 invoice under an approved “previous business-day fixing” policy gives €9,700, but the record must still say requested_date=2025-01-05, observed_date=2025-01-03, and fill_method=previous_fixing. Labeling 0.9700 as a Sunday observation invents a market data point that the source never published.
The same input should produce different storage behavior by use case. An accounting report may carry Friday’s fixing forward when its policy requires a rate for every calendar date. A market-return series should normally keep Saturday and Sunday missing, then join the next genuine observation, because copied values create artificial zero-return days and distort volatility or correlation. Preserve the source publication time and dataset version as well: if Friday’s fixing is later revised to 0.9698, append or version the correction and identify which conversions need recomputation rather than silently changing an audited result.
Currency lifecycle, redenomination, and predecessor codes
Long histories can cross a currency launch, redenomination, peg change, or withdrawal. Confirm whether the API preserves obsolete ISO codes, maps them into a successor currency, or truncates the series. Store the original code and conversion rule; silently rewriting a predecessor currency into its successor creates a false historical comparison.
Define the legally or operationally accepted source, date rule, rounding policy, and audit fields.
Prefer a documented time series with stable dates, consistent units, and an explicit missing-value policy.
Use market-appropriate data and prevent look-ahead, revised-history, timezone, and survivorship errors.
Historical reference data does not represent the final executable price, spread, fee, or settlement amount.
How to compare free historical currency API options
| Criterion | Questions to ask | Risk |
|---|---|---|
| History | Earliest date? Daily or intraday? Range endpoint? | Free tier may expose only recent dates |
| Coverage | Which fiat currencies and base currencies? | Cross rates may be derived |
| Source | Central-bank reference, market feed, or aggregate? | Rates can differ by methodology |
| Free terms | Requests, key, attribution, caching, commercial use? | Trial access may expire |
| Operations | Status, retries, versioning, error schema? | Silent gaps can corrupt reports |
Do not mix reference rates, executable FX prices, and converters
A central-bank daily reference rate is suitable for many reporting tasks but is not an executable bid or ask. A currency converter may calculate an amount without exposing a historical time series. Keep these intents separate when evaluating APIs.
A practical free-tier checklist
- Confirm historical endpoints are included in the free tier, not only latest rates.
- Record request quotas, rate limits, attribution, caching, and commercial-use terms.
- Check the earliest available date, supported base currencies, and missing-day policy.
- Test error responses for invalid dates, unsupported codes, and quota exhaustion.
Choose the source category before the provider
| Source type | Strength | Typical limitation | Good fit |
|---|---|---|---|
| Central-bank or public statistics | Documented official reference series | Limited currencies, frequencies, or base conventions | Reporting and research |
| Commercial API free tier | Developer-friendly JSON, SDKs, support | Quota, key, history, or feature restrictions | Apps and prototypes |
| Market-data feed | Timestamps and richer price fields | Licensing, redistribution, and higher cost | Trading and valuation |
| Aggregator | Broad coverage and normalized schemas | Methodology and provenance need inspection | Multi-region products |
How to get historical exchange rates via API
Provider-neutral REST request for USD/EUR history
GET /historical?base=USD&symbols=EUR&from=2025-01-01&to=2025-01-31
Accept: application/json
{
"base": "USD",
"start_date": "2025-01-01",
"end_date": "2025-01-31",
"rates": {
"2025-01-02": { "EUR": 0.00 }
}
}The path and field names are illustrative, not a claim about a specific provider. Do not copy the placeholder rate into production. Adapt the request to the selected API documentation and validate the returned value and observation date.
Validate before storing a daily historical exchange rate
- Validate ISO 4217 currency codes and the requested date order.
- Confirm whether the rate means quote units per one base unit.
- Preserve the provider, source date, retrieval time, and raw response.
- Handle weekends, holidays, nulls, duplicates, retries, and pagination explicitly.
A production-safe Python ingestion pattern
from decimal import Decimal
from datetime import date
import requests
params = {
"base": "USD",
"symbols": "EUR",
"from": "2025-01-01",
"to": "2025-01-31",
}
response = requests.get(API_URL, params=params, timeout=20)
response.raise_for_status()
payload = response.json()
for observed_on, values in payload["rates"].items():
rate = Decimal(str(values["EUR"]))
assert rate > 0
save_rate(
base="USD",
quote="EUR",
observed_on=date.fromisoformat(observed_on),
value=rate,
provider=PROVIDER_NAME,
retrieved_at_utc=RETRIEVED_AT,
)The field names remain illustrative. Use decimal arithmetic for stored financial values, set explicit timeouts, reject malformed payloads, and make writes idempotent so retries do not create duplicate observations.
Pagination, caching, and retry behavior
- Split long ranges into documented windows and checkpoint the last completed date.
- Use exponential backoff with jitter for retryable responses; do not retry invalid parameters.
- Cache immutable historical observations only after checking whether the provider revises history.
- Store the response version or checksum so changed historical values can be detected.
Historical FX data quality and production checks
Validate completeness and continuity
Build an expected business-day calendar for each series, then classify every gap as an expected holiday, an unavailable fixing, a provider failure, or a processing error. Do not silently turn missing observations into zero.
Detect outliers without inventing replacement rates
Flag impossible values, non-positive rates, abrupt changes, duplicate dates, and inconsistent reciprocal pairs. An alert should trigger review or a second-source comparison; it should not automatically manufacture a replacement value.
Preserve provenance for audit and reconciliation
| Store | Purpose |
|---|---|
| Provider and endpoint version | Reproduce the retrieval path |
| Requested and observed dates | Explain weekend or holiday fallback |
| Base, quote, rate, and precision | Prevent inversion and rounding mistakes |
| Source timestamp and retrieval time | Separate data age from ingestion delay |
| Raw payload checksum | Detect revisions and duplicate processing |
Monitor the free tier as an external dependency
Track success rate, latency, quota headers, schema changes, stale observations, and license updates. Keep a documented fallback or a recovery export for critical workflows because free access, quotas, and endpoints can change.
How QVeris helps with historical forex rates API discovery
QVeris helps developers and agents discover and inspect callable capabilities. Start with the Alpha Vantage FX Daily tool details, inspect its inputs and outputs, then follow the QVeris REST API reference to connect it. This reduces discovery and schema-inspection work; it does not change a provider’s data, limits, license, or service level.
Free historical exchange rate API FAQ
Yes. Public endpoints and free tiers exist, but historical depth, currencies, attribution, authentication, and quotas differ.
Send a base currency, targets, and a date or range, then validate the source date, units, timezone, and missing observations.
Several commercial APIs and public reference-rate services do. Choose by history, coverage, source methodology, license, and operational limits.
Yes when the provider exposes a historical endpoint. Confirm its date format and how it handles weekends and holidays.
Some do; others are keyless but may require attribution or impose rate limits. Check the current documentation and terms.
Check source, history, currencies, base rules, frequency, gaps, quotas, authentication, attribution, caching, licensing, errors, and status visibility.
Many daily reference series publish only on business days. Decide whether to keep the gap or use the previous available observation according to your business rule.
They may use different sources, fixing times, market conventions, aggregation methods, rounding, or historical revisions.
Often yes, subject to the provider’s license and revision policy. Retain provenance and a checksum so revisions remain detectable.
Not by default. A daily reference rate is not an executable bid or ask and does not include spread, fees, or slippage.
