Compare data_updated_at with timestamp to calculate observation age. Read market_session for the market's status and stale for each requested currency's flag. A weekend response can carry the final observation from the trading week, so its response time does not establish a fresh weekend quote.
Request the rate and its time fields
Read the rate together with the metadata in the latest response. Every latest response carries source, market_session, timestamp, data_updated_at and rates, plus the notice "Indicative rates, not for settlement." The stale object has a separate true or false value for each requested currency.
The API quotes every currency against USD. Keep the response's rate, session and time fields together when you check a weekend or holiday result. The rate value alone does not tell you when its contributing observation was made, and the response time has a different meaning from the observation time.
curl "https://api.exchangerate.dev/v1/latest/USD?symbols=EUR"Identify the market session
market_session is open during the interbank week. It is weekend after the Friday 17:00 New York close until Sunday 17:00 New York, or interbank_closed for a known non-weekend closure. Read that value to distinguish the scheduled weekend closure from another known closure.
A weekend response can contain the final observation from the trading week. The label describes the session; it does not imply a fresh weekend quote. For a holiday check, use the returned session alongside the observation time. The interbank_closed value identifies a known non-weekend closure, while data_updated_at supplies the observation time behind the rates.
Calculate the observation age
The formula is observation age = timestamp - data_updated_at, expressed in minutes. timestamp is when the response was made. data_updated_at is the oldest contributing observation behind the rates in that response, so use it when you calculate how old the observation was at response time.
Use the example numbers from one response made at 2026-10-29 04:35 UTC. Its data_updated_at is 2026-10-29 04:19 UTC; the observation was 16 minutes old when the response was made. The EUR value is 0.89717 EUR per USD, which is the inverse of the USD per EUR rate on the EUR to USD rate page.
| Field | Meaning | Example value |
|---|---|---|
| market_session | The market's session status | open |
| data_updated_at | The oldest contributing observation behind the rates | 2026-10-29 04:19 UTC |
| timestamp | When the response was made | 2026-10-29 04:35 UTC |
| stale | Per currency, whether the rate is marked stale | {"EUR":false} |
Check each currency's stale flag
stale is an object with one true or false value per requested currency. Read the entry for the currency you are checking. Treating the whole object as a single boolean loses the per-currency result that the response supplies.
In the example response, the object is {"EUR":false}. Keep those flags alongside the calculated age and session. Each field answers a separate question: the flag says whether that currency's rate is marked stale, the age measures the time between observation and response, and the session identifies the market's status.
Account for weekend gaps in history
/v1/range has no row for weekend days. A latest response that carries the final observation from the trading week does not create a weekend row in the range response.
When you compare latest and historical responses, preserve that distinction. Use the latest response's own time fields to calculate its observation age. Read the range response with the expectation that weekend days have no rows; a latest response made during the weekend can still refer to an observation from the trading week.
Allow for your access plan's delay
Keyless calls allow 10 requests a minute and 100 an hour per IP, with rates 15 minutes late. A free key has 5,000 requests a month and 10 requests a minute, with rates also 15 minutes late. Paid plans are live.
Check the returned time fields even when you know the plan's delay. Paid access does not imply a fresh weekend observation. The figures are indicative mid-market rates, not for settlement or trading. Banks, cards and transfer services apply their own spread and fees, so these rates do not specify the amount a transfer pays out.