Prices: Cardmarket and TCGplayer
Every card carries a European quote and a North American one, in their native currencies. This page covers how to pick between them and how to read what each marketplace reports.
Two markets, one card
Trading cards do not have a price. They have a price in a market. A Pokémon card that settles at $80 on TCGplayer can sit at €55 on Cardmarket, and the gap is not a conversion artefact — European print runs, distribution and demand genuinely differ from American ones. An API that gives you one number and calls it “the price” is quietly wrong for half the world.
So every card in TCGGraph carries at least two quotes: tcgplayer in USD for North America, and cardmarket in EUR for Europe. Neither is converted from the other. Both are the marketplace’s own numbers, in the marketplace’s own currency.
{
"prices": [
{
"source": "tcgplayer",
"region": "NA",
"finish": "holofoil",
"condition": "NM",
"currency": "USD",
"market": 2380.34,
"low": 1805,
"high": 6000
},
{
"source": "cardmarket",
"region": "EU",
"finish": "holofoil",
"condition": "NM",
"currency": "EUR",
"market": 1832.38,
"low": 1282.38,
"high": 2617.08,
"trend": 1832.38,
"avg1": 1784.13,
"avg7": 1797.50,
"avg30": 1867.76,
"sellers": 38
}
]
}Choosing a source
Every card always returns every quote it has, so a plain request needs no extra parameters. What the source parameter changes is which quote filtering and sorting run against. Price bounds are read in that source’s currency, so source=cardmarket&minPrice=50 means €50, not $50.
# Sort and filter on the European market
GET /v1/cards?game=pokemon&source=cardmarket&minPrice=50&sort=-price
# region=EU is the same thing, without naming a vendor
GET /v1/cards?game=pokemon®ion=EU&minPrice=50&sort=-priceThe response echoes the decision back as meta.priceSource, which is worth asserting on in tests. Getting a USD sort when you meant a EUR one is the kind of bug that surfaces as a mildly wrong list rather than an error.
{
cards(
filter: { game: POKEMON, source: CARDMARKET, minPrice: 50 }
sort: PRICE_DESC
limit: 20
) {
pageInfo { totalCount priceSource }
nodes {
name
prices {
source
currency
market
trend
avg7
avg30
sellers
}
}
}
}What Cardmarket reports
Cardmarket exposes more of its own statistics than TCGplayer does, and they are the fields European sellers actually price against. We serve them under stable names rather than passing the marketplace’s vocabulary through unchanged.
| Cardmarket | TCGGraph | Notes |
|---|---|---|
| trend | trend | Cardmarket's own trend price. We also copy it to market. |
| avg | avg30 | Their all-time average is not comparable across reprints; we serve the 30-day window instead. |
| avg1 | avg1 | Mean of yesterday's sales. |
| avg7 | avg7 | Mean of the last seven days. |
| avg30 | avg30 | Mean of the last thirty days. |
| low | low | Cheapest live article in any condition. |
| lowFoil | low | Served on the foil finish row rather than as a separate field. |
| countArticles | sellers | How many live listings the quote is drawn from. |
| idProduct | externalIds.cardmarketId | Kept so you can deep-link to the product page. |
trend is the one to reach for when repricing. It is Cardmarket’s own smoothed estimate and it is what sellers on the platform anchor to, so a listing generated from avg30 will look mispriced next to the competition even when it is a defensible number. Use avg1 and avg7 to detect movement, not to set a price.
sellers is the depth behind the quote. A trend price drawn from four live articles is a rumour; the same price drawn from two hundred is a market. Gate any automated repricing on it.
Condition ladders do not line up
The two marketplaces grade differently, and they do not use the same number of rungs. Cardmarket runs seven grades from Mint down to Poor; TCGplayer runs five. We keep each marketplace’s own grade on its own quote rather than inventing a shared scale that would misrepresent both.
| TCGplayer | Closest Cardmarket | Notes |
|---|---|---|
| NM — Near Mint | NM | The default both marketplaces quote. |
| LP — Lightly Played | EX | Cardmarket's Excellent is the closest grade. |
| MP — Moderately Played | GD | Good. |
| HP — Heavily Played | LP | Light Played, despite the initials. |
| DMG — Damaged | PL / PO | Played or Poor, depending on the listing. |
The full Cardmarket ladder is MT (Mint), NM (Near Mint), EX (Excellent), GD (Good), LP (Light Played), PL (Played), PO (Poor). Note that LP means Lightly Played on TCGplayer and Light Played on Cardmarket, but they sit at different points on their respective ladders — TCGplayer’s is second from the top, Cardmarket’s is fifth. Mapping them onto each other by string equality is the single most common mistake in this area.
Reading the spread
Because both quotes are native, the difference between them is real information rather than rounding. Cross-border sellers use it to decide which market to list in; collectors use it to decide which market to buy from.
type Quote = { source: string; currency: string; market: number };
const EUR_PER_USD = 0.92;
/** Positive means the card is dearer in Europe than in the States. */
function spread(prices: Quote[]) {
const us = prices.find((p) => p.source === "tcgplayer")?.market;
const eu = prices.find((p) => p.source === "cardmarket")?.market;
if (us === undefined || eu === undefined) return null;
return ((eu / EUR_PER_USD - us) / us) * 100;
}Convert only at the point of display, and only with a rate you control. We do not fold a conversion into the stored data, because a price that silently moves when the currency market does is impossible to reconcile against a sale that already happened.
Finishes and languages
- Cardmarket treats a foil as a separate product with its own listings, so foil and nonfoil arrive as separate rows on
prices, distinguished byfinish. - European printings exist in English, German, French, Italian, Spanish and Portuguese, and they do not trade at the same price. Non-English printings resolve to their own card records rather than being collapsed into the English one.
- Sealed product is not priced here. These endpoints cover singles; sealed has a different shape and a different set of buyers.
Freshness
Both sources are refreshed on the same schedule and stamped with updatedAt, so you never have to work out which half of a card’s pricing is stale. Daily closes are kept for both markets, which means you can chart a European price series without having collected it yourself. See the REST reference for the history endpoint, or the Cardmarket overview for what the European coverage includes game by game.