Exchange rate timestamps and freshness

Distinguish observation time from request time, read stale and market-session fields, and design a freshness check for an exchange-rate application.

A white narwhal checking a desk clock beside an observation slip in an archive tray.

There is more than one clock

A rate can be observed, published, fetched by your server and rendered in the browser at different times. Replacing the observation timestamp with the latest request time makes an unchanged rate look newer than it is.

Keep request or retrieval time as a separate application field if you need to measure transport or cache behaviour. It must not overwrite the timestamp supplied with the rate.

Read the Narwhal fields together

Current-rate records contain timestamp and stale. The response-level market_session is open, weekend or interbank_closed. These fields answer different questions: when the observation applies, whether the service marks it stale, and the current session context.

The conversion response carries its selected rate’s timestamp and stale state alongside the converted amount. An open session alone does not establish that every currency record is fresh.

Calculate age without losing the time zone

For an illustrative observation at 09:00 UTC viewed at 09:07 UTC on the same date, the age is seven minutes. An application policy of at most five minutes would reject that observation for its time-sensitive action, even if the request just returned successfully.

Illustrative application policy, not Narwhal’s stale threshold
Observation:           2026-09-24T09:00:00Z
Application time:      2026-09-24T09:07:00Z
Age:                   420 seconds
Application limit:     300 seconds
Within age limit:      false

Make the acceptance rule explicit

Use a time-zone-aware date parser and a reliable application clock. A timestamp that is invalid or unexpectedly in the future should be treated as a validation issue, not as an extra-fresh rate.

  • Read and retain the API stale flag.
  • Compare observation age with your application’s documented limit.
  • Apply any market-session restriction required for the action.
  • Choose a fallback: show the dated observation with a clear label, or disable the action until acceptable data arrives.

Respect the publication schedule

A daily reference series and a current indicative feed have different schedules. The ECB normally updates its euro reference rates around 16:00 CET on working days, excluding TARGET closing days. That schedule illustrates why an overnight or holiday gap does not by itself prove a failed data pipeline.

Narwhal exposes its own session and freshness context. On weekends, a previously accepted observation can remain available with its original timestamp. Your UI should retain that date rather than relabelling it as a new weekend observation.

Cache the context with the number

Cache the rate, direction, timestamp and stale state as one record. If a refresh fails, an older cached record continues to age. Do not reset its timestamp or silently change its stale flag to make it pass an application check.

Historical FX observations use an observation date and do not carry the current-rate stale or market-session fields. A historical date should be interpreted as part of that series, not scored against today’s short current-rate age limit. Use the FX history API reference for those semantics.

Sources and references

Published . Last reviewed .