Pass-through, per source
Most metals APIs collect prices from several feeds, run a weighted median, throw away the inputs, and hand you one number. The blend is opaque. When prices disagree across exchanges (which happens daily around rollover, around settlement, around every market close), you can't tell whether the API's number reflects reality or the API's internal weighting.
We took the opposite position. The response for any symbol includes every source that contributed, as its own row, with its own timestamp. No hidden blend. No mystery weights. The aggregation logic, source weights, and divergence thresholds are operational choices we tune per release; the per-call proof of which sources fired is what your application sees.
GET /v1/prices?symbol=XAU-USD-SPOT
{
"symbol": "XAU",
"price": "4803.94",
"is_stale": false,
"computed_at": "2026-05-01T02:34:02Z",
"sources": [
{ "source": "oracle.xau_usd", "price": "4803.94", "timestamp": "..." },
{ "source": "spot_reference.usd", "price": "4803.42", "timestamp": "..." },
{ "source": "futures.gc_f", "price": "4802.80", "timestamp": "..." }
]
}Sources we ingest
Source categories at each tier. Per-call proof of which feeds fired for any given price lives in your /v1/prices response.
| Source | Used for | Tier |
|---|---|---|
| Live spot oracle | Real-time gold + silver spot | Physical, Pro |
| Continuous spot reference | Industry-standard spot, 13 currencies | Free, all tiers |
| Futures settlement reference (gold + silver + copper) | Daily settlement, futures continuity, settlement-vs-spot differentials | Physical (gold), Pro (silver, copper) |
| ECB reference rates | FX triangulation for non-USD prices | All tiers |
| Tokenized gold (PAXG, XAUT) | 24/7 informational signal during TradFi closure | Physical, Pro (informational only) |
Source identifiers, license rationale, refresh cadences, and upstream endpoint details are documented internally and evolve with each release. If you need this depth for legal evaluation, email hello@goldprice.dev with your use case and we'll respond.
Non-USD prices on the currency pages convert from live interbank FX via exchangerate.dev, our sibling currency API, refreshed roughly every 60 seconds, with ECB reference rates as fallback.
Cross-source divergence
With every primary source visible, the next question is obvious: how much do they actually disagree? Every response on a multi-source row carries a top-level divergence_bps integer — the spread between non-stale primary sources, in basis points relative to the mean.
Single-source rows omit the field rather than report a misleading zero. Tokenized PAXG / XAUT are tagged informational and feed a separate divergence_flag when they trade meaningfully off spot. The endpoint GET /v1/prices/divergence lists every symbol whose current spread exceeds a configurable threshold and is available on every tier — the spread itself is the trust signal.
On the LBMA fix
Staleness, per source
Because we pass every source through, staleness is per-source. The response always emits a top-level is_stale that flips true when the primary source falls behind its expected refresh window. Add ?include=sources and each row in sources[] carries its own source_timestamp so you can make your own freshness call on any source you prefer.
A second field, value_stale, is available via ?include=stats (auth required — anonymous callers never receive it) and appears on rows whose upstream feed has stopped moving while we keep fetching it (a frozen partner feed, a daily-fix syndication being served as live, etc.). The two failure modes are distinct: is_stale means our scraper hasn't written; value_stale means upstream has stopped publishing actual change. Both surface honestly.
Forward view: futures curve
/data/gold renders the market-implied forward price path on one chart, served by /v1/forward-view/{asset}. The breakdown below covers the math, source, and refresh cadence.
Futures curve
The next 5 forward gold contracts. Settle prices at this tier are ~15 minutes delayed via our primary delayed-feed series with a secondary fallback. We are not a licensed real-time market data redistributor; that licensed feed is deferred until $5K MRR. The dashed line connects the 5 settle points; gaps appear when both our primary and fallback feeds fail for a contract. Open interest and volume are best-effort null at this tier and are not surfaced in the response.
Data freshness
Futures settle prices fire weekdays at 20:30 UTC: a single year-round schedule, +2h post-settle in EDT, +1h in EST, DST-stable.
What we don't do
- LBMA fix. See above.
- Tick-level L2 order books. We publish prices, not depth. If you need depth, license it from an exchange or LSEG.
- Sub-second latency guarantees.We don't publish a numerical latency SLA.
- Continuous copper spot. We ship copper futures settlement only. Front-month rotation if customer demand warrants the complexity.
- Silent blending. The whole point of this page.
Methodology changelog
| Version | Change |
|---|---|
| v3.0 | Tightened public methodology to source categories + divergence + staleness concepts. Per-source identifiers, refresh cadences, and aggregation specifics moved out of the public page. |
| v2.1 | Metals pivot. Added silver spot via XAG oracle and copper futures settlement. |
| v2.0 | Pivot to pass-through-per-source. Killed blended-median aggregation. Added live spot oracle, ECB FX, tokenized gold (informational). |
| v1.0 | Initial multi-source aggregation. Tier-1 weighted median (superseded). |
Spot something off, or have a source we should consider? Email hello@goldprice.dev. We publish material corrections here.
Questions about the API? Read the docs.