LearnReference

Reading source and market_session in your pipeline

Every exchangerate.dev response carries two freshness fields: source and market_session. Together they tell you exactly what you are looking at, and whether to accept that rate or wait for a fresher one.

19 Jun 2026 · 5 min read

Every call to /v1/latest, /v1/convert, or /v1/range returns a source field and a market_session field alongside the rate data. Read both before you act on a number. source tells you the quality class of the data; market_session tells you the state of the FX trading day when that data was captured.

  • source has three values: live (spot), ecb_daily (ECB fix), or market_daily (stored daily market-feed close for currencies without an ECB fix).
  • market_session reports the state of the FX trading day: open, weekend, or interbank_closed.
  • For a live-only pipeline, request a single pair and reject the response client-side unless its per-currency sources value is live.
  • Use data_updated_at alongside source to see exactly when the underlying rate was last written.
  • Rates are indicative. They are published for reference and analytics, not for settlement.

What each field contains

source classifies where the rate came from. ecb_daily means the European Central Bank reference fix, published once per business day around 16:00 CET. live means live market data that updates approximately every 60 seconds through the trading week.

market_session describes the state of the interbank trading week. It is open during the trading week, weekend from the Friday 17:00 New York close until Sunday 17:00 New York, or interbank_closed for a known non-weekend closure. It does not name Sydney, Tokyo, London, or New York sessions.

ValueWhat it meansWhen it moves
source: liveIndicative spot rateIntraday (~60s), trading week
source: ecb_dailyECB official reference fixOnce per business day, ~16:00 CET
source: market_dailyStored close, no ECB fixDaily market feed
market_session: openAn active trading session is runningChanges as sessions open and close
market_session: weekendSaturday or Sunday (interbank closed)Reference rates carry Friday's fix; live feed not updating
market_session: interbank_closedKnown non-weekend market closureSet when a closure is detected

Reading both fields together

Neither field alone gives you the full picture. A rate with source: live and market_session: weekend means the interbank market is closed and the live field is carrying its last intraday rate from the trading week, not a fresh weekend quote. A rate with source: ecb_daily and market_session: weekend means you have a reference fix that has not moved since Friday.

The example below reads both fields and logs a freshness decision. It calls /v1/latest/USD and checks whether the rate is from the live source before using it in a downstream calculation:

python · reading source and market_session
import requestsAPI = "https://api.exchangerate.dev/v1"KEY = "exr_live_..."resp = requests.get(    f"{API}/latest/USD",    headers={"Authorization": f"Bearer {KEY}"},    timeout=10,)resp.raise_for_status()data = resp.json()source = data["source"]           # e.g. "ecb_daily"session = data["market_session"]  # e.g. "open"updated = data["data_updated_at"] # e.g. "2026-06-19T15:05:12Z"if source == "live":    print(f"Live rate, session: {session}, updated: {updated}")    eur = data["rates"]["EUR"]    # proceed with calculationelif source == "ecb_daily":    print(f"Reference fix, updated: {updated}, session: {session}")    # decide whether to proceed or waitelif source == "market_daily":    print(f"Daily market close, updated: {updated}")
data_updated_at vs timestamp

data_updated_at is when the underlying rate was last written. timestamp is when the response was built. For freshness decisions, read data_updated_at: it tells you the age of the rate itself, not the age of the HTTP response.

Enforcing live-only data in your client

The API does not accept a source=live query filter. If your pipeline requires live spot, request only the symbols you need and reject any response whose per-currency sources value is not live. This keeps the freshness policy in your application and makes a daily-reference fallback explicit.

python · reject a non-live response
resp = requests.get(    f"{API}/latest/USD",    headers={"Authorization": f"Bearer {KEY}"},    params={"symbols": "EUR"},    timeout=10,)resp.raise_for_status()data = resp.json()if data["sources"]["EUR"] != "live":    raise RuntimeError(        f"Live EUR unavailable; received {data['sources']['EUR']}"    )eur = data["rates"]["EUR"]print(eur, data["data_updated_at"], data["market_session"])

For a multi-symbol request, use the sources map rather than the top-level source: the top-level value reports the least-fresh class anywhere in the response. A single daily-reference currency can therefore make a mixed basket report ecb_daily even when the other symbols are live.

Weekend behavior by source

On weekends, the source field separates two situations. source: ecb_daily with market_session: weekend means the ECB has not published since Friday, so the rate carries Friday's fix. For source: live with market_session: weekend, the interbank market is closed, the last intraday rate from the trading week is carried.

A weekend live response and a weekend ECB fix are both labeled weekend. On Monday, the live source resumes intraday updates; the ECB fix publishes at ~16:00 CET.

The notice field

Every response also carries a notice field. For live data it reads: "Indicative rates, not for settlement." For reference-rate data it adds attribution to the ECB. The notice is machine-readable so you can surface it to your own users if you display rates in a UI.

Indicative only

All rates are published for reference, analytics, and display. They are not a dealing quote and must not be used to settle a transaction. The notice field on every response states this explicitly.

Questions

What are the possible values for the source field?

The source field returns "live" (indicative spot), "ecb_daily" (ECB fix), or "market_daily" (stored daily market-feed close for currencies without an ECB fix).

What does market_session tell me, and how is it different from source?

market_session describes the state of the interbank trading week: "open", "weekend", or "interbank_closed" for a known non-weekend closure. source describes the data class. A rate can have source: live and market_session: weekend simultaneously, meaning the live field is carrying its last known intraday rate while the interbank market is closed.

How can I make my pipeline accept only live rates?

Request only the symbols you need, read the per-currency sources map, and reject the response client-side unless the required symbol is labeled "live". The API does not expose a source=live query filter.

What is data_updated_at and when should I use it instead of timestamp?

data_updated_at is when the underlying rate was last written to the data store. timestamp is when the HTTP response was built. To decide whether a rate is recent enough to act on, read data_updated_at. The gap between the two can be significant if the rate has not moved recently.

Keep reading

Start with a free API key

5,000 requests a month on the free plan. No credit card.

Get a free key