Get a game
One game, with its gameData schema: the fields every card of the game carries and you can filter on.
schema is the contract for gameData: every field listed is on the game's cards and is accepted as a /v1/cards filter. Numeric fields (Int, Float) also take min and max bounds.
Path parameters
| Parameter | Type | Description |
|---|---|---|
| slugrequired | string | The game's slug. One of: |
Response
200 The game.
| Field | Type | Description |
|---|---|---|
| data | Game (Game reference) | A Game object with three more fields. |
| data.schema | object[] | The game's gameData fields. |
| data.schema[].name | string | The field name, as it appears under gameData and as a filter. |
| data.schema[].type | string | Int and Float fields take min/max bounds; Object fields are filtered by dotted path.One of: |
| data.schema[].description | string | What the field holds. |
| data.schema[].example | string | A value from a real card. Absent unless it applies. |
| data.notableSets | object[] | Sets we call out on the game's page. |
| data.notableSets[].code | string | Set code. |
| data.notableSets[].name | string | Set name. |
| data.notableSets[].released | string | Release date or year, as the page shows it. |
| data.notableSets[].cards | integer | Cards in the set. |
| data.priceSources | string[] | The marketplaces that quote this game, by display name (Cardmarket, TCGplayer, Card Kingdom, Mana Pool), not source id. |
Examples
Real responses from the production API, recorded on 2026-09-24 by the script that also checks every field above against them. Arrays are shown in full.
Pokémon
curl "https://api.tcggraph.com/v1/games/pokemon" \
-H "Authorization: Bearer $TCGGRAPH_API_KEY"const response = await fetch("https://api.tcggraph.com/v1/games/pokemon", {
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/games/pokemon",
headers={"Authorization": f"Bearer {os.environ['TCGGRAPH_API_KEY']}"},
)
body = response.json()
response.raise_for_status(){
"data": {
"slug": "pokemon",
"name": "Pokémon Trading Card Game",
"shortName": "Pokémon",
"publisher": "The Pokémon Company",
"released": 1996,
"counts": {
"cards": 4159,
"sets": 176,
"printings": 20635,
"languages": 6
},
"languages": [
"en",
"de",
"es",
"fr",
"it",
"ja"
],
"formats": [
"Standard",
"Expanded",
"Unlimited",
"GLC"
],
"sampleCount": 20,
"indexed": {
"cards": 26447,
"sets": 230,
"printingsByLanguage": {
"de": 13331,
"en": 26447,
"es": 12561,
"fr": 16760,
"it": 12812,
"ja": 27861
}
},
"schema": [
{
"name": "supertype",
"type": "Enum",
"description": "Pokémon, Trainer or Energy."
},
{
"name": "subtypes",
"type": "[String]",
"description": "Basic, Stage 1, Stage 2, ex, V, VMAX, Tera, Supporter, Item…"
},
{
"name": "hp",
"type": "Int",
"description": "Hit points for Pokémon cards."
},
{
"name": "types",
"type": "[String]",
"description": "Energy types the Pokémon belongs to."
},
{
"name": "evolvesFrom",
"type": "String",
"description": "The Pokémon this card evolves from."
},
{
"name": "attacks",
"type": "[Object]",
"description": "name, cost, convertedEnergyCost, damage and text."
},
{
"name": "abilities",
"type": "[Object]",
"description": "name, type (Ability, Poké-Power, Poké-Body…) and text."
},
{
"name": "weaknesses",
"type": "[Object]",
"description": "Type and multiplier or modifier."
},
{
"name": "resistances",
"type": "[Object]",
"description": "Type and damage reduction."
},
{
"name": "retreatCost",
"type": "[String]",
"description": "Energy required to retreat."
},
{
"name": "convertedRetreatCost",
"type": "Int",
"description": "Number of energy cards needed to retreat."
},
{
"name": "regulationMark",
"type": "String",
"description": "Rotation letter used by Standard legality."
},
{
"name": "nationalPokedexNumbers",
"type": "[Int]",
"description": "Pokédex entries referenced by the card."
}
],
"notableSets": [
{
"code": "BS",
"name": "Base Set",
"released": "1999-01-09",
"cards": 102
},
{
"code": "SV3.5",
"name": "Scarlet & Violet — 151",
"released": "2023-09-22",
"cards": 207
},
{
"code": "SWSH7",
"name": "Evolving Skies",
"released": "2021-08-27",
"cards": 237
},
{
"code": "ME01",
"name": "Mega Evolution",
"released": "2025-09-26",
"cards": 230
},
{
"code": "ME02",
"name": "Phantasmal Flames",
"released": "2026-01-30",
"cards": 244
}
],
"priceSources": [
"Cardmarket",
"TCGplayer"
]
}
}Errors
Every error has the same body; switch on error.code. Any endpoint can also answer 401, 402, 403 or 429 for reasons of key, plan or rate; those are on Errors.
| Status | Code | When |
|---|---|---|
| 404 | not_found | No game has that slug. Slugs are lowercase and hyphenated: magic-the-gathering, not mtg. |
Unknown slug
curl "https://api.tcggraph.com/v1/games/mtg" \
-H "Authorization: Bearer $TCGGRAPH_API_KEY"const response = await fetch("https://api.tcggraph.com/v1/games/mtg", {
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/games/mtg",
headers={"Authorization": f"Bearer {os.environ['TCGGRAPH_API_KEY']}"},
)
body = response.json()
response.raise_for_status(){
"error": {
"code": "not_found",
"message": "No game with slug \"mtg\"."
}
}