Home Documentation Pricing API Status Blog About FAQ Support

Open Exchange Rates Time-Series Burns Your Quota

Reviewed by Madhushan, Fintech Developer — April 2026

If you've shipped anything against Open Exchange Rates that touches history, you've probably hit this the hard way. Their documentation is explicit: "Requests to the time-series.json API endpoint count as one request for each day of data returned."

Meaning:

For a charting use case that backfills a year of daily rates across 5 currency pairs, you're at 5 × 365 = 1,825 requests — past the free tier in a single page load.

AllRatesToday prices historical differently: one request per range, not per day. This article explains the difference, what it costs in practice, and how to design around either.

The quota model

OpenExchangeRates time-series.json

GET /api/time-series.json?app_id=XXX&start=2025-01-01&end=2025-12-31&base=USD&symbols=EUR
# costs: 365 requests against your monthly quota

The endpoint returns all 365 daily rates in one HTTP call — but internally it's billed as if you'd made 365 individual historical requests.

AllRatesToday historical-rates

GET /api/historical-rates?source=USD&target=EUR&from=2025-01-01&to=2025-12-31
# costs: 1 request against your monthly quota

One HTTP call, one quota decrement.

Concrete scenarios

Scenario 1: Dashboard with 5 pairs × 90-day history

Scenario 2: Tax-year backfill (1 year, 1 pair)

Scenario 3: Multi-pair backtest (10 pairs × 3 years)

The OpenExchangeRates model effectively turns historical analysis into a line-item purchase: every day of data you want, you pay for.

Why the pricing model exists

Historical data is bandwidth-heavy. An "all currencies for one day" response can be 5-10 KB. Open Exchange Rates' per-day billing reflects internal cost: each day is a separate backend lookup. It's defensible from an infra economics perspective.

It's still a bad developer experience. When your request count doesn't match your HTTP call count, capacity planning gets confusing fast. You have to explain to new team members why one line of code burned 365 requests.

AllRatesToday's approach is to price the API surface area, not the underlying row count. One call, one request, regardless of the date range. Simpler to reason about, easier to stay under quota.

When per-day billing is fine

When range-based pricing matters

Any of these become 10-50x cheaper in quota terms on AllRatesToday.

AllRatesToday historical endpoint, in detail

curl -X GET "https://allratestoday.com/api/historical-rates?source=USD&target=EUR&from=2025-01-01&to=2025-12-31" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

{
  "source": "USD",
  "target": "EUR",
  "from": "2025-01-01",
  "to": "2025-12-31",
  "rates": [
    { "time": "2025-01-01", "rate": 0.9521 },
    { "time": "2025-01-02", "rate": 0.9534 },
    ...
    { "time": "2025-12-31", "rate": 0.9214 }
  ]
}

Supported periods include shortcuts (period=30d, period=1y) and custom date ranges. Every range is one request.

Migrating a time-series query

Most apps using Open Exchange Rates' time-series.json pass start, end, and a base/symbols combination. The equivalent AllRatesToday call is:

- https://openexchangerates.org/api/time-series.json?start=2025-01-01&end=2025-12-31&base=USD&symbols=EUR&app_id=XXX
+ https://allratestoday.com/api/historical-rates?source=USD&target=EUR&from=2025-01-01&to=2025-12-31
  (Authorization: Bearer YOUR_API_KEY)

Response shape is different (array of {time, rate} vs keyed object), but the transformation is straightforward.

What if you still need per-day granularity?

Both APIs support single-date historical lookups at one-request-per-date:

If your app cares about a handful of specific dates rather than ranges, either API is fine.

Stop burning quota on history

Free historical data, one request per range, 60-second real-time updates. No credit card.

Get your free API key