Search products
Searches the catalogue. Returns a paginated list of products matching the body.
Use this to find a card by name, browse an expansion, or filter on game-specific attributes like rarity or color. To replicate the full catalogue, use GET /v1/feeds/products instead — the feed is regenerated whenever a game's catalogue updates (typically minutes after a change).
Filter fields:
name— free-text search against the product name, ranked by relevance. A print number before or after the name (sephiroth 44) pins that print; an expansion code plus print number (msh-54,msh 54,msh54) pins a single card; an expansion code on its own (msh) surfaces that expansion's products.printNumber— exact print-number match, ignoring case.productIds,expansionId,nameSlug— direct lookups when you already know the identifier.productIds,expansionId,cardmarketId, andtcgplayerIdtake up to 200 ids per call — split larger sets across several calls.expansionId— one or more expansions, matched as "any of". Pair it withnameSlugto follow a card across a set of expansions.productType,productCategory— restrict to cards or sealed (and a sealed category likebooster_box).gameFilters— pick a game (e.g.{ "game": "mtg" }), and optionally that game's own attribute filters in the same object.
Marketplace listings:
Send a listings object — even an empty one — and every result gains an availability block: how many listings match, and the cheapest one you can buy, with its listingId ready for POST /v1/cart/items. Filter those listings with deliveryCountry, condition, language, and finish, and set inStock: true to drop products with no match.
deliveryCountry applies the same rule as checkout, so a listing returned here can be added to your cart. Sellers ship within their own country and across Europe and North America; a country outside that set matches nothing.
availability.cheapest.price is what you pay. It sits alongside pricesByFinish, where cardnexus.low is the marketplace floor across every country and every seller — so the two differ whenever the cheapest copy in the world can't reach you.
Two combinations are rejected with 400: listings together with cardmarketId or tcgplayerId, and listings together with sortBy: releaseDate. With listings, results are ordered by relevance and offset + limit cannot exceed 300,000.
Language: send an Accept-Language header (en, fr, it, es, de) to work in another language — your name text is matched in that language where a translation exists (falling back to English), and product and expansion names in the results come back in it where a translation exists. Searching Blizzaroi with Accept-Language: fr finds Abomasnow.
Pagination + sort:
limitdefaults to 50, max 200.offsetdefaults to 0.sortBy,sortDirection— sort the results.
Each result has productType set to either card or sealed. Card products carry per-finish prices and per-game attributes; sealed products carry a single price plus EAN/SKU.
This endpoint has its own rate-limit bucket (catalogue-search); paginating through tens of thousands of results will hit it before your account-level limit. The daily feeds are the right tool for bulk catalogue replication.
Authentication is required (any valid API key); no scope.
- Type: stringAccept
- Language The language to work in —
en,fr,it,es, orde, with or without a region. Name searches match in that language where a translation exists, falling back to English. Defaults to English.
- Type: array integer[] 1…200cardmarket
Id min:0max:9007199254740991Restrict results to products carrying any of these Cardmarket product ids (1–200), returned with full details. Use this to fetch details for ids you already know; to turn a list of ids into products and learn which ones don't match, use
POST /v1/products/resolve. - Type: array 1…200expansion
Id Restrict results to these expansions (1–200). Ids are returned by
GET /v1/games/{gameId}/expansions. - game
Filters Restrict to a single game, and optionally filter on that game's own attributes (rarity, color, …). Pass
{ "game": "mtg" }for any MTG product, or addfilters: { rarity: { op: "or", values: ["mythic"] } }to narrow further. To narrow to expansions, useexpansionId.Restrict to a single game, and optionally filter on that game's own attributes (rarity, color, …). Pass
{ "game": "mtg" }for any MTG product, or addfilters: { rarity: { op: "or", values: ["mythic"] } }to narrow further. To narrow to expansions, useexpansionId.- gameconst:sorceryrequired
- filtersType: object
- Type: integerlimitmin:1max:200
Integer numbers.
- Type: objectlistings
Search against live marketplace listings. Sending this object — even empty — adds an
availabilityblock to every result carrying the cheapest listing you can buy under these filters. Not accepted together withcardmarketId,tcgplayerId, orsortBy: releaseDate. - Type: stringnamemin length:1
Free-text search. Matches against the product name with relevance ranking — the closer the match, the higher the result. A print number before or after the name pins that print:
sephiroth 44returns the Sephiroth numbered 44 first. An expansion code plus print number pins a single card:msh-54,msh 54, andmsh54all return card 54 of the expansion coded MSH. Send anAccept-Languageheader to search names in another language. - Type: stringname
Slug min length:1Exact match against the product's
nameSlug, ignoring case — every printing of that card, across expansions. Slugs come back on every product innameSlug. - Type: integeroffsetmin:0max:9007199254740991
Integer numbers.
- Type: stringprint
Number min length:1Return only products with this print number, matched exactly ignoring case —
232,038,ST02-44. Combine withexpansionIdto pin a single printing. - Type: stringproduct
Category Restrict to a single sealed-product category (e.g.
booster_box,bundle). Only meaningful when filtering onsealed. - Type: array 1…200product
Ids Restrict results to a specific set of product ids (1–200). Useful for batch lookups when you already know which products you want.
- Type: objectproduct
Type Restrict to one or more product types —
{ op: "or", values: ["card"] }for cards only.
- application/json
- application/json
- application/json
- application/json
- application/json
- application/json
- application/json
curl https://public-api.cardnexus.com/v1/products/search \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"offset": 0,
"limit": 50,
"productIds": [
1
],
"expansionId": [
42,
118
],
"name": "",
"printNumber": "ST02-44",
"nameSlug": "",
"cardmarketId": [
0
],
"tcgplayerId": [
0
],
"productType": {
"op": "and",
"values": [
"card"
]
},
"productCategory": "",
"gameFilters": {
"game": "sorcery",
"filters": {}
},
"listings": {
"deliveryCountry": "GB",
"inStock": true,
"condition": [
"NM"
],
"language": [
"en",
"fr"
],
"finish": [
"Standard"
]
},
"sortBy": "printNumber",
"sortDirection": "asc"
}'
{
"data": [
{
"id": 50212,
"gameId": "mtg",
"expansionId": 42,
"game": {
"id": "mtg",
"name": "Magic: The Gathering"
},
"expansion": {
"id": 42,
"name": "Limited Edition Alpha",
"code": "LEA",
"symbolUrl": "https://images.cardnexus.com/expansions/mtg/lea/symbol.svg"
},
"name": "Black Lotus",
"nameSlug": "black-lotus",
"languages": [
"en"
],
"imageUrl": "https://images.cardnexus.com/products/mtg/lea/black-lotus-front.jpg",
"externalIds": {
"cardmarket": [
{
"finish": "Standard",
"id": 5824
}
],
"tcgplayer": [
{
"finish": "Standard",
"id": 1527
}
],
"scryfallId": "ff1b8fc5-604a-4449-a73d-861e53642a70",
"scryfallOracleId": "b7ad39b3-5d10-45a4-99ae-30972ea6ac42"
},
"productType": "card",
"printNumber": "232",
"rarity": "rare",
"finishes": [
"Standard"
],
"pricesByFinish": {
"Standard": {
"cardmarket": {
"currency": "EUR",
"marketValue": 18250,
"change7d": -1.2
},
"tcgplayer": {
"currency": "USD",
"marketValue": 20100,
"change7d": -0.9
}
}
},
"attributes": {
"manaCost": "{0}",
"colors": [],
"typeLine": "Artifact"
}
}
],
"pagination": {
"offset": 0,
"limit": 50,
"total": 124,
"hasMore": true
}
}