# CardTrader API scraper — Europe's trading-card marketplace (cardtrader.com): Magic, Pokémon, Yu-Gi-Oh!, One Piece, Lorcana, Flesh and Blood, Digimon, Star Wars Unlimited and more. Search with set, category and rarity filters, every public offer with condition, card language, foil, seller and seller country, CardTrader's market price with 35-day history, sets and games. EUR or USD, any ship-to country. No account, no browser.

> Search CardTrader for one game by card or product name: product id, name, version, collector number, set, category, number of offers, the lowest price and the image. Narrow to a set, a category (singles, booster boxes…) or a rarity; sort by name, price, collector number, rarity or release date; page through 12 rows at a time. Add card_language / min_condition / foil / first_edition to get, per row, the 3 cheapest offers matching them (CardTrader's own search filter), and rows without a matching offer dropped.
> ReefAPI engine `cardtrader` · 6 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/cardtrader/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed calls are free.
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http). Clients that add connectors by URL, such as ChatGPT and the Claude app, connect with OAuth 2.1 (the user pastes their key once on a ReefAPI page; discovery at `/.well-known/oauth-protected-resource/mcp`). Config files send the key as `Authorization: Bearer <key>`. `?key=<key>` in the URL also works as a last-resort fallback.

## Endpoints

### POST https://api.reefapi.com/cardtrader/v1/search — 2 credits
Search CardTrader for one game by card or product name: product id, name, version, collector number, set, category, number of offers, the lowest price and the image. Narrow to a set, a category (singles, booster boxes…) or a rarity; sort by name, price, collector number, rarity or release date; page through 12 rows at a time. Add card_language / min_condition / foil / first_edition to get, per row, the 3 cheapest offers matching them (CardTrader's own search filter), and rows without a matching offer dropped.

**Parameters:**
- `query` (string, optional) — Card or product name (part of it is enough), or text of the version line such as a collector number '081/080'.
- `game` (enum, optional, default "pokemon") — The game, as CardTrader names it in its URLs. Aliases like mtg, ygo, onepiece, fab, swu, dbs and the numeric game id are accepted. [one of: magic, pokemon, yu-gi-oh, flesh-and-blood, digimon, one-piece, dragon-ball-super, cardfight-vanguard, lorcana, star-wars, union-arena, riftbound, gundam, sorcery, palworld, cyberpunk]
- `expansion` (string, optional) — Set slug from `expansions` (e.g. delta-reign, wild-blaze) or a cardtrader.com set URL.
- `category` (string, optional) — Category: singles, or a category id / slug / name from `games` (Booster Box, Boosters, Bundle, Complete Set…). Omit for every category.
- `rarity` (string, optional) — Rarity as CardTrader names it for the game (rarity_options in the response lists them). Applies to single cards; category defaults to singles when only rarity is set.
- `sort` (enum, optional, default "name_asc") — CardTrader's own orderings: name, price, collector number, rarity, release date. [one of: name_asc, name_desc, price_asc, price_desc, number_asc, number_desc, rarity_asc, rarity_desc, newest, oldest]
- `page` (integer, optional, default 1) — Result page, 12 rows each (CardTrader's page size).
- `only_available` (boolean, optional, default false) — Only products that currently have offers.
- `card_language` (array, optional) — Only offers of cards printed in these languages (one or more codes, e.g. en or en,jp). Names such as Japanese are accepted. [one of: en, fr, de, it, es, pt, jp, kr, ru, zh-CN, zh-TW, nl, pl, sv, id, th]
- `min_condition` (enum, optional) — Only offers in this condition or better (Mint > Near Mint > Slightly Played > Moderately Played > Played > Poor). Codes NM, SP, MP, PL, PO are accepted. [one of: mint, near_mint, slightly_played, moderately_played, played, poor]
- `foil` (boolean, optional) — true = only foil offers, false = only non-foil (games with a foil property; for Pokémon use reverse_holo).
- `reverse_holo` (boolean, optional) — Pokémon: true = only reverse-holo offers, false = only non-reverse.
- `first_edition` (boolean, optional) — true/false: first-edition copies (Pokémon, Yu-Gi-Oh!).
- `signed` (boolean, optional) — true/false: signed copies.
- `altered` (boolean, optional) — true/false: altered copies.
- `with_offers` (boolean, optional, default false) — Also return the 3 cheapest offers of every row (set automatically when an offer filter is given).
- `language` (enum, optional, default "en") — CardTrader site language: card names follow it in translated_name (Charizard → Glurak in de); a query also matches names in this language. [one of: en, it, es, fr, de]
- `currency` (enum, optional, default "EUR") — Price currency. USD prices are CardTrader's own USD prices (with its own buyer fee), not a conversion of the euro price. [one of: EUR, USD]
- `country` (enum, optional, default "DE") — Ship-to country of the shopper. CardTrader shows only the offers whose sellers ship to this country (directly or through CardTrader Zero), and the shipping 'from' price to it, so offers and lowest prices differ by country. [one of: DE, US, IT, FR, ES, GB, NL, BE, AT, PT, IE, LU, DK, SE, FI, PL, CZ, SK, SI, HR, HU, RO, BG, GR, CY, MT, EE, LV, LT, CH, NO, CA, AU, JP]
- `max_rotations` (integer, optional, default 3) — How many fresh exits to try before giving up.

**Returns:** results[]{product_id, name, translated_name, version, collector_number, rarity, url, game_id, category{id, slug, name, is_single}, expansion{id, slug, code, name, translated_name, release_date, presale}, offers_count (offer rows the site counts for the card), lowest_price, currency, lowest_price_formatted, image, image_full, best_offers[] (with an offer filter or with_offers: the 3 cheapest matching offers, same fields as product/offers)}, count, page, per_page, has_more, game, language, currency, country, sort, filters_applied, offer_filters_applied, rarity_options[], rows_dropped_without_offers, query, expansion, category

**Example request body:**
```json
{
  "game": "pokemon",
  "query": "charizard",
  "sort": "price_desc"
}
```

### POST https://api.reefapi.com/cardtrader/v1/expansion/products — 2 credits
Every product of one set with the same rows as search, by collector number by default; filter by category, rarity and name, or by offer condition / language / foil.

**Parameters:**
- `expansion` (string, required) — Set slug from `expansions` (e.g. delta-reign, wild-blaze) or a cardtrader.com set URL.
- `query` (string, optional) — Card or product name (part of it is enough), or text of the version line such as a collector number '081/080'.
- `game` (enum, optional, default "pokemon") — The game, as CardTrader names it in its URLs. Aliases like mtg, ygo, onepiece, fab, swu, dbs and the numeric game id are accepted. [one of: magic, pokemon, yu-gi-oh, flesh-and-blood, digimon, one-piece, dragon-ball-super, cardfight-vanguard, lorcana, star-wars, union-arena, riftbound, gundam, sorcery, palworld, cyberpunk]
- `category` (string, optional) — Category: singles, or a category id / slug / name from `games` (Booster Box, Boosters, Bundle, Complete Set…). Omit for every category.
- `rarity` (string, optional) — Rarity as CardTrader names it for the game (rarity_options in the response lists them). Applies to single cards; category defaults to singles when only rarity is set.
- `sort` (enum, optional, default "name_asc") — CardTrader's own orderings: name, price, collector number, rarity, release date. [one of: name_asc, name_desc, price_asc, price_desc, number_asc, number_desc, rarity_asc, rarity_desc, newest, oldest]
- `page` (integer, optional, default 1) — Result page, 12 rows each (CardTrader's page size).
- `only_available` (boolean, optional, default false) — Only products that currently have offers.
- `card_language` (array, optional) — Only offers of cards printed in these languages (one or more codes, e.g. en or en,jp). Names such as Japanese are accepted. [one of: en, fr, de, it, es, pt, jp, kr, ru, zh-CN, zh-TW, nl, pl, sv, id, th]
- `min_condition` (enum, optional) — Only offers in this condition or better (Mint > Near Mint > Slightly Played > Moderately Played > Played > Poor). Codes NM, SP, MP, PL, PO are accepted. [one of: mint, near_mint, slightly_played, moderately_played, played, poor]
- `foil` (boolean, optional) — true = only foil offers, false = only non-foil (games with a foil property; for Pokémon use reverse_holo).
- `reverse_holo` (boolean, optional) — Pokémon: true = only reverse-holo offers, false = only non-reverse.
- `first_edition` (boolean, optional) — true/false: first-edition copies (Pokémon, Yu-Gi-Oh!).
- `signed` (boolean, optional) — true/false: signed copies.
- `altered` (boolean, optional) — true/false: altered copies.
- `with_offers` (boolean, optional, default false) — Also return the 3 cheapest offers of every row (set automatically when an offer filter is given).
- `language` (enum, optional, default "en") — CardTrader site language: card names follow it in translated_name (Charizard → Glurak in de); a query also matches names in this language. [one of: en, it, es, fr, de]
- `currency` (enum, optional, default "EUR") — Price currency. USD prices are CardTrader's own USD prices (with its own buyer fee), not a conversion of the euro price. [one of: EUR, USD]
- `country` (enum, optional, default "DE") — Ship-to country of the shopper. CardTrader shows only the offers whose sellers ship to this country (directly or through CardTrader Zero), and the shipping 'from' price to it, so offers and lowest prices differ by country. [one of: DE, US, IT, FR, ES, GB, NL, BE, AT, PT, IE, LU, DK, SE, FI, PL, CZ, SK, SI, HR, HU, RO, BG, GR, CY, MT, EE, LV, LT, CH, NO, CA, AU, JP]
- `max_rotations` (integer, optional, default 3) — How many fresh exits to try before giving up.

**Returns:** results[]{product_id, name, translated_name, version, collector_number, rarity, url, game_id, category{id, slug, name, is_single}, expansion{id, slug, code, name, translated_name, release_date, presale}, offers_count (offer rows the site counts for the card), lowest_price, currency, lowest_price_formatted, image, image_full, best_offers[] (with an offer filter or with_offers: the 3 cheapest matching offers, same fields as product/offers)}, count, page, per_page, has_more, game, language, currency, country, sort, filters_applied, offer_filters_applied, rarity_options[], rows_dropped_without_offers, expansion, category

**Example request body:**
```json
{
  "game": "pokemon",
  "expansion": "delta-reign"
}
```

### POST https://api.reefapi.com/cardtrader/v1/expansions — 1 credit
Every set CardTrader lists for a game, newest first: slug (for search and expansion/products), name, set code and release date.

**Parameters:**
- `game` (enum, optional, default "pokemon") — The game, as CardTrader names it in its URLs. Aliases like mtg, ygo, onepiece, fab, swu, dbs and the numeric game id are accepted. [one of: magic, pokemon, yu-gi-oh, flesh-and-blood, digimon, one-piece, dragon-ball-super, cardfight-vanguard, lorcana, star-wars, union-arena, riftbound, gundam, sorcery, palworld, cyberpunk]
- `query` (string, optional) — Only sets whose name or code contains this text.
- `max_rotations` (integer, optional, default 3) — How many fresh exits to try before giving up.

**Returns:** expansions[]{slug, name, code, release_date, url}, count, total, game

**Example request body:**
```json
{
  "game": "magic"
}
```

### POST https://api.reefapi.com/cardtrader/v1/games — 1 credit
Every game CardTrader sells, with its id, slug and product categories (Singles, Booster Boxes, Boosters, Bundles, Complete Sets…) with their ids and slugs.

**Parameters:**
- `max_rotations` (integer, optional, default 3) — How many fresh exits to try before giving up.

**Returns:** games[]{id, slug, name, url, categories[]{id, slug, name, is_single}}, count

### POST https://api.reefapi.com/cardtrader/v1/product/detail — 3 credits
One CardTrader card or product by id or URL: name, set, collector number, rarity, images, the card page's price boxes (CT Min Price, CT Market Price, Best Deal, US Market Price), the ~35-day daily CT market and US market price history (plus foil), the price summary (lowest price overall, with CardTrader Zero, with direct shipping, in Near Mint or better), the number of copies for sale, other printings, and the cheapest offers with condition, card language, foil, seller, seller country and shipping 'from' price for the ship-to country.

**Parameters:**
- `product_id` (string, required) — CardTrader product id (product_id of any search row) or a cardtrader.com card URL.
- `offers_limit` (integer, optional, default 100) — How many of the cheapest offers to include (0 = none, price summary only).
- `language` (enum, optional, default "en") — CardTrader site language: card names follow it in translated_name (Charizard → Glurak in de); a query also matches names in this language. [one of: en, it, es, fr, de]
- `currency` (enum, optional, default "EUR") — Price currency. USD prices are CardTrader's own USD prices (with its own buyer fee), not a conversion of the euro price. [one of: EUR, USD]
- `country` (enum, optional, default "DE") — Ship-to country of the shopper. CardTrader shows only the offers whose sellers ship to this country (directly or through CardTrader Zero), and the shipping 'from' price to it, so offers and lowest prices differ by country. [one of: DE, US, IT, FR, ES, GB, NL, BE, AT, PT, IE, LU, DK, SE, FI, PL, CZ, SK, SI, HR, HU, RO, BG, GR, CY, MT, EE, LV, LT, CH, NO, CA, AU, JP]
- `max_rotations` (integer, optional, default 3) — How many fresh exits to try before giving up.

**Returns:** product{product_id, name, translated_name, version, collector_number, rarity, url, game{id, slug, name}, category{}, expansion{}, release_date, presale, can_be_graded, image, back_image, attributes{}, ct_min_price, ct_market_price, best_deal_price (the card page's price boxes 'CT Min Price', 'CT Market Price', 'Best Deal' — cheapest CardTrader Zero offer in English, Near Mint or better — computed as the page computes them), ct_min_price_foil, ct_market_price_foil, us_market_price ('US Market Price' box), us_market_price_foil, ct_market_price_daily (latest point of the daily CT market series), ct_market_price_daily_date, ct_market_trend, ct_market_price_daily_foil, price_history{ct_market[]{date, price}, ct_market_foil[], us_market[], us_market_foil[]} (~35 days), copies_for_sale (the site's count of copies), other_printings[]{product_id, name, version, expansion, expansion_slug, url}}, price_summary{lowest_price, lowest_price_ct_zero, lowest_price_direct, lowest_price_near_mint, offer_rows, copies_in_offers}, offers[]{offer_id, price (what the buyer pays, as the site shows it), currency, price_formatted, seller_price, buyer_fee, quantity, condition, condition_code (MT|NM|SP|MP|PL|PO), condition_rank, card_language{code, name}, foil, reverse_holo, first_edition, signed, altered, graded, rarity, collector_number, comment, photos[], seller{id, username, url, type (private|professional), country_code, country, ct_zero_seller, one_day_ready, rating_percent, feedback_count, ct_zero_avg_shipping_days}, ships_from, shipping_from_price, direct_shipping, ct_zero, on_vacation, offer_type (seller|ct_zero_hub), hub_group_size}, hub_offers[] (CardTrader Zero hub stock, same fields), offers_count, offers_has_more, currency, country

**Example request body:**
```json
{
  "product_id": "374423"
}
```

### POST https://api.reefapi.com/cardtrader/v1/product/offers — 3 credits
Every public offer on one card or product, cheapest first, as CardTrader shows them to a shopper in the ship-to country: price (with the seller price and CardTrader's buyer fee), quantity, condition, card language, foil / reverse holo, first edition, signed, altered, graded, the seller's name, type, country, rating and feedback count, the shipping 'from' price, whether the seller ships direct or only through CardTrader Zero, and CardTrader Zero hub stock. Filter by card language, minimum condition, foil, first edition, signed, altered, graded, seller country, seller type, CardTrader Zero or direct shipping and price; every filtered field is returned per offer so the filtering can be checked. Reads up to 1 000 offer rows.

**Parameters:**
- `product_id` (string, required) — CardTrader product id (product_id of any search row) or a cardtrader.com card URL.
- `card_language` (array, optional) — Only offers of cards printed in these languages (one or more codes, e.g. en or en,jp). Names such as Japanese are accepted. [one of: en, fr, de, it, es, pt, jp, kr, ru, zh-CN, zh-TW, nl, pl, sv, id, th]
- `min_condition` (enum, optional) — Only offers in this condition or better (Mint > Near Mint > Slightly Played > Moderately Played > Played > Poor). Codes NM, SP, MP, PL, PO are accepted. [one of: mint, near_mint, slightly_played, moderately_played, played, poor]
- `foil` (boolean, optional) — true = only foil offers, false = only non-foil (games with a foil property; for Pokémon use reverse_holo).
- `reverse_holo` (boolean, optional) — Pokémon: true = only reverse-holo offers, false = only non-reverse.
- `first_edition` (boolean, optional) — true/false: first-edition copies (Pokémon, Yu-Gi-Oh!).
- `signed` (boolean, optional) — true/false: signed copies.
- `altered` (boolean, optional) — true/false: altered copies.
- `graded` (boolean, optional) — true/false: graded (slabbed) copies.
- `seller_country` (array, optional) — Only offers shipped from these countries (ISO codes).
- `seller_type` (enum, optional) — Only offers from this seller type. [one of: private, professional]
- `ct_zero_only` (boolean, optional) — Only offers buyable with CardTrader Zero (shipped together via CardTrader's hub).
- `direct_shipping_only` (boolean, optional) — Only offers the seller ships directly to the ship-to country.
- `price_min` (number, optional) — Lowest offer price.
- `price_max` (number, optional) — Highest offer price.
- `limit` (integer, optional, default 100) — How many offers to return (cheapest first).
- `language` (enum, optional, default "en") — CardTrader site language: card names follow it in translated_name (Charizard → Glurak in de); a query also matches names in this language. [one of: en, it, es, fr, de]
- `currency` (enum, optional, default "EUR") — Price currency. USD prices are CardTrader's own USD prices (with its own buyer fee), not a conversion of the euro price. [one of: EUR, USD]
- `country` (enum, optional, default "DE") — Ship-to country of the shopper. CardTrader shows only the offers whose sellers ship to this country (directly or through CardTrader Zero), and the shipping 'from' price to it, so offers and lowest prices differ by country. [one of: DE, US, IT, FR, ES, GB, NL, BE, AT, PT, IE, LU, DK, SE, FI, PL, CZ, SK, SI, HR, HU, RO, BG, GR, CY, MT, EE, LV, LT, CH, NO, CA, AU, JP]
- `max_rotations` (integer, optional, default 3) — How many fresh exits to try before giving up.

**Returns:** product{product_id, name, translated_name, version, expansion{}, rarity, url, market_price, copies_for_sale}, price_summary{} (over the matching offers), offers[]{offer_id, price (what the buyer pays, as the site shows it), currency, price_formatted, seller_price, buyer_fee, quantity, condition, condition_code (MT|NM|SP|MP|PL|PO), condition_rank, card_language{code, name}, foil, reverse_holo, first_edition, signed, altered, graded, rarity, collector_number, comment, photos[], seller{id, username, url, type (private|professional), country_code, country, ct_zero_seller, one_day_ready, rating_percent, feedback_count, ct_zero_avg_shipping_days}, ships_from, shipping_from_price, direct_shipping, ct_zero, on_vacation, offer_type (seller|ct_zero_hub), hub_group_size}, count, matching_offers, scanned_offers, pages_read, offers_truncated, filters_applied, currency, country

**Example request body:**
```json
{
  "product_id": "374423"
}
```

## At scale
- **Volume:** 5M+ requests a day, measured at 60 requests a second across the fleet with no
  central bottleneck. Per-key limits are raised for high-volume accounts; volume pricing on request.
- **Missing a source:** tell us a site we do not cover and it becomes an engine. A customer asked
  for bestprice.gr on 21 Sep 2026 and it was in the catalog on 22 Sep.
- **Support:** 2 minute median time from a question in the live chat to the first answer. Setup
  help included, no support tier to buy.
- **One key, one credit pool** across every API. No per-site plans, no separate subscriptions.

## More
- Try it live, no code: https://reefapi.com/playground?engine=cardtrader
- Human docs page: https://reefapi.com/docs/cardtrader
- Overview page: https://reefapi.com/cardtrader-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
