Skip to content

M1, M2, and M3 valuation engines ​

Date: 2026-09-14.
Environment: staging.
Rule version: pdf-2026-09-14.

M1 values a raw card, M2 a sealed product, and M3 a graded card. Identity and evidence never cross engine boundaries. A missing value remains null, never 0.

Sources in the current environment ​

Snag does not have open Cardmarket or eBay API access. The backend therefore makes no live call to either service and never turns a missing source into fabricated data.

SourceStaging use
CardTraderstructured alternative NM anchor for recent M1; always labelled cardtrader
GCCexact successful sales for M2/M3
eBay/Cardmarketobservations only through an authorised, reviewed feed or import
Personal valuelocal app fallback when no qualified quote can be produced

Observations live in valuation_evidence, decisions in valuation_decisions, and the M1 ladder in m1_prices/m1_refusals.

M1 — raw cards ​

The document covers Poor, Played, Light Played, Good, Excellent, and Near Mint. Mint is outside its scope.

Recent blocks ​

For Mega Evolution, Scarlet & Violet, and Sword & Shield, the engine starts with the first same-language NM price and applies:

ConditionFactor
Near Mint100%
Excellent85%
Good60%
Played40%
Poor20%

The PDF defines no Light Played factor. Snag refuses to invent one and offers a personal value instead. On staging, CardTrader can technically replace the unavailable Cardmarket anchor; the alternative source remains visible in the response.

Other blocks ​

M1 uses only successful eBay sales in the exact condition. It selects the first non-empty window—30 days, 3 months, 6 months, then 12 months—and averages it. Without proven eBay coverage or without a sale in 12 months, no quote is published and a personal value is offered.

GET /cards/:id/m1-prices?language=&variant= returns all six conditions in one request. The app switches values immediately when the user changes condition.

M2 — sealed products ​

Exact identity includes product, language, format/SKU, variant, and currency.

  1. Take the first same-language Cardmarket price.
  2. Add all successful eBay/GCC sales from the first non-empty window: 30 days, 3 months, 6 months, 12 months.
  3. Give the anchor the same weight as one sale.
  4. Calculate the mean, remove values outside ±30%, and recalculate once.
  5. Without a sale in 12 months or without a qualified anchor, publish no quote.

GCC can supply sales, but a GCC-only mean is not presented as a PDF-compliant M2 quote. Until an authorised Cardmarket anchor is available, the frontend shows the unavailable state and allows a personal value.

M3 — graded cards ​

Card, language, variant, grading company, grade, and qualifier must match exactly. M3 never extrapolates from raw and never converts grades between graders.

  • Clear market: at least three exact eBay/GCC sales in the last three calendar months; mean, remove values outside ±30%, recalculate.
  • Unclear market: at least one exact sale in 12 months; the lowest exact, fixed, active, plausible Cardmarket/eBay listing replaces the latest sale only when it is cheaper.
  • Doubtful market: no exact sale in 12 months; no quote, personal value allowed.

When eBay/Cardmarket listings are unavailable, the latest exact sale remains the best evidence and the decision carries listings-unavailable. A GCC listing is not silently substituted.

Frontend contract ​

GET /valuations serves one exact M2/M3 market and GET /valuations/batch supplies collection totals without N+1 calls. Quotes older than 48 hours are not served. The frontend shows source, sample size, and freshness, and offers a personal M1/M2/M3 value whenever the engine refuses to price.

This delivery targets staging. It is not a merge or deployment of main to production.