Docs / Probability surface

Probability surface

The market-implied probability surface for gold and silver: strike-aligned curves from GLD/SLV options, Kalshi, and Polymarket, jointly. Product overview at /surface.

PRO TIER+XAU + XAG60s CADENCE · UTC

The surface

GET/v1/surface/{metal}Bearer · Pro+

One call per horizon, four families in one payload: per-venue legs, gated consensus, the options-vs-PM wedge, and touch markets. metal is xau or xag; optional ?horizon=YYYY-MM-DD selects a bucket from the expiries index. Unknown horizons return 404 unknown_horizon with the live list.

Sample response

{
  "result": "success",
  "metal": "xau",
  "timezone": "UTC",
  "as_of": "2026-07-06T14:30:00Z",
  "served_at": "2026-07-06T14:31:12Z",
  "snapshot_age_seconds": 72,
  "max_staleness_seconds": 180,
  "methodology": "last_trade@1",
  "horizon": {
    "target": "2026-07-10",
    "alignment": "tight",
    "max_span_hours": 24,
    "venues_live": ["options", "kalshi"],
    "venues_missing": [
      {"venue": "polymarket", "reason": "no_market_at_horizon"}]
  },
  "reference_spot": {
    "usd": "4123.50", "source": "pyth_xauusd",
    "tradeable_book": false
  },
  "legs": [
    {"venue": "options", "underlying": "GLD", "expiry": "2026-07-10",
     "trading_day": "2026-07-06", "state": "live", "market_open": true,
     "semantics": "terminal_above", "settlement_ref": "gld_nav",
     "measure": "risk_neutral",
     "points": [
       {"threshold_usd": "4100", "prob_above": "0.61",
        "last_trade_age_seconds": 41},
       {"threshold_usd": "4200", "prob_above": "0.34",
        "last_trade_age_seconds": 187}]},
    {"venue": "kalshi", "series": "KXGOLDW",
     "close_time": "2026-07-10T20:00:00Z",
     "trading_day": "2026-07-06", "state": "live",
     "semantics": "terminal_above", "settlement_ref": "kalshi_index",
     "measure": "real_world", "quote_scale": "probability_0_1",
     "points": [
       {"threshold_usd": "4100", "prob_above": "0.63",
        "yes_bid": "0.61", "yes_ask": "0.65",
        "bid_size": "1250", "ask_size": "900"}]}
  ],
  "consensus": [
    {"threshold_usd": "4100", "prob_above": "0.62", "venues": 2,
     "max_divergence": "0.02",
     "measures": ["risk_neutral", "real_world"],
     "settlement_refs": ["gld_nav", "kalshi_index"]}
  ],
  "wedge": {
    "available": true,
    "options_market_open": true,
    "points": [{"threshold_usd": "4100", "options_minus_pm": "-0.02"}]
  },
  "touch": []
}

Honesty fields

served_at and snapshot_age_seconds make the stacked 60-second caches measurable per request, plus a standard Age header. reference_spot is labeled tradeable_book: false: there is no real spot bid/ask, from us or anyone. Prediction-market quotes carry quote_scale so a 61-cent contract bid is never mistaken for a gold-price bid. Legs that settle mid-session flip to state: "settled" and are served from a grace snapshot, never silently vanished. Silver has no Polymarket leg, so XAG never has a wedge; the response says available: false, reason: "no_pm_leg".

Horizon index

GET/v1/surface/{metal}/expiriesBearer · Pro+

The front door for "what dates can I ask about?". Every servable target-date bucket, its venues, and its alignment grade. default: true marks the bucket the surface serves with no horizon parameter.

Sample response

{
  "result": "success",
  "metal": "xau",
  "timezone": "UTC",
  "as_of": "2026-07-06T14:30:00Z",
  "horizons": [
    {"target": "2026-07-07", "alignment": "tight",
     "venues": ["options", "kalshi"], "default": false},
    {"target": "2026-07-10", "alignment": "tight",
     "venues": ["options", "kalshi"], "default": true},
    {"target": "2026-12-31", "alignment": "loose", "max_span_days": 13,
     "venues": ["options", "polymarket"],
     "note": "options expire 2026-12-18; polymarket settles 2026-12-31 on cme_gc"}
  ]
}

Arbitrage signals

GET/v1/signals/arbitrage?metal=xauBearer · Pro+

Cross-venue executable-edge detection swept across every live horizon. Populated rarely; the empty array below is the honest, normal case. Our own published research found zero executable gold arb across a full trading day, and the endpoint reflects that reality instead of manufacturing signals.

Sample response

{
  "result": "success",
  "metal": "xau",
  "signals": []
}

MCP tool + WebSocket channel

The get_surface(metal, horizon?) MCP tool returns the same shape as the surface endpoint, gated identically. On Realtime Pro, the surface:{metal} WebSocket channel pushes the default-horizon snapshot on each engine recompute; see the stream reference.

FAQ

How do I pick a horizon?
Call /v1/surface/{metal}/expiries first. It lists every servable target-date bucket, which venues cover it, and how tightly they align. Then pass ?horizon=YYYY-MM-DD to /v1/surface/{metal}. With no horizon parameter you get the nearest bucket where at least two venues are live.
Why is consensus sometimes missing?
Consensus requires tight settlement alignment (venues settling within the same 24-hour window) and identical market semantics. When venues settle days apart the legs are shown side by side and consensus is refused, because averaging markets that resolve on different days would be fiction.
What does methodology last_trade@1 mean?
The options feed carries trades, not quotes, so probability estimates come from recency-weighted last trades via finite differences, with each point's trade age disclosed. The methodology string is versioned so a future upgrade (for example to mid-quotes from a quote-bearing source) is visible in the payload.
Which tier do I need?
Pro or higher. Physical, Free, and grandfathered Basic keys receive 403 plan_gated. The MCP tool get_surface follows the same gate; Realtime Pro adds the surface:{metal} WebSocket channel.