Pricing is opt-in. It surfaces our own valuation — a market price, a per-condition raw ladder, and graded values that blend our price feed with real recent sales into one trustworthy number, each with a confidence and a trend. It is not a passthrough of a single third-party estimate.
| Where | What you get |
|---|---|
?include=prices on card endpoints | A compact pricing object on every card: market, condition ladder, and reconciled graded headline values. |
| GET …/cards/:id/prices | The full payload for one card — everything above plus an aggregate sold band and last_sold_at per graded value. |
"pricing": {
"currency": "USD",
"market": 4435.20, // ungraded market price
"market_updated_at": "2026-07-16T...Z",
"is_stale": false, // true if the market price is overdue for a refresh
"trend_7d": { "direction": "up", "percent": 3.5 },
"conditions": [ // raw ladder for the card's variant
{ "condition": "NM", "price": 4435.20 },
{ "condition": "LP", "price": 3100 }
],
"graded": [
{ "company": "PSA", "grade": "10", "value": 947.97,
"low": 780, "high": 1200, "confidence": "high",
"value_kind": "sold", "sold_count": 21,
"trend": { "direction": "up", "percent": 12.0 },
"last_sold_at": "2026-07-10T...Z", // /prices endpoint only
"band": { "median": 900, "recent_median": 947,
"p10": 780, "p90": 1200, "count": 21 } } // /prices endpoint only
]
} market is the ungraded (raw) market price in USD, or null when we don’t have one. is_stale flags a price overdue for a refresh; trend_7d is the 7-day move.conditions[] is the raw price ladder — NM, LP, MP, HP, DMG — for the card’s own variant. It’s omitted/empty when we don’t have per-condition data for that card.Each graded entry is one company + grade (e.g. PSA 10). The value is reconciled:
when enough recent sales exist we trust them; with only a few, we blend them with our feed;
with none, we fall back to the feed estimate. value_kind and confidence tell you which happened.
| Field | Meaning |
|---|---|
value | The single reconciled price for this company + grade |
value_kind | `sold` (backed by recent sales), `blended` (feed + a few sales), or `feed` (estimate only) |
confidence | `high` / `med` / `low` — how much sold-comp evidence backs the value |
low / high | Value band (p10 / p90 of comps, or a ±band around the estimate) |
sold_count | Number of recent (≤90d) sold comps backing the value |
trend | `{ direction: up|down|flat, percent }` — sold-momentum (recent vs prior median), manipulation-safe |
last_sold_at | Timestamp of the most recent comp (full /prices endpoint only) |
band | `{ median, recent_median, p10, p90, count }` aggregate sold band (full /prices endpoint only) |
The trend compares the recent (0–30d) median against the prior (31–90d) median,
needs a minimum sample in both windows, and is clamped — so a single outlier sale can’t swing
it. Bands use p10/p90, never raw min/max.
Pricing returns our computed numbers and aggregate bands (counts, medians, ranges). It does not return individual sold listings, marketplace-by-marketplace breakdowns, or per-source provenance. Those stay internal.