Reference/API concepts

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.

ERexchangerate.dev·Jun 19, 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.

Key points
source has three values: live (aggregated spot, updates intraday through the trading week), ecb_daily (European Central Bank reference fix, once per business day), or fred_daily (Federal Reserve daily series).
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. fred_daily means the Federal Reserve daily series. live means aggregated spot 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: liveAggregated spot consensusIntraday (~60s), trading week
source: ecb_dailyECB official reference fixOnce per business day, ~16:00 CET
source: fred_dailyFederal Reserve daily seriesOnce per business day
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 consensus 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_sessioncopy
import requests

API = "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 calculation
elif source == "ecb_daily":
    print(f"Reference fix, updated: {updated}, session: {session}")
    # decide whether to proceed or wait
else:
    print(f"FRED daily series, 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 responsecopy
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 or source: fred_daily with market_session: weekend means the reference institution has not published since Friday, and the rate reflects Friday's fix. For source: live with market_session: weekend, the interbank market is closed — the last intraday consensus 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.
ER
exchangerate.dev
API concepts and integration guides for developers building on FX data.

Keep reading

TutorialHow to get exchange rates in PythonRead BlogWhat ECB-based FX APIs miss between fixesRead GuideIndicative vs executable FX ratesRead
More ComparisonsFixer vs exchangerate.devOpen Exchange Rates vs exchangerate.devCurrencylayer vs exchangerate.devCurrencylayer vs ExchangeRate-API
LearnIndicative vs executable FX rates: what a rates API actually gives youECB reference rates, explained
Live RatesEUR/USDGBP/USDUSD/JPY