Response Format
JSON response structure, pagination, data types, and envelope format for the TCG Price Lookup API.
Envelope
Every API response is wrapped in a standard envelope. For list endpoints:
{
"data": [...],
"total": 47,
"limit": 20,
"offset": 0
}
For single-resource endpoints (card detail, batch lookup):
{
"data": { ... }
}
There is no success, meta, or status field in the envelope. A 2xx HTTP status code means the request succeeded. Anything else means an error — see error handling.
Envelope fields
| Field | Type | Present on | Description |
|---|---|---|---|
data | object or array | All responses | The requested resource(s) |
total | integer | List endpoints | Total number of matching records (across all pages) |
limit | integer | List endpoints | Number of results per page (as requested) |
offset | integer | List endpoints | Number of results skipped |
Card object
The card object is the core data structure returned by search, card detail, and batch endpoints.
Full card object (from /v1/cards/{id})
{
"id": "pokemon-sv4-charizard-ex-006",
"name": "Charizard ex",
"game": "pokemon",
"set": "Paradox Rift",
"setCode": "sv4",
"number": "006",
"rarity": "Double Rare",
"image": "https://images.tcgpricelookup.com/pokemon/sv4/006.jpg",
"prices": {
"market": 42.50,
"low": 35.00,
"mid": 41.00,
"high": 55.00,
"conditions": {
"near_mint": 42.50,
"lightly_played": 38.25,
"moderately_played": 34.00,
"heavily_played": 29.75,
"damaged": 21.25
},
"graded": {
"psa_10": 125.00,
"psa_9": 75.00,
"bgs_9_5": 110.00,
"cgc_9_5": 95.00
}
},
"sources": ["tcgplayer", "ebay"],
"updatedAt": "2026-04-10T12:00:00Z"
}
Card fields
| Field | Type | Description |
|---|---|---|
id | string | Unique card identifier in the format {game}-{setCode}-{slug} |
name | string | Full card name as printed on the card |
game | string | Game identifier: pokemon, mtg, yugioh, lorcana, onepiece, swu, fab, pokemonjp |
set | string | Human-readable set name |
setCode | string | Short set code used in IDs and filters (e.g., sv4, mh3) |
number | string | Card number within the set, zero-padded (e.g., "006") |
rarity | string | Card rarity as defined by the game publisher |
image | string | Card image URL (HTTPS, hosted on our CDN) |
prices | object | Pricing data object — see below |
sources | string[] | Data sources used to compute prices (e.g., tcgplayer, ebay) |
updatedAt | string | ISO 8601 timestamp of the most recent price update |
Prices object
| Field | Type | Description |
|---|---|---|
market | number | Aggregated market price in USD — the most reliable single price to display |
low | number | Lowest active listing price |
mid | number | Median listing price |
high | number | Highest listing price |
conditions | object | Per-condition pricing from Near Mint to Damaged |
graded | object | Graded card values (PSA, BGS, CGC). May be null if no graded data exists |
Conditions object
| Field | Condition |
|---|---|
near_mint | Near Mint (NM) |
lightly_played | Lightly Played (LP) |
moderately_played | Moderately Played (MP) |
heavily_played | Heavily Played (HP) |
damaged | Damaged (D) |
Graded object
| Field | Grader / Grade |
|---|---|
psa_10 | PSA Gem Mint 10 |
psa_9 | PSA Mint 9 |
bgs_9_5 | Beckett Black Label 9.5 |
cgc_9_5 | CGC Pristine 9.5 |
Not all grades are available for every card. Fields with no data are omitted from the response rather than returned as null.
Search result card object
Cards returned by /v1/search may have fewer fields than the full card detail object. Price condition and graded data may be condensed to just the market price:
{
"id": "pokemon-sv4-charizard-ex-006",
"name": "Charizard ex",
"game": "pokemon",
"set": "Paradox Rift",
"rarity": "Double Rare",
"prices": {
"market": 42.50,
"conditions": {
"near_mint": 42.50,
"lightly_played": 38.25
}
}
}
Use the /v1/cards/{id} endpoint to get the complete card object including all conditions, graded values, and source metadata.
Price history object
The price history endpoint (Trader plan and above) returns a different structure:
{
"data": {
"cardId": "pokemon-sv4-charizard-ex-006",
"period": "30d",
"history": [
{ "date": "2026-03-11", "market": 38.00, "low": 32.00, "high": 48.00 },
{ "date": "2026-03-18", "market": 39.50, "low": 33.00, "high": 49.00 },
{ "date": "2026-04-10", "market": 42.50, "low": 35.00, "high": 55.00 }
]
}
}
History entries are sorted oldest-first. The date field is an ISO 8601 date string (YYYY-MM-DD). Daily granularity is returned for 7d and 30d periods; weekly granularity for 90d and 1y; monthly for all.
Handling null and missing fields
Fields with no data are omitted from the response — they are not present with a null value. Always use optional chaining when accessing nested fields:
// Safe — won't throw if graded data is absent
const psa10 = card.prices?.graded?.psa_10 ?? null;
// Unsafe — will throw TypeError if graded is missing
const psa10 = card.prices.graded.psa_10;
# Safe — use .get() for dict access
psa10 = card.get("prices", {}).get("graded", {}).get("psa_10")
Pagination
All list endpoints (/v1/search, /v1/sets, /v1/games) support limit and offset parameters:
GET /v1/search?q=charizard&limit=20&offset=40
| Parameter | Type | Default | Max | Description |
|---|---|---|---|---|
limit | integer | 20 | 100 | Results per page |
offset | integer | 0 | — | Number of results to skip |
To iterate through all results:
async function* fetchAll(query) {
let offset = 0;
const limit = 100;
while (true) {
const res = await tcg.search(query, { limit, offset });
yield* res.data;
offset += limit;
if (offset >= res.total) break;
}
}
Data types
- Prices — floating-point numbers in USD. Never strings.
- Dates — ISO 8601 strings. Timestamps include time zone:
"2026-04-10T12:00:00Z". Date-only fields:"2026-04-10". - IDs — URL-safe strings. Safe to use directly in endpoint paths and query parameters.
- Counts — integers. Never floats.