Skip to content

Time semantics

There are three timestamps in play, and they answer three different questions. Use the right one — they are not interchangeable.

receivedAt — local clock, on every event payload

Section titled “receivedAt — local clock, on every event payload”

Every SDK event payload carries receivedAt: number (ms since epoch, from Date.now()). It records the moment the SDK received the message, on your machine’s clock.

client.on('odds:changed', ({ quote, receivedAt }) => {
const sdkLatencyMs = Date.now() - receivedAt
// very small unless you queued the callback
})

Use it for:

  • End-to-end latency analysis (gateway → SDK).
  • Stale-data detection (“alert if no odds:changed for selection X in the last 10 seconds”).
  • Ordering events from the same connection, since they’re monotonic per-client.

Don’t use it to compare against another machine’s clock — it’s local.

Every Quote has a timestamp: number. It’s set by whichever party constructed the Quote — usually the gateway, occasionally the SDK during hydration.

It approximates how fresh the quote is — but it is not the bookmaker’s authoritative emit time. The gateway doesn’t get that from upstream; it stamps the Quote when it processes the update.

Use it for:

  • Rough freshness checks (“this quote is more than 30s old, treat as stale”).
  • Cross-bookmaker comparisons when you need a single notion of “around when”.

Don’t use it for:

  • Sub-second arbitrage windows — the gateway’s clock and the bookmaker’s clock are not synchronised.
  • Latency budgetsreceivedAt - quote.timestamp includes whatever staleness was already in the gateway’s view.

Same semantics as quote.timestamp, but for the full order book snapshot. Set when the gateway constructs the OrderBook.

The scheduled match start time, as a Luxon DateTime. Optional — some bookmakers don’t provide it. Use it for “this match starts in N minutes” displays. Not related to update freshness.

You want to know…Use…
When the SDK saw this updatereceivedAt
Roughly how fresh this price isquote.timestamp
When the match startssportEvent.startDate
End-to-end SDK latencyDate.now() - receivedAt
Whether the connection is downclient.snapshot().stale