Quickstart
A key, one request, and what comes back. Every response on this page is what the live API answered.
1. Get a key
Pick a plan, then create a key under API keys. It is shown once. Every plan reaches every game and the whole catalog; plans differ in credits, limits and price watches. Keep it in an environment variable, never in browser code (see Authentication).
export TCGGRAPH_KEY="tcg_live_..."2. Make a request
Every REST endpoint is under https://api.tcggraph.com/v1 with the key as a bearer token. This one finds Charizard ex in the 151 set:
Search Pokémon cards by name
curl "https://api.tcggraph.com/v1/cards?game=pokemon&name=charizard%20ex&set=sv3pt5&limit=2" \
-H "Authorization: Bearer $TCGGRAPH_API_KEY"const response = await fetch("https://api.tcggraph.com/v1/cards?game=pokemon&name=charizard%20ex&set=sv3pt5&limit=2", {
headers: {
Authorization: `Bearer ${process.env.TCGGRAPH_API_KEY}`,
},
});
const body = await response.json();
if (!response.ok) throw new Error(`${body.error.code}: ${body.error.message}`);import os
import requests
response = requests.get(
"https://api.tcggraph.com/v1/cards",
params={
"game": "pokemon",
"name": "charizard ex",
"set": "sv3pt5",
"limit": "2",
},
headers={"Authorization": f"Bearer {os.environ['TCGGRAPH_API_KEY']}"},
)
body = response.json()
response.raise_for_status(){
"data": [
{
"id": "pkm_sv3pt5_183",
"game": "pokemon",
"name": "Charizard ex",
"language": "en",
"printedName": null,
"baseCardId": null,
"englishId": null,
"sameArtwork": [
"pkm_ja_sv2a_185"
],
"pricesFrom": "own",
"pricesTwin": null,
"set": {
"code": "sv3pt5",
"name": "151",
"language": "en",
"releasedAt": "2023-09-22"
},
"collectorNumber": "183",
"rarity": "Ultra Rare",
"artist": "PLANETA Mochizuki",
"text": null,
"images": {
"small": "https://cards.tcggraph.io/sv/pkm_sv3pt5_183/small.webp",
"normal": "https://cards.tcggraph.io/sv/pkm_sv3pt5_183/normal.webp",
"large": "https://cards.tcggraph.io/sv/pkm_sv3pt5_183/large.webp"
},
"imageFrom": "own",
"hashes": {
"phash": "cd5a31a4c69c4f53",
"phashColor": "dd5bb0b0a60f4b43cd5231ccc6d82f33edb1114cced0a733"
},
"prices": [
{
"source": "cardmarket",
"region": "EU",
"listType": "retail",
"finish": "foil",
"currency": "EUR",
"market": 38.47,
"low": 22,
"trend": 38.47,
"avg1": 40.33,
"avg7": 42.24,
"avg30": 43.11,
"basis": "product-page",
"updatedAt": "2026-10-05T08:05:39.971Z"
},
{
"source": "tcgplayer",
"region": "NA",
"listType": "retail",
"finish": "foil",
"currency": "USD",
"market": 39.44,
"low": 33.57,
"trend": null,
"avg1": null,
"avg7": null,
"avg30": null,
"basis": null,
"updatedAt": "2026-10-04T22:00:05.544Z"
}
],
"gradedPrices": [
{
"grader": "raw",
"grade": "ungraded",
"currency": "USD",
"price": 40.49,
"salesVolume": 606,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "any",
"grade": "7",
"currency": "USD",
"price": 28.75,
"salesVolume": 606,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "any",
"grade": "8",
"currency": "USD",
"price": 35.66,
"salesVolume": 606,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "any",
"grade": "9",
"currency": "USD",
"price": 50,
"salesVolume": 606,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "any",
"grade": "9.5",
"currency": "USD",
"price": 69.99,
"salesVolume": 606,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "psa",
"grade": "10",
"currency": "USD",
"price": 205,
"salesVolume": 606,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "bgs",
"grade": "10",
"currency": "USD",
"price": 799,
"salesVolume": 606,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "cgc",
"grade": "10",
"currency": "USD",
"price": 84.84,
"salesVolume": 606,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "sgc",
"grade": "10",
"currency": "USD",
"price": 64.5,
"salesVolume": 606,
"updatedAt": "2026-10-05T09:20:50.686Z"
}
],
"languagePrices": [
{
"source": "cardmarket",
"language": "en",
"finish": "foil",
"currency": "EUR",
"low": 31.9,
"lowNm": 31.9,
"market": 40,
"offers": 21,
"truncated": true,
"truncatedAbove": 40,
"conditions": [
{
"condition": "nm",
"low": 31.9,
"offers": 16
},
{
"condition": "ex",
"low": 36.38,
"offers": 4
},
{
"condition": "gd",
"low": 39.99,
"offers": 1
}
],
"updatedAt": "2026-10-05T08:05:40.080Z"
},
{
"source": "cardmarket",
"language": "fr",
"finish": "foil",
"currency": "EUR",
"low": 53,
"lowNm": 53,
"market": 78.09,
"offers": 50,
"truncated": true,
"truncatedAbove": 89.44,
"conditions": [
{
"condition": "mt",
"low": 75,
"offers": 1
},
{
"condition": "nm",
"low": 53,
"offers": 44
},
{
"condition": "ex",
"low": 55,
"offers": 4
},
{
"condition": "gd",
"low": 60,
"offers": 1
}
],
"updatedAt": "2026-09-30T11:48:02.155Z"
},
{
"source": "cardmarket",
"language": "de",
"finish": "foil",
"currency": "EUR",
"low": 22,
"lowNm": 31.99,
"market": 37.99,
"offers": 28,
"truncated": true,
"truncatedAbove": 40,
"conditions": [
{
"condition": "nm",
"low": 31.99,
"offers": 21
},
{
"condition": "ex",
"low": 32,
"offers": 6
},
{
"condition": "gd",
"low": 22,
"offers": 1
}
],
"updatedAt": "2026-10-05T08:05:40.080Z"
},
{
"source": "cardmarket",
"language": "es",
"finish": "foil",
"currency": "EUR",
"low": 45,
"lowNm": 45,
"market": 65,
"offers": 10,
"truncated": false,
"truncatedAbove": null,
"conditions": [
{
"condition": "nm",
"low": 45,
"offers": 9
},
{
"condition": "ex",
"low": 50,
"offers": 1
}
],
"updatedAt": "2026-09-30T11:47:55.509Z"
},
{
"source": "cardmarket",
"language": "it",
"finish": "foil",
"currency": "EUR",
"low": 38,
"lowNm": null,
"market": 38,
"offers": 1,
"truncated": true,
"truncatedAbove": 40,
"conditions": [
{
"condition": "gd",
"low": 38,
"offers": 1
}
],
"updatedAt": "2026-10-05T08:05:40.080Z"
},
{
"source": "cardmarket",
"language": "pt",
"finish": "foil",
"currency": "EUR",
"low": 100,
"lowNm": 100,
"market": 100,
"offers": 1,
"truncated": false,
"truncatedAbove": null,
"conditions": [
{
"condition": "nm",
"low": 100,
"offers": 1
}
],
"updatedAt": "2026-10-02T12:30:16.437Z"
},
{
"source": "cardmarket",
"language": "ja",
"finish": "foil",
"currency": "EUR",
"low": null,
"lowNm": null,
"market": null,
"offers": 0,
"truncated": false,
"truncatedAbove": null,
"conditions": [],
"updatedAt": "2026-10-02T12:30:15.812Z"
},
{
"source": "cardmarket",
"language": "ko",
"finish": "foil",
"currency": "EUR",
"low": null,
"lowNm": null,
"market": null,
"offers": 0,
"truncated": false,
"truncatedAbove": null,
"conditions": [],
"updatedAt": "2026-10-02T12:30:16.529Z"
}
],
"printings": [
{
"key": "foil",
"label": "Holofoil",
"kind": "surface",
"images": {
"small": "https://cards.tcggraph.io/sv/pkm_sv3pt5_183/small.webp",
"normal": "https://cards.tcggraph.io/sv/pkm_sv3pt5_183/normal.webp",
"large": "https://cards.tcggraph.io/sv/pkm_sv3pt5_183/large.webp"
},
"imageFrom": "card",
"externalIds": {
"cardmarketId": 733778,
"tcgplayerId": 517017
},
"prices": [
{
"source": "cardmarket",
"region": "EU",
"listType": "retail",
"finish": "foil",
"currency": "EUR",
"market": 38.47,
"low": 22,
"trend": 38.47,
"avg1": 40.33,
"avg7": 42.24,
"avg30": 43.11,
"basis": "product-page",
"updatedAt": "2026-10-05T08:05:39.971Z"
},
{
"source": "tcgplayer",
"region": "NA",
"listType": "retail",
"finish": "foil",
"currency": "USD",
"market": 39.44,
"low": 33.57,
"trend": null,
"avg1": null,
"avg7": null,
"avg30": null,
"basis": null,
"updatedAt": "2026-10-04T22:00:05.544Z"
}
],
"cardId": "pkm_sv3pt5_183"
}
],
"priceStatus": {
"cardmarket": "priced",
"tcgplayer": "priced",
"graded": "priced"
},
"legalities": {
"expanded": "legal",
"standard": "legal",
"unlimited": "legal"
},
"gameData": {
"hp": 330,
"types": [
"Fire"
],
"attacks": [
{
"cost": [
"Fire"
],
"name": "Brave Wing",
"text": "If this Pokémon has any damage counters on it, this attack does 100 more damage.",
"damage": "60+",
"convertedEnergyCost": 1
},
{
"cost": [
"Fire",
"Fire",
"Fire",
"Fire"
],
"name": "Explosive Vortex",
"text": "Discard 3 Energy from this Pokémon.",
"damage": "330",
"convertedEnergyCost": 4
}
],
"subtypes": [
"Stage 2",
"ex"
],
"abilities": [],
"supertype": "Pokémon",
"weaknesses": [
{
"type": "Water",
"value": "×2"
}
],
"evolvesFrom": "Charmeleon",
"resistances": [],
"retreatCost": [
"Colorless",
"Colorless"
],
"regulationMark": "G",
"convertedRetreatCost": 2,
"nationalPokedexNumbers": [
6
]
},
"externalIds": {
"cardmarketId": 733778,
"tcgplayerId": 517017
}
},
{
"id": "pkm_sv3pt5_199",
"game": "pokemon",
"name": "Charizard ex",
"language": "en",
"printedName": null,
"baseCardId": null,
"englishId": null,
"sameArtwork": [
"pkm_ja_sv2a_201"
],
"pricesFrom": "own",
"pricesTwin": null,
"set": {
"code": "sv3pt5",
"name": "151",
"language": "en",
"releasedAt": "2023-09-22"
},
"collectorNumber": "199",
"rarity": "Special Illustration Rare",
"artist": "miki kudo",
"text": null,
"images": {
"small": "https://cards.tcggraph.io/sv/pkm_sv3pt5_199/small.webp",
"normal": "https://cards.tcggraph.io/sv/pkm_sv3pt5_199/normal.webp",
"large": "https://cards.tcggraph.io/sv/pkm_sv3pt5_199/large.webp"
},
"imageFrom": "own",
"hashes": {
"phash": "8d8d5a7a9262e566",
"phashColor": "858d5a3a3b72a5668dcd507a92e2e52e8d85705a9f63694e"
},
"prices": [
{
"source": "cardmarket",
"region": "EU",
"listType": "retail",
"finish": "foil",
"currency": "EUR",
"market": 410.24,
"low": 109.98,
"trend": 410.24,
"avg1": 310,
"avg7": 318.36,
"avg30": 381.92,
"basis": "product-page",
"updatedAt": "2026-10-05T11:37:45.105Z"
},
{
"source": "tcgplayer",
"region": "NA",
"listType": "retail",
"finish": "foil",
"currency": "USD",
"market": 342.73,
"low": 297.67,
"trend": null,
"avg1": null,
"avg7": null,
"avg30": null,
"basis": null,
"updatedAt": "2026-10-04T22:00:05.544Z"
}
],
"gradedPrices": [
{
"grader": "raw",
"grade": "ungraded",
"currency": "USD",
"price": 344.32,
"salesVolume": 1910,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "any",
"grade": "7",
"currency": "USD",
"price": 319.61,
"salesVolume": 1910,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "any",
"grade": "8",
"currency": "USD",
"price": 320,
"salesVolume": 1910,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "any",
"grade": "9",
"currency": "USD",
"price": 364.76,
"salesVolume": 1910,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "any",
"grade": "9.5",
"currency": "USD",
"price": 618.13,
"salesVolume": 1910,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "psa",
"grade": "10",
"currency": "USD",
"price": 1375,
"salesVolume": 1910,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "bgs",
"grade": "10",
"currency": "USD",
"price": 6000,
"salesVolume": 1910,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "cgc",
"grade": "10",
"currency": "USD",
"price": 575.22,
"salesVolume": 1910,
"updatedAt": "2026-10-05T09:20:50.686Z"
},
{
"grader": "sgc",
"grade": "10",
"currency": "USD",
"price": 626.19,
"salesVolume": 1910,
"updatedAt": "2026-10-05T09:20:50.686Z"
}
],
"languagePrices": [
{
"source": "cardmarket",
"language": "en",
"finish": "foil",
"currency": "EUR",
"low": 259.99,
"lowNm": null,
"market": 299.98,
"offers": 7,
"truncated": true,
"truncatedAbove": 305,
"conditions": [
{
"condition": "ex",
"low": 290,
"offers": 4
},
{
"condition": "gd",
"low": 285,
"offers": 2
},
{
"condition": "pl",
"low": 259.99,
"offers": 1
}
],
"updatedAt": "2026-10-05T11:37:45.240Z"
},
{
"source": "cardmarket",
"language": "de",
"finish": "foil",
"currency": "EUR",
"low": 109.98,
"lowNm": 289.99,
"market": 300,
"offers": 23,
"truncated": true,
"truncatedAbove": 305,
"conditions": [
{
"condition": "nm",
"low": 289.99,
"offers": 9
},
{
"condition": "ex",
"low": 270,
"offers": 10
},
{
"condition": "gd",
"low": 220,
"offers": 3
},
{
"condition": "po",
"low": 109.98,
"offers": 1
}
],
"updatedAt": "2026-10-05T11:37:45.240Z"
},
{
"source": "cardmarket",
"language": "it",
"finish": "foil",
"currency": "EUR",
"low": 229,
"lowNm": 300,
"market": 299.85,
"offers": 17,
"truncated": true,
"truncatedAbove": 305,
"conditions": [
{
"condition": "mt",
"low": 300,
"offers": 1
},
{
"condition": "nm",
"low": 300,
"offers": 1
},
{
"condition": "ex",
"low": 299,
"offers": 6
},
{
"condition": "gd",
"low": 229,
"offers": 8
},
{
"condition": "pl",
"low": 299,
"offers": 1
}
],
"updatedAt": "2026-10-05T11:37:45.240Z"
},
{
"source": "cardmarket",
"language": "es",
"finish": "foil",
"currency": "EUR",
"low": 330,
"lowNm": 380,
"market": 450,
"offers": 14,
"truncated": false,
"truncatedAbove": null,
"conditions": [
{
"condition": "nm",
"low": 380,
"offers": 11
},
{
"condition": "ex",
"low": 330,
"offers": 3
}
],
"updatedAt": "2026-09-30T08:24:28.751Z"
},
{
"source": "cardmarket",
"language": "fr",
"finish": "foil",
"currency": "EUR",
"low": 285,
"lowNm": null,
"market": 300,
"offers": 3,
"truncated": true,
"truncatedAbove": 305,
"conditions": [
{
"condition": "ex",
"low": 285,
"offers": 3
}
],
"updatedAt": "2026-10-05T11:37:45.240Z"
},
{
"source": "cardmarket",
"language": "ja",
"finish": "foil",
"currency": "EUR",
"low": null,
"lowNm": null,
"market": null,
"offers": 0,
"truncated": false,
"truncatedAbove": null,
"conditions": [],
"updatedAt": "2026-10-03T00:16:48.793Z"
},
{
"source": "cardmarket",
"language": "ko",
"finish": "foil",
"currency": "EUR",
"low": null,
"lowNm": null,
"market": null,
"offers": 0,
"truncated": false,
"truncatedAbove": null,
"conditions": [],
"updatedAt": "2026-10-02T05:10:35.407Z"
},
{
"source": "cardmarket",
"language": "pt",
"finish": "foil",
"currency": "EUR",
"low": null,
"lowNm": null,
"market": null,
"offers": 0,
"truncated": false,
"truncatedAbove": null,
"conditions": [],
"updatedAt": "2026-10-02T05:10:31.980Z"
}
],
"printings": [
{
"key": "foil",
"label": "Holofoil",
"kind": "surface",
"images": {
"small": "https://cards.tcggraph.io/sv/pkm_sv3pt5_199/small.webp",
"normal": "https://cards.tcggraph.io/sv/pkm_sv3pt5_199/normal.webp",
"large": "https://cards.tcggraph.io/sv/pkm_sv3pt5_199/large.webp"
},
"imageFrom": "card",
"externalIds": {
"cardmarketId": 733794,
"tcgplayerId": 517045
},
"prices": [
{
"source": "cardmarket",
"region": "EU",
"listType": "retail",
"finish": "foil",
"currency": "EUR",
"market": 410.24,
"low": 109.98,
"trend": 410.24,
"avg1": 310,
"avg7": 318.36,
"avg30": 381.92,
"basis": "product-page",
"updatedAt": "2026-10-05T11:37:45.105Z"
},
{
"source": "tcgplayer",
"region": "NA",
"listType": "retail",
"finish": "foil",
"currency": "USD",
"market": 342.73,
"low": 297.67,
"trend": null,
"avg1": null,
"avg7": null,
"avg30": null,
"basis": null,
"updatedAt": "2026-10-04T22:00:05.544Z"
}
],
"cardId": "pkm_sv3pt5_199"
}
],
"priceStatus": {
"cardmarket": "priced",
"tcgplayer": "priced",
"graded": "priced"
},
"legalities": {
"expanded": "legal",
"standard": "legal",
"unlimited": "legal"
},
"gameData": {
"hp": 330,
"types": [
"Fire"
],
"attacks": [
{
"cost": [
"Fire"
],
"name": "Brave Wing",
"text": "If this Pokémon has any damage counters on it, this attack does 100 more damage.",
"damage": "60+",
"convertedEnergyCost": 1
},
{
"cost": [
"Fire",
"Fire",
"Fire",
"Fire"
],
"name": "Explosive Vortex",
"text": "Discard 3 Energy from this Pokémon.",
"damage": "330",
"convertedEnergyCost": 4
}
],
"subtypes": [
"Stage 2",
"ex"
],
"abilities": [],
"supertype": "Pokémon",
"weaknesses": [
{
"type": "Water",
"value": "×2"
}
],
"evolvesFrom": "Charmeleon",
"resistances": [],
"retreatCost": [
"Colorless",
"Colorless"
],
"regulationMark": "G",
"convertedRetreatCost": 2,
"nationalPokedexNumbers": [
6
]
},
"externalIds": {
"cardmarketId": 733794,
"tcgplayerId": 517045
}
}
],
"meta": {
"page": 1,
"limit": 2,
"totalCount": 3,
"totalPages": 2,
"hasMore": true,
"priceSource": "cardmarket"
}
}3. Read the response
- Lists are
{ data: [...], meta: {...} }.metahaspage,limit,totalCount,totalPagesandhasMore; page with?page=up to 100 cards at a time, 2 credits a page. - The fields every game shares are at the top of the card; the ones a game adds (Pokémon’s
hp, Magic’smanaValue) are undergameData. Every field is described on the Card object. pricesholds one quote per marketplace, list type (retail or buylist) and finish, each in that marketplace’s own currency: EUR on Cardmarket, USD on TCGplayer. Choose one rather than taking the first.printingsis the same quotes grouped by finish.idis stable and is what the price, history and watch endpoints take.
const res = await fetch("https://api.tcggraph.com/v1/cards?game=pokemon&name=charizard%20ex&set=sv3pt5&limit=2", {
headers: { Authorization: `Bearer ${process.env.TCGGRAPH_KEY}` },
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { data, meta } = await res.json();
for (const card of data) {
// One quote per source, list type and finish, each in its own currency. Pick the one you mean.
const eu = card.prices.find((p) => p.source === "cardmarket" && p.listType === "retail");
const us = card.prices.find((p) => p.source === "tcgplayer" && p.listType === "retail");
console.log(card.id, card.name, eu?.market, eu?.currency, us?.market, us?.currency);
}
console.log(`${meta.totalCount} matches, page ${meta.page} of ${meta.totalPages}`);4. Check what it cost
Every successful response says what it was charged and what is left: X-Credits-Cost, X-Credits-Remaining and X-RateLimit-Remaining. Errors and 304s cost nothing and carry no credit headers. See Credits and rate limits.
5. When something is wrong, the API says what
A parameter the API does not know is refused, not ignored, and the error names the one you probably meant:
`q` instead of `name`
curl "https://api.tcggraph.com/v1/cards?q=charizard" \
-H "Authorization: Bearer $TCGGRAPH_API_KEY"const response = await fetch("https://api.tcggraph.com/v1/cards?q=charizard", {
headers: {
Authorization: `Bearer ${process.env.TCGGRAPH_API_KEY}`,
},
});
const body = await response.json();
if (!response.ok) throw new Error(`${body.error.code}: ${body.error.message}`);import os
import requests
response = requests.get(
"https://api.tcggraph.com/v1/cards",
params={
"q": "charizard",
},
headers={"Authorization": f"Bearer {os.environ['TCGGRAPH_API_KEY']}"},
)
body = response.json()
response.raise_for_status(){
"error": {
"code": "invalid_request",
"message": "Unknown filter \"q\". Did you mean name=?",
"details": {
"field": "q",
"suggestion": "name",
"allowed": [
"page",
"limit",
"sort",
"game",
"name",
"text",
"rarity",
"set",
"collectorNumber",
"artist",
"language",
"minPrice",
"maxPrice",
"source",
"region",
"grader",
"grade",
"supertype",
"subtypes",
"hp",
"types",
"evolvesFrom",
"attacks",
"abilities",
"weaknesses",
"resistances",
"retreatCost",
"convertedRetreatCost",
"regulationMark",
"nationalPokedexNumbers",
"manaCost",
"manaValue",
"colors",
"colorIdentity",
"typeLine",
"power",
"toughness",
"loyalty",
"keywords",
"layout",
"finishes",
"cardType",
"cost",
"counter",
"life",
"attribute",
"trigger",
"frameType",
"race",
"atk",
"def",
"level",
"linkRating",
"linkMarkers",
"pendulumScale",
"archetypes",
"banlist",
"inkCost",
"inkable",
"ink",
"lore",
"strength",
"willpower",
"classifications",
"moveCost",
"version",
"aspects",
"arena",
"traits",
"unique",
"variant",
"playCost",
"dp",
"digivolveCosts",
"form",
"inheritedEffect",
"securityEffect",
"memoryCost",
"reserveCost",
"durability",
"elements",
"classes",
"speed",
"line",
"specifiedCost",
"comboPower",
"comboEnergy",
"specialTraits",
"characters",
"era",
"series",
"back",
"minHp",
"maxHp",
"minConvertedRetreatCost",
"maxConvertedRetreatCost",
"minManaValue",
"maxManaValue",
"minCost",
"maxCost",
"minPower",
"maxPower",
"minCounter",
"maxCounter",
"minLife",
"maxLife",
"minAtk",
"maxAtk",
"minDef",
"maxDef",
"minLevel",
"maxLevel",
"minLinkRating",
"maxLinkRating",
"minPendulumScale",
"maxPendulumScale",
"minInkCost",
"maxInkCost",
"minLore",
"maxLore",
"minStrength",
"maxStrength",
"minWillpower",
"maxWillpower",
"minMoveCost",
"maxMoveCost",
"minCost",
"maxCost",
"minPower",
"maxPower",
"minHp",
"maxHp",
"minLevel",
"maxLevel",
"minPlayCost",
"maxPlayCost",
"minDp",
"maxDp",
"minMemoryCost",
"maxMemoryCost",
"minReserveCost",
"maxReserveCost",
"minLevel",
"maxLevel",
"minPower",
"maxPower",
"minLife",
"maxLife",
"minDurability",
"maxDurability",
"minCost",
"maxCost",
"minSpecifiedCost",
"maxSpecifiedCost",
"minPower",
"maxPower",
"minComboPower",
"maxComboPower",
"minComboEnergy",
"maxComboEnergy"
],
"docs": "https://tcggraph.com/docs/rest#filtering"
}
}
}Every code and what to do about it is on Errors.
6. GraphQL, if it helps
One request can cover several games or pick only the fields you need, for 2 credits whatever it asks for. REST does everything GraphQL does.
The most expensive card in three games, one request
Aliases put each root field under its own key. Three root fields are still one request, 2 credits.
curl -X POST "https://api.tcggraph.com/graphql" \
-H "Authorization: Bearer $TCGGRAPH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"{\n pokemon: cards(filter: { game: POKEMON, source: CARDMARKET }, sort: PRICE_DESC, limit: 1) {\n nodes { id name prices { source finish market } }\n }\n magic: cards(filter: { game: MAGIC_THE_GATHERING, source: CARDMARKET }, sort: PRICE_DESC, limit: 1) {\n nodes { id name prices { source finish market } }\n }\n lorcana: cards(filter: { game: DISNEY_LORCANA, source: CARDMARKET }, sort: PRICE_DESC, limit: 1) {\n nodes { id name prices { source finish market } }\n }\n}"}'const response = await fetch("https://api.tcggraph.com/graphql", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TCGGRAPH_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"query": "{\n pokemon: cards(filter: { game: POKEMON, source: CARDMARKET }, sort: PRICE_DESC, limit: 1) {\n nodes { id name prices { source finish market } }\n }\n magic: cards(filter: { game: MAGIC_THE_GATHERING, source: CARDMARKET }, sort: PRICE_DESC, limit: 1) {\n nodes { id name prices { source finish market } }\n }\n lorcana: cards(filter: { game: DISNEY_LORCANA, source: CARDMARKET }, sort: PRICE_DESC, limit: 1) {\n nodes { id name prices { source finish market } }\n }\n}"
}),
});
const body = await response.json();
if (!response.ok) throw new Error(`${body.error.code}: ${body.error.message}`);import os
import requests
response = requests.post(
"https://api.tcggraph.com/graphql",
headers={"Authorization": f"Bearer {os.environ['TCGGRAPH_API_KEY']}"},
json={"query": "{\n pokemon: cards(filter: { game: POKEMON, source: CARDMARKET }, sort: PRICE_DESC, limit: 1) {\n nodes { id name prices { source finish market } }\n }\n magic: cards(filter: { game: MAGIC_THE_GATHERING, source: CARDMARKET }, sort: PRICE_DESC, limit: 1) {\n nodes { id name prices { source finish market } }\n }\n lorcana: cards(filter: { game: DISNEY_LORCANA, source: CARDMARKET }, sort: PRICE_DESC, limit: 1) {\n nodes { id name prices { source finish market } }\n }\n}"},
)
body = response.json()
response.raise_for_status(){
"data": {
"lorcana": {
"nodes": [
{
"id": "lor_p1_3",
"name": "Elsa - Snow Queen",
"prices": [
{
"source": "CARDMARKET",
"finish": "foil",
"market": 1706.76
},
{
"source": "CARDMARKET",
"finish": "normal",
"market": 5928.28
}
]
}
]
},
"pokemon": {
"nodes": [
{
"id": "pkm_ecard3_149",
"name": "Ho-oh",
"prices": [
{
"source": "CARDMARKET",
"finish": "normal",
"market": 8082.3
},
{
"source": "CARDMARKET",
"finish": "reverse-holo",
"market": 2338.05
},
{
"source": "TCGPLAYER",
"finish": "reverse-holo",
"market": 900
}
]
}
]
},
"magic": {
"nodes": [
{
"id": "mtg_6ce8744a-ede",
"name": "Traveling Chocobo",
"prices": [
{
"source": "CARDMARKET",
"finish": "foil",
"market": 50000
}
]
}
]
}
}
}Next steps
- REST overview: conventions, filtering, pagination, and every endpoint.
- GET /v1/cards: every filter and sort, with examples.
- Prices: what each marketplace’s numbers mean.
- openapi.json: generate a typed client (see SDKs).