Methodology
How every score on this site is computed.
Open methodology is the whole product. If we publish a number we publish the formula. If we don't have the data we don't pretend.
Last refresh: May 19, 2026 · Catalog: 15,458 pops
Rarity Index — 0 to 100
Deterministic score derived from three real fields on every pop. Same inputs always produce the same output. No randomness, no external data, no time decay.
Honest limitations: Our source dataset has incomplete vault flags. Only 8 pops are currently marked vaulted, which is far below the true number. As the data layer improves, more pops will rise into the higher bands. The formula stays fixed; the inputs sharpen.
Category Heat — 0 to 100
Heat measures how much weight a category carries in the catalog. Three real signals, all from the pops table:
Why log? So a 100-pop category isn't crushed by a 3,000-pop one, but the giant categories still register as bigger. Why size + exclusive + vault? Because those are the only three real demand proxies we have until sales data arrives.
Honest limitations: The vault component is suppressed right now because vault flags are sparse in the source dataset. Heat scores currently cluster between 30 and 50. When the vault data improves, the spread widens.
Trend Score — 0 to 100
A momentum proxy combining the two above with a recency component. Until sales data arrives this is the closest we get to "is this pop on a run."
Honest limitations: Only 0% of pops carry a confirmed release year in our current dataset. For the rest, recency contributes a neutral 50. Trend Score still works but the recency lever sits idle.
Prices — sourced, dated, labeled
When a card or pop has a market price displayed, here's exactly where it came from and what it means.
price_snapshots tableWhat "market price" actually is. TCGplayer's market price is a weighted average of recent listing prices, not a record of final sales. It moves with current asking prices — quickly when supply or demand shifts, slowly when the market is quiet. For most use cases ("is this card going up?", "how much do I list mine for?") it's the right signal.
Honest limitations: listing prices can lag — or front-run — actual completed sales, especially during hype spikes. eBay Marketplace Insights (final sale prices) is a separate data feed we're working to add as a complement. Until then we deliberately call this "market price", not "sold price."
What we do not publish yet
The following metrics are easy to fake and easy to spot. We will not ship them until the underlying data is real.
Final sale prices (sold listings)
TCGplayer gives us listing-market prices — what people are asking right now. eBay Marketplace Insights gives final sale prices and is on our partner queue. Until then we label what we show as "market price," not "sold price."
Value projection ($1m / $3m / $6m)
Goes live once we have ~90 days of price history per product. We already capture daily snapshots; the historical archive replay (Feb 2024 → today) is queued to backfill 15 months in one batch.
Undervalued / overvalued alerts at scale
The analytics engine is built (see backend/analytics/price_signals.py). It activates per product once that product has a 30-day window of snapshots. Activates progressively as the catalog price coverage grows.
Portfolio P&L
Needs per-user collection tracking + user-submitted cost basis. Not a priority until the marketplace half of the product is live.
Data sources
- Catalog seed: kennymkchan/funko-pop-data on GitHub — a community-maintained dataset of 15,458 pops. Cleaned and enriched during ingestion.
- Enrichment: regex-based extraction of variant (Chase, Glow, Prototype…), exclusive (SDCC, Target, Hot Topic…), and category from product names and taxonomy tags.
- Score computation: the formulas above are committed to
backend/analytics/and re-runnable viascripts/backfill_rarity.pyandscripts/cache_category_heat.py.