Freshness

A 3-hour-old stock price presented confidently is worse than no data at all. Freshness rules ensure stale data is handled appropriately.

The freshness object

Every contract includes a freshness section with two key timestamps:

{
  "freshness": {
    "generated_at": "2026-02-16T12:00:00Z",
    "valid_until": "2026-02-16T15:00:00Z",
    "stale_behavior": "warn",
    "stale_warning": "This data was generated at {generated_at} and may not reflect current values.",
    "expired_behavior": "suppress"
  }
}

Three states

The runtime computes a freshness status based on the current time:

StatusConditionDescription
validWithin the first 80% of the validity windowData is fresh. Present normally.
stalePast 80% but before valid_untilData is aging. The contract's stale_behavior activates.
expiredPast valid_untilData is no longer valid. The expired_behavior takes over.

Stale behaviors

When data enters the stale window, the provider can specify one of four actions:

  • warn — Present the data but include the stale_warning text. The AI must tell the user the data may be outdated. This is the most common choice.
  • suppress — Do not present the data at all. Used for time-critical data like live stock prices.
  • degrade — Present the data with reduced precision. For example, show "approximately $420" instead of "$423.17".
  • refresh — Attempt to fetch fresh data from refresh_endpoint before presenting. Falls back to the expired behavior if refresh fails.

Expired behaviors

Once past valid_until, the options are more restrictive:

  • suppress — The data is silently dropped. The AI acts as if it was never received. This is the safest default.
  • warn — Present with a prominent warning that the data is expired.
  • degrade — Show only non-time-sensitive fields (e.g., fund name, category) while hiding prices and returns.

Cache policy

The optional cache_policy field provides HTTP-style caching guidance (e.g., "max-age=3600"). AI runtimes that cache responses can use this to know when to refetch.

Why 80%?

The stale threshold at 80% of the validity window provides a buffer zone. For a 3-hour validity window, the data enters "stale" at 2 hours 24 minutes, giving the runtime time to warn users or attempt a refresh before full expiration.