# PokéWallet API — full documentation > REST API for trading card game prices and data: 12 games under one API key, with TCGPlayer (USD) and CardMarket (EUR) prices. Base URL: https://api.pokewallet.io. This file joins the documentation pages of every game and the SDK and MCP server pages; authentication, rate limits, errors and best practices appear once, in the Pokémon section, and apply to all games. Updated: 2026-10-19. Summary: https://pokewallet.io/llms.txt ## Pages - Pokémon TCG: https://pokewallet.io/api-docs (Markdown: https://pokewallet.io/api-docs.md) - One Piece Card Game: https://pokewallet.io/api-docs/one-piece (Markdown: https://pokewallet.io/api-docs/one-piece.md) - Magic: The Gathering: https://pokewallet.io/api-docs/magic-the-gathering (Markdown: https://pokewallet.io/api-docs/magic-the-gathering.md) - Yu-Gi-Oh!: https://pokewallet.io/api-docs/yugioh (Markdown: https://pokewallet.io/api-docs/yugioh.md) - Disney Lorcana: https://pokewallet.io/api-docs/lorcana (Markdown: https://pokewallet.io/api-docs/lorcana.md) - Flesh and Blood: https://pokewallet.io/api-docs/flesh-and-blood (Markdown: https://pokewallet.io/api-docs/flesh-and-blood.md) - Dragon Ball Super: https://pokewallet.io/api-docs/dragon-ball-super (Markdown: https://pokewallet.io/api-docs/dragon-ball-super.md) - Digimon: https://pokewallet.io/api-docs/digimon (Markdown: https://pokewallet.io/api-docs/digimon.md) - Star Wars Unlimited: https://pokewallet.io/api-docs/star-wars-unlimited (Markdown: https://pokewallet.io/api-docs/star-wars-unlimited.md) - Cardfight!! Vanguard: https://pokewallet.io/api-docs/cardfight-vanguard (Markdown: https://pokewallet.io/api-docs/cardfight-vanguard.md) - Riftbound: https://pokewallet.io/api-docs/riftbound (Markdown: https://pokewallet.io/api-docs/riftbound.md) - Cyberpunk: https://pokewallet.io/api-docs/cyberpunk (Markdown: https://pokewallet.io/api-docs/cyberpunk.md) - SDKs (TypeScript, Python): https://pokewallet.io/developers/sdk (Markdown: https://pokewallet.io/developers/sdk.md) - MCP server: https://pokewallet.io/developers/mcp (Markdown: https://pokewallet.io/developers/mcp.md) --- # PokéWallet API Documentation Source: https://pokewallet.io/api-docs Complete REST reference for the most comprehensive Pokémon TCG platform. Real-time pricing, 50,000+ cards database, and generous rate limits. In short PokéWallet is a REST API for Pokémon TCG card prices and data: 50,000+ cards with TCGPlayer (USD) and CardMarket (EUR) prices, refreshed daily, plus sets, search and card images. The free tier (100 requests/hour) only needs an API key; price history and set analytics need the Pro plan (€20/month) or its 7-day trial. At a glance - **Base URL:** `https://api.pokewallet.io` - **Cards:** 50,000+ Pokémon TCG cards, plus sealed products priced on TCGPlayer - **Card IDs:** `pk_` + hex for cards on TCGPlayer; hex without prefix for CardMarket-only cards - **Prices:** TCGPlayer (USD) for every variant and CardMarket (EUR) for `normal` and `holo`, refreshed daily - **Free on every plan:** Sets, set cards, card details, search and images - **Pro plan or 7-day trial:** Price history, prices by set, set statistics, completion value, trending sets and top cards - **API key:** One key for all 12 games, with shared rate limits Updated Oct 19, 2026 ## Quick Start Get started with PokéWallet API in 4 simple steps: ### Create an Account Sign up for free to start using the API. Upgrade anytime from your dashboard. [Sign Up Now](https://pokewallet.io/auth/login?source=pokemon) ### Generate an API Key Create your first API key from the dashboard. ### Make Your First Request Start querying the API with your key. *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/search?q=charizard" ``` ### Join the Discord Community Stay up to date with new features, ask for help, and connect with other developers. [Join Discord](https://discord.gg/znDxEjmDVP) ## Authentication All API requests (except `/health`) require authentication using an API key. ### API Key Format API keys follow this format: - **Production keys:** `pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` - **Development keys:** `pk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` > **Security Warning:** Never expose your API keys in client-side code, public repositories, or logs. Always use environment variables. ### Authentication Methods You can authenticate using either the `X-API-Key` header or `Authorization` header: *X-API-Key Header (Recommended)* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/search?q=pikachu" ``` *Authorization Header* ```bash curl -H "Authorization: Bearer pk_live_your_key_here" \ "https://api.pokewallet.io/search?q=pikachu" ``` ## Rate Limits Rate limits vary depending on your subscription plan: | Plan | Per hour | Per day | Paid endpoints | Price | | --- | --- | --- | --- | --- | | Free | 100 | 1,000 | — | €0 | | Coffee | 1,000+ | 10,000+ | — | Buy a coffee on Ko-fi | | Pro | 5,000 | 50,000 | Pokémon + One Piece | €20/month | | Ultra | 7,000 | 70,000 | All 12 games | €29/month | | Business | Custom | Custom | All 12 games | Contact us | | Early Access | 1,000 | 10,000 | — | No longer available | > All new users start on the **Free plan**. Upgrade from your [dashboard](https://pokewallet.io/dashboard). Early Access was our initial launch tier and is no longer available for new users. > **Please note:** After upgrading your plan, activation may require a couple of hours. [See all plans, pricing and FAQs](https://pokewallet.io/pricing) ### Rate Limit Headers Every API response includes rate limit information: ``` X-RateLimit-Limit-Hour: 100 X-RateLimit-Remaining-Hour: 95 X-RateLimit-Limit-Day: 1000 X-RateLimit-Remaining-Day: 823 ``` ### Rate Limit Exceeded (429) When you exceed your rate limit, you'll receive a `429 Too Many Requests` response: ```json { "error": "Rate limit exceeded", "message": "Hourly limit exceeded", "limits": { "hourly": { "limit": 100, "used": 100, "remaining": 0 }, "daily": { "limit": 1000, "used": 523, "remaining": 477 } } } ``` ## Public Endpoints > **No Authentication Required:** These endpoints are publicly accessible. ### GET /health (No Auth Required) Check API status, database, cache, and storage health with response times. ### Example Request: *cURL* ```bash curl "https://api.pokewallet.io/health" ``` ### Response Example (Healthy): *200 OK* ```json { "status": "healthy", "timestamp": "2025-12-16T10:30:00.000Z", "version": "1.1.0", "checks": { "database": { "status": "healthy", "responseTime": 45 }, "cache": { "status": "healthy", "responseTime": 3 }, "storage": { "status": "healthy", "responseTime": 12 } }, "responseTime": 60, "region": "FRA" } ``` ### Response Example (Unhealthy): *503 Service Unavailable* ```json { "status": "unhealthy", "timestamp": "2025-12-16T10:30:00.000Z", "version": "1.1.0", "message": "Critical services unavailable - API may not function correctly", "checks": { "database": { "status": "unhealthy", "responseTime": null, "message": "Connection failed" }, "cache": { "status": "healthy", "responseTime": 3 }, "storage": { "status": "healthy", "responseTime": 12 } }, "responseTime": 1050, "region": "FRA" } ``` ### GET / (No Auth Required) Get API information, version, and available endpoints. ### Example Request: *cURL* ```bash curl "https://api.pokewallet.io/" ``` ### Response Example: *200 OK* ```json { "name": "PokeWallet API", "version": "1.1.0", "status": "production", "authentication": { "required": true, "method": "API Key", "header": "X-API-Key", "format": "pk_live_xxxxxxxxxxxxx" }, "endpoints": { "health": { "path": "/health", "auth_required": false }, "search": { "path": "/search?q=charizard&limit=20", "auth_required": true }, "cardDetail": { "path": "/cards/:id", "auth_required": true }, "sets": { "path": "/sets", "auth_required": true }, "setDetails": { "path": "/sets/:setCode?page=1&limit=50", "auth_required": true }, "images": { "path": "/images/:id?size=high", "auth_required": true } }, "rate_limits": { "per_hour": 100, "per_day": 1000, "plan": "free" } } ``` ### GET /games (No Auth Required) Lists the games available under their own prefix (`/mtg`, `/ygo`, …) with their routes. Pokémon and One Piece are not in this list: they use `/cards`, `/sets`… and `/op/…`. ### Example Request: *cURL* ```bash curl "https://api.pokewallet.io/games" ``` ### Response Example (first of ten games): *200 OK* ```json { "success": true, "data": [ { "code": "mtg", "name": "Magic: the Gathering", "endpoints": { "sets": "/mtg/sets", "set": "/mtg/sets/:set", "card": "/mtg/cards/:id", "search": "/mtg/search?q=", "image": "/mtg/images/:id" } } ] } ``` > **Pokémon TCG PRO endpoints: Pro or Ultra plan** > > Pro (€20/month) covers Pokémon and One Piece only. Ultra (€29/month) includes everything in Pro plus the paid endpoints of the other 10 games: Magic, Yu-Gi-Oh!, Lorcana and more. > > [Compare plans →](https://pokewallet.io/pricing) ## Card ID Formats The API uses two different ID formats depending on the card's data source: ### TCG Cards (TCGPlayer) **Format:** `pk_` + hexadecimal hash **Example:** ``` pk_72046138a4c1908a9f27c93fdd8189ba... ``` **Usage:** All cards with TCGPlayer data (even if they also have CardMarket data) > **One ID per printing:** alternate printings of the same card number (e.g. Pikachu 025/165 base, Poké Ball Pattern, Master Ball Pattern) have different IDs. Finishes of the same product (Normal / Reverse Holofoil) share one ID. ### CardMarket-Only Cards **Format:** Direct hexadecimal hash (no `pk_` prefix) **Example:** ``` 2208e8a2750c07d89e54870ffcef80d1... ``` **Usage:** Only cards exclusively from CardMarket (e.g., Japanese sets, European promos) > **Unique Variants:** Cards with the same `card_number` but different variants (V1, V2, etc.) have unique IDs. ## Price Variants Prices come from two different sources, each with its own way of classifying card variants. Understanding this distinction is important when reading the `prices` array in any response. ### TCGPlayer Uses a `sub_type_name` field to distinguish versions: - **`Normal`:** Common / non-holo cards - **`Holofoil`:** Holo cards - **`Reverse Holofoil`:** Most Vintage Sets (Base through Neo) - **`1st Edition`:** Base Set 1st Ed and similar - **`Unlimited`:** Standard version of sets that have 1st editions - **`Shadowless`:** Specific Base Set variants ### CardMarket Uses a simpler `variant_type` field: - **`normal`:** Standard non-holo version - **`holo`:** Holo version > CardMarket uses a simpler two-tier system regardless of the set era. ## Product Types TCGPlayer also lists sealed products — booster boxes, elite trainer boxes, blisters, tins, displays, theme decks — alongside singles. The API surfaces both, labeled by a `product_type` field. ### Cards Singles — the default. Have a `rarity`, appear in price statistics, completion value and top-cards rankings. ### Sealed Products Booster boxes, ETBs, blisters, tins, displays, theme decks. Priced only via TCGPlayer — `cardmarket` is always `null`, since CardMarket sealed data isn't imported yet. > **Where `product_type` appears:** inside `card_info` on `/search`, `/sets/:setCode` and `/cards/:id`; at the row level (alongside `id`, `card_number`, `name`) on `/prices/:setCode`. > **Excluded from aggregates:** sealed products are omitted from `/analytics/top-cards`, `/sets/:setCode/statistics` and `/sets/:setCode/completion-value` — a booster box's price would otherwise dominate rankings and completion-cost estimates meant for singles. They still appear in `/sets` (counted separately via `sealed_count`) and `/sets/:setCode` (listed alongside the cards). ## Search Endpoints > **Authentication Required:** All Search endpoints require an API key. ### GET /search Advanced card search with unified pricing from TCGPlayer and CardMarket. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | Required | Search query. Supports multiple formats: **Card name:** `charizard`, `pikachu ex`; **Set code:** `SV2a`, `SWSH3`; **Card number:** `148`, `148/165`; **set_id + card number:** `24541 148` — precise lookup using a numeric set ID and card number | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 20, max: 100) | ### Example Requests: *cURL — Search by name* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/search?q=charizard+ex" ``` *cURL — Search by set_id + card number (precise lookup)* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/search?q=24541%20148" ``` ### Response Example (TCG Card): *200 OK* ```json { "query": "pikachu", "results": [ { "id": "pk_72046138a4c1908a9f27c93fdd8189ba4ac8e683efaed6b9161efcef129302394a9ec1d20d", "card_info": { "name": "Pikachu ex (Pikachu 60)", "clean_name": "Pikachu ex Pikachu 60", "set_name": "Battle Academy 2024", "set_code": "BA2024", "set_id": "23520", "card_number": "106", "rarity": "Holo Rare", "card_type": "Lightning", "hp": "200.0", "stage": "Basic", "card_text": null, "attacks": ["[LLC] Thunderbolt (120)"], "weakness": "Fx2", "resistance": null, "retreat_cost": "1.0", "product_type": "card" }, "images": { "languages": ["en", "it", "de"] }, "tcgplayer": { "prices": [{ "sub_type_name": "Normal", "low_price": 7, "mid_price": 9.37, "high_price": 18, "market_price": 8.01, "direct_low_price": null, "updated_at": "2025-12-27T05:14:43.451818" }], "url": "https://www.tcgplayer.com/product/556443" }, "cardmarket": null } ], "pagination": { "page": 1, "limit": 20, "total": 56, "total_pages": 3 }, "metadata": { "total_count": 56, "tcg": 18, "cardmarket": 38, "tcg_only": 18, "cardmarket_only": 38, "both_sources": 0 } } ``` ### Response Example (CardMarket-Only Card): *200 OK* ```json { "query": "cubone cbb3c", "results": [ { "id": "8eb728bd59d4e1a0d94c354e4cc65a7465b55cfa4261bfa93301faa5ec921f97", "card_info": { "name": "Cubone (CBB3C 04)", "set_code": "CBB3C", "set_id": "-15", "card_number": "4", "product_type": "card" }, "images": { "languages": ["en"] }, "tcgplayer": null, "cardmarket": { "product_name": "Cubone (CBB3C 04)", "prices": [ { "avg": null, "low": 0.02, "avg1": null, "avg7": null, "avg30": null, "trend": 0, "updated_at": "2025-12-29T04:54:57.728497", "variant_type": "normal" }, { "avg": 0.37, "low": 0.02, "avg1": 0.1, "avg7": 0.35, "avg30": 0.35, "trend": 0.29, "updated_at": "2025-12-29T04:54:57.728497", "variant_type": "holo" } ], "product_url": "https://www.cardmarket.com/en/Pokemon/Products/Singles/Gem-Pack-Vol-3/Cubone-V1-CBB3C04" } }, { "id": "a7ed43b641d4f24b494ad5889845085f33966d1f19cb9e0ed353979025d8da31", "card_info": { "name": "Cubone (CBB3C 04)", "set_code": "CBB3C", "set_id": "-15", "card_number": "4", "product_type": "card" }, "images": { "languages": ["en"] }, "tcgplayer": null, "cardmarket": { "product_name": "Cubone (CBB3C 04)", "prices": [ { "avg": null, "low": 0.02, "trend": 0, "variant_type": "normal" } ], "product_url": "https://www.cardmarket.com/en/Pokemon/Products/Singles/Gem-Pack-Vol-3/Cubone-V4-CBB3C04" } } ], "pagination": { "page": 1, "limit": 2, "total": 7, "total_pages": 4 }, "metadata": { "total_count": 7, "tcg": 0, "cardmarket": 7, "tcg_only": 0, "cardmarket_only": 7, "both_sources": 0 } } ``` > **Note on CardMarket-Only Cards:** The 7 Cubone variants (V1-V7) all share the same `card_number: "4"` and `set_code: "CBB3C"`, but each has a unique ID. This ensures each variant can be uniquely identified and its correct image can be retrieved. **Set Identifiers:** Use `set_id` to match cards to their set: it is the same value returned by the `/sets` endpoint. `card_info.set_code` may contain the numeric set id instead of the short code for some cards. **Image Languages:** The `images.languages` array lists the languages the card's image is available in. `"en"` is always present and refers to the card's default artwork (English for international sets, Japanese for Japanese sets); additional codes (`it`, `fr`, `de`, `es`, `pt`) mean a localized European variant can be requested via `/images/:id?lang=xx`. See the [Images Endpoint](https://pokewallet.io/api-docs#images-endpoint). **Sealed Products:** Results can include sealed products (booster boxes, ETBs, displays, etc.) as well as cards — check `card_info.product_type`. CardMarket-only results are always `"card"`, since CardMarket sealed data isn't imported yet. See [Product Types](https://pokewallet.io/api-docs#product-types). ### GET /search/by-price-range (Coming Soon) Search cards by price range with optional filters for rarity and set. > **⏳ This endpoint is currently in development** and will be available soon after thorough testing. ### GET /search/by-type (Coming Soon) Search cards by card type (Pokemon, Trainer, Energy) and optional subtype filters. > **⏳ This endpoint is currently in development** and will be available soon after thorough testing. ## Cards Endpoints > **Authentication Required:** All Cards endpoints require an API key in the `X-API-Key` header. ### GET /cards/:id Get complete card details with unified pricing from TCGPlayer and CardMarket. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Required | Card ID - Two formats supported: **TCG cards:** `pk_xxx` (with prefix); **CardMarket-only:** hexadecimal hash (no prefix) | | `set_code` | string | Optional | Set code for disambiguation (e.g., "SWSH3", "SV1", "CBB3C"). Supports both alphanumeric codes and numeric group IDs. | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cards/pk_xxx" ``` ### Response Example: *200 OK* ```json { "id": "pk_xxx", "card_info": { "name": "Charizard VMAX", "clean_name": "Charizard VMAX", "set_name": "Darkness Ablaze", "set_code": "SWSH3", "set_id": "22789", "card_number": "20/189", "rarity": "Secret Rare", "card_type": "Pokemon", "hp": "330", "stage": null, "card_text": "VMAX rule: When your VMAX Pokemon is Knocked Out...", "attacks": ["Fire Spin - 320 damage"], "weakness": "Water", "resistance": null, "retreat_cost": "3", "product_type": "card" }, "images": { "languages": ["en", "it", "fr", "de", "es"] }, "tcgplayer": { "url": "https://tcgplayer.com/product/123456", "prices": [ { "sub_type_name": "Normal", "low_price": 245.99, "mid_price": 299.99, "high_price": 450.00, "market_price": 285.00, "direct_low_price": 250.00, "updated_at": "2025-12-16T04:00:00Z" } ] }, "cardmarket": { "product_name": "Charizard VMAX (Secret)", "product_url": "https://cardmarket.com/product/789012", "prices": [{ "variant_type": "normal", "avg": 260.50, "low": 240.00, "trend": 270.00, "avg1": 258.30, "avg7": 255.80, "avg30": 280.50, "updated_at": "2025-12-16T04:00:00Z" }] } } ``` ### GET /cards/:id/price-history (Pro) Get historical price snapshots from both TCGPlayer and CardMarket, with percentage changes over 7, 14, 30, 60 and 120 days. > **Pro feature — 7-day free trial available.** Activate your free trial from the [dashboard](https://pokewallet.io/dashboard) to access this endpoint at no cost. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Required | Card ID (`pk_xxx` for TCG+CM cards, `encrypted_id` for CM-only cards) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cards/pk_xxx/price-history" ``` ### Response Example: *200 OK* ```json { "id": "pk_abc123", "card_name": "Charizard (Base Set)", "tcgplayer": { "variants": { "Normal": { "current": { "market": 12.50, "low": 10.00, "mid": 11.50, "high": 15.00, "direct_low": 11.00 }, "price_7d": 11.80, "price_14d": 11.20, "price_30d": null, "price_60d": null, "price_120d": null, "change_7d": "+5.9%", "change_14d": "+11.6%", "change_30d": null, "change_60d": null, "change_120d": null, "last_updated": "2026-04-26T06:00:00Z" } } }, "cardmarket": { "variants": { "normal": { "current": { "avg": 9.50, "low": 8.00, "trend": 9.20 }, "avg_1d": 9.40, "avg_7d": 8.90, "avg_30d": 8.50, "price_7d": 8.90, "price_14d": 8.60, "price_30d": null, "price_60d": null, "price_120d": null, "change_7d": "+6.7%", "change_14d": "+10.5%", "change_30d": null, "change_60d": null, "change_120d": null, "last_updated": "2026-04-26T06:00:00Z" } } } } ``` > Fields like `price_14d`, `price_30d`, `price_60d`, `price_120d` return `null` until enough weekly snapshots have accumulated. `price_7d` is available from April 16, 2026. ### Trial Response Headers: When accessing this endpoint during an active trial, two extra headers are included: ``` X-Trial-Expires-At: 2026-05-01T00:00:00.000Z X-Trial-Days-Remaining: 7 ``` ### Error Responses: | Status | Description | | --- | --- | | `403` — trial not activated | `{ "error": "Trial not activated", "redeem_url": "https://pokewallet.io/dashboard" }` | | `403` — trial expired | `{ "error": "Pro plan required", "upgrade_url": "https://pokewallet.io/pricing" }` | ## Sets Endpoints > **Authentication Required:** All Sets endpoints require an API key. ### GET /sets Get list of all Pokemon sets with card counts. ### Response Fields: | Field | Type | Description | | --- | --- | --- | | `name` | string | Set name | | `set_code` | string \| null | Short code for the set (e.g., "SV1", "SWSH3"). May be `null` for some promo or special sets. | | `set_id` | string | Unique numeric identifier for the set (group_id) | | `card_count` | number | Number of card **printings** in the set — one per TCGPlayer product, so alternate printings of the same collector number (Master Ball Pattern, Poké Ball Pattern, …) count separately. Equals the number of card entries in `/sets/:setCode`. Sealed products are **not** included — see `sealed_count`. | | `number_count` | number | Number of distinct **collector numbers** in the set: `025/165` counts once however many printings it has. **Omitted** (not `0`) when not available. | | `sealed_count` | number | Number of sealed products in the set. See [Product Types](https://pokewallet.io/api-docs#product-types). **Omitted** (not `0`) when not yet available for this deployment — a missing field means "unknown", not "none". | | `language` | string \| null | Set language code (e.g., "eng", "jap", "ger"). May be `null` if not specified. | | `release_date` | string \| null | Set release date (e.g., "3rd August, 2007"). May be `null` if unknown. | ### Example Request: ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/sets" ``` ### Response Example: *200 OK* ```json { "success": true, "data": [ { "name": "SV09: Journey Together", "set_code": "JTG", "set_id": "24073", "card_count": 190, "number_count": 190, "sealed_count": 27, "language": "eng", "release_date": "28th March, 2025" }, { "name": "SV2a: Pokemon Card 151", "set_code": "SV2a", "set_id": "23599", "card_count": 516, "number_count": 210, "sealed_count": 4, "language": "jap", "release_date": "16th June, 2023" }, { "name": "Plasma Freeze", "set_code": "PLF", "set_id": "1382", "card_count": 122, "number_count": 122, "sealed_count": 5, "language": "eng", "release_date": "8th May, 2013" } ], "total": 864 } ``` > `card_count + sealed_count` is the number of entries listed by `/sets/:setCode` (its `total_cards`). SV2a above has 210 collector numbers but 516 printings: most numbers exist as a base card plus Poké Ball Pattern and Master Ball Pattern versions, each with its own ID and price. ### GET /sets/:setCode Get set details with paginated card list. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `setCode` | string | Required | Set identifier - accepts either `set_code` (e.g., "PLF", "SV2a") or `set_id` (e.g., "1382"). Both values are returned by the `/sets` endpoint. Prefer `set_id`: it is always unique. | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 50, max: 200) | | `language` | string | Optional | Filter by language when a `set_code` matches multiple sets (e.g., `eng`, `jap`, `chn`). Not needed when using a numeric `set_id`. | ### Set Object Fields: | Field | Type | Description | | --- | --- | --- | | `name` | string | Set name | | `set_code` | string \| null | Short code for the set. May be `null` for some promo sets. | | `set_id` | string | Unique numeric identifier for the set (group_id) | | `total_cards` | number | Total number of entries in the `cards` list, across all pages: every card printing **plus** sealed products. | | `language` | string \| null | Set language code (e.g., "eng", "jap"). May be `null` if not specified. | | `release_date` | string \| null | Set release date (e.g., "3rd August, 2007"). May be `null` if unknown. | > The `cards` list has **one entry per printing**. Alternate printings of the same collector number — Master Ball Pattern, Poké Ball Pattern, Pokémon Center exclusives, Prerelease `[Staff]`, Cosmos Holofoil — are separate entries, each with its own `id` and prices. Sealed products are listed too: each entry's `card_info.product_type` is `"card"` or `"sealed"`. See [Product Types](https://pokewallet.io/api-docs#product-types). ### Card Fields Specific to This Endpoint: | Field | Type | Description | | --- | --- | --- | | `card_info.variants` | string[] | TCGPlayer finishes of this printing, e.g. `["Normal", "Reverse Holofoil"]`. A reverse holo sold as the same product is a finish of the same entry, not a separate entry. Empty for CardMarket-only cards and sealed products. Only returned by `/sets/:setCode`. | ### Example Request: ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/sets/PLF" ``` ### Response Example: *200 OK* ```json { "success": true, "set": { "name": "Plasma Freeze", "set_code": "PLF", "set_id": "1382", "total_cards": 127, "language": "eng", "release_date": "8th May, 2013" }, "cards": [ { "id": "pk_4687f4c4a0499fd6a7fa267a9bef2cb4c462f19478522c5a85eaf116ca1d1f0c8ad2ba5fc8ac3c668627bce5", "card_info": { "name": "Weedle", "clean_name": "Weedle", "set_name": "Plasma Freeze", "set_code": "1382", "card_number": "1/116", "rarity": "Common", "card_type": null, "product_type": "card", "variants": ["Normal", "Reverse Holofoil"], "hp": "50.0", "stage": "Basic", "card_text": null, "attacks": [ "[G] Triple Stab (10x) Flip 3 coins. This attack does 10 damage times the number of heads." ], "weakness": "Rx2", "resistance": null, "retreat_cost": "1.0" }, "images": { "languages": ["en", "it", "fr", "de", "es", "pt"] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/90547" }, "cardmarket": { "product_name": "Weedle", "prices": [], "product_url": "https://www.cardmarket.com/en/Pokemon/Products/Singles/Plasma-Freeze/Weedle-PLF1" } }, { "id": "pk_d5e4b0f70f10d85b1439e7169de2b226b8265aa41579d52defcdbf3361dc53898e5e143670fdbcd2", "card_info": { "name": "Plasma Freeze Booster Box", "clean_name": "Plasma Freeze Booster Box", "set_name": "Plasma Freeze", "set_code": "PLF", "card_number": null, "rarity": null, "card_type": null, "product_type": "sealed", "variants": [], "hp": null, "stage": null, "card_text": null, "attacks": [], "weakness": null, "resistance": null, "retreat_cost": null }, "images": { "languages": ["en"] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/98516" }, "cardmarket": null } ``` ### Alternate Printings: The same collector number can appear several times, once per printing. Real example from SV2a (IDs shortened): *SV2a — card number 025/165* ```json [ { "id": "pk_ca32920ee8a538e4794fa…", "card_info": { "name": "Pikachu - 025/165", "card_number": "025/165", "variants": ["Normal"] } }, { "id": "pk_a2d13d65cfc4dfb669f2d…", "card_info": { "name": "Pikachu - 025/165 (Poke Ball Pattern)", "card_number": "025/165", "variants": ["Holofoil"] } }, { "id": "pk_779e688ac75c524ebcdd6…", "card_info": { "name": "Pikachu - 025/165 (Master Ball Pattern)", "card_number": "025/165", "variants": ["Holofoil"] } } ] ``` > CardMarket does not distinguish these printings. When a collector number has several printings, the `cardmarket` block is attached to one of them — normally the base printing — and is `null` on the others. TCGPlayer prices are always the printing's own. ### Set Not Found: *404 Not Found* ```json { "error": "Set not found: invalid set_code" } ``` ### Disambiguation Response: Some set codes (e.g., `"PR"`) are shared by multiple sets with different `set_id`s. When this happens, instead of returning a single set, the API returns a disambiguation response listing all matching sets so you can pick the right one. *200 OK — Multiple matches* ```json { "disambiguation": true, "message": "Multiple sets found for set_code 'PR'. Use set_id to specify which one.", "matches": [ { "set_id": "1938", "set_code": "PR", "name": "Alternate Art Promos", "language": "eng", "release_date": null }, { "set_id": "1451", "set_code": "PR", "name": "XY Promos", "language": "eng", "release_date": null }, { "set_id": "1407", "set_code": "PR", "name": "Black and White Promos", "language": "eng", "release_date": null } ], "total": 21 } ``` > **Tip:** When you receive a disambiguation response, pick the `set_id` of the set you need and call `/sets/1938` (using the numeric `set_id`) to get that specific set with its cards. ### GET /sets/:setCode/image Retrieve the logo/image for a set. Returns binary image data (PNG). Not all sets have an image available. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `setCode` | string | Required | Set identifier — accepts either `set_code` (e.g., `SWSH3`) or numeric `set_id` (e.g., `23456`). Both are returned by the `/sets` endpoint. | | `language` | string | Optional | Required only when a `set_code` is shared by multiple sets (e.g., `eng`, `jap`). Not needed when using a numeric `set_id`. | ### Response Headers: - `Content-Type`: `image/png` - `Cache-Control`: `public, max-age=86400` ### Example Request: ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/sets/SWSH3/image" \ --output swsh3.png ``` ### Error Responses: *404 — Image not available* ```json { "error": "Image not available", "message": "No set image is available for this set." } ``` *409 — Ambiguous set code* ```json { "error": "Ambiguous set code", "message": "Multiple sets found for set_code 'SM11'. Add ?language=eng (or jap, etc.) to disambiguate, or use a numeric set_id.", "matches": [ { "set_id": "2464", "language": "eng" }, { "set_id": "23690", "language": "jap" } ] } ``` > **Tip:** Use a numeric `set_id` (e.g., `/sets/23456/image`) to always get a unique result without disambiguation. ### GET /sets/:setCode/statistics (PRO) Get complete price statistics and rarity breakdown for a set. Returns average, min and max prices from both TCGPlayer (USD) and CardMarket (EUR), plus the most expensive card and a 7-day trend direction. > **Pro feature — 7-day free trial available.** Activate your free trial from the [dashboard](https://pokewallet.io/dashboard) to access this endpoint at no cost. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `setCode` | string | Required | Numeric group_id (`23599`) or alphanumeric set code (`sv2a`) | | `variant` | string | Optional | Filter CardMarket prices by variant: `normal`, `holo`. Does not affect TCGPlayer data. | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/sets/23599/statistics" ``` ### Response Example: *200 OK* ```json { "set_info": { "name": "SV2a_ Pokemon Card 151", "set_code": "23599", "total_cards": 524 }, "price_statistics": { "tcgplayer": { "avg_market_price": "7.80", "min_price": 0.07, "max_price": 307.56, "most_expensive": { "name": "Charizard ex - 201/165", "price": 307.56 } }, "cardmarket": { "avg_price": "2.34", "min_price": 0.37, "max_price": 17.91, "trend_direction": "up" } }, "rarity_breakdown": { "Common": 199, "Uncommon": 186, "Rare": 77, "Double Rare": 12, "Art Rare": 18, "Super Rare": 16, "Special Art Rare": 8, "Ultra Rare": 3, "Unknown": 5 } } ``` > **Sealed products excluded:** booster boxes, ETBs, displays and similar are left out of `price_statistics` and `rarity_breakdown` — they don't have a `rarity` and would otherwise dominate the price range. See [Product Types](https://pokewallet.io/api-docs#product-types). ### Trial Response Headers: When accessing this endpoint during an active trial, two extra headers are included: ``` X-Trial-Expires-At: 2026-05-01T00:00:00.000Z X-Trial-Days-Remaining: 7 ``` ### Error Responses: | Status | Description | | --- | --- | | `403` — trial not activated | `{ "error": "Trial not activated", "redeem_url": "https://pokewallet.io/dashboard" }` | | `403` — trial expired | `{ "error": "Pro plan required", "upgrade_url": "https://pokewallet.io/pricing" }` | ### GET /sets/trending (PRO) Returns the sets with the highest average price variation over the last 7 or 30 days, based on CardMarket moving averages. Each set includes the top movers (individual cards with the largest price change). > **Pro feature — 7-day free trial available.** Activate your free trial from the [dashboard](https://pokewallet.io/dashboard) to access this endpoint at no cost. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `period` | string | Optional | Time window: `7d` (default) or `30d` | | `limit` | number | Optional | Number of sets to return (default: 10, max: 50) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/sets/trending?period=7d&limit=5" ``` ### Response Example: *200 OK* ```json { "period": "7d", "trending_sets": [ { "set_name": "Miracle of the Desert", "set_code": "-4", "card_count": 46, "cardmarket": { "price_change": "+90.6%", "avg_price_current": 15.67, "avg_price_previous": 8.22, "top_movers": [ { "name": "Dusclops (ADV2 031)", "change": "+449.1%" }, { "name": "Raichu ex (ADV2 023)", "change": "+433.3%" }, { "name": "Typhlosion ex (ADV2 013)", "change": "+389.4%" } ] }, "tcgplayer": null }, { "set_name": "BW1_ Black Collection", "set_code": "23893", "card_count": 18, "cardmarket": { "price_change": "+40.8%", "avg_price_current": 2.22, "avg_price_previous": 1.58, "top_movers": [ { "name": "Beartic (BW1b 018)", "change": "+171.2%" }, { "name": "Emboar (BW1b 010)", "change": "+97.4%" }, { "name": "Sawsbuck (BW1b 007)", "change": "-86.3%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } } ] } ``` ### Trial Response Headers: When accessing this endpoint during an active trial, two extra headers are included: ``` X-Trial-Expires-At: 2026-05-01T00:00:00.000Z X-Trial-Days-Remaining: 7 ``` ### Error Responses: | Status | Description | | --- | --- | | `403` — trial not activated | `{ "error": "Trial not activated", "redeem_url": "https://pokewallet.io/dashboard" }` | | `403` — trial expired | `{ "error": "Pro plan required", "upgrade_url": "https://pokewallet.io/pricing" }` | ### GET /sets/:setCode/completion-value (PRO) Calculates the estimated cost to complete a set by buying one copy of every card. Returns separate estimates for TCGPlayer (USD) and CardMarket (EUR) — no cross-currency conversion is performed. Includes a breakdown by rarity. > **Pro feature — 7-day free trial available.** Activate your free trial from the [dashboard](https://pokewallet.io/dashboard) to access this endpoint at no cost. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `setCode` | string | Required | Numeric group_id (`23599`) or alphanumeric set code (`sv2a`). CardMarket-only sets (negative group_id) return 404. | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/sets/23599/completion-value" ``` ### Response Example: *200 OK* ```json { "set_info": { "name": "SV2a_ Pokemon Card 151", "set_code": "23599", "total_cards": 524 }, "completion_cost": { "tcgplayer": { "currency": "USD", "low_estimate": 4516.16, "market_estimate": 4056.03, "high_estimate": 13687.29 }, "cardmarket": { "currency": "EUR", "low_estimate": 683.50, "avg_estimate": 1232.46, "trend_estimate": 1526.69 }, "note": "TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available." }, "breakdown_by_rarity": { "Common": { "count": 199, "total_cost": 950.32 }, "Uncommon": { "count": 186, "total_cost": 732.37 }, "Rare": { "count": 77, "total_cost": 645.50 }, "Double Rare": { "count": 12, "total_cost": 8.29 }, "Art Rare": { "count": 18, "total_cost": 254.25 }, "Super Rare": { "count": 16, "total_cost": 85.38 }, "Special Art Rare": { "count": 8, "total_cost": 893.35 }, "Ultra Rare": { "count": 3, "total_cost": 31.02 }, "Unknown": { "count": 5, "total_cost": 12.47 } } } ``` > **Sealed products excluded:** the completion cost is for one copy of each card — a booster box or display isn't a card to collect, so it's left out of `completion_cost` and `breakdown_by_rarity`. See [Product Types](https://pokewallet.io/api-docs#product-types). *404 — CardMarket-only set* ```json { "success": false, "error": "This is a CardMarket-only set without TCGPlayer pricing data" } ``` ### Trial Response Headers: When accessing this endpoint during an active trial, two extra headers are included: ``` X-Trial-Expires-At: 2026-05-01T00:00:00.000Z X-Trial-Days-Remaining: 7 ``` ### Error Responses: | Status | Description | | --- | --- | | `403` — trial not activated | `{ "error": "Trial not activated", "redeem_url": "https://pokewallet.io/dashboard" }` | | `403` — trial expired | `{ "error": "Pro plan required", "upgrade_url": "https://pokewallet.io/pricing" }` | ## Prices Endpoints ### GET /prices/:setCode (PRO) Returns prices for every card in a Pokémon set, flat list, all variants. Use `?source` to restrict to a single marketplace. > **Pro feature — 7-day free trial available.** Activate your free trial from the [dashboard](https://pokewallet.io/dashboard) to access this endpoint at no cost. ### Path Parameter: | Parameter | Type | Examples | | --- | --- | --- | | `:setCode` | string or number | `MEW`, `sv2a` (set code, case-insensitive) \| `22873`, `-188` (numeric group_id) | ### Query Parameters: | Parameter | Type | Required | Values | | --- | --- | --- | --- | | `source` | string | No | `tcg` — TCGPlayer only \| `cm` — CardMarket only \| omit for both | ### Example Requests: *cURL* ```bash # Both sources (default) curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/prices/MEW" # TCGPlayer only curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/prices/MEW?source=tcg" # By numeric group_id curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/prices/22873" ``` ### Response Example: *200 OK* ```json { "success": true, "source": "both", "set_code": "MEW", "group_id": "23237", "total": 361, "data": [ { "id": "pk_72046138a4c1908a9f27c93fdd8189ba4ac8e683efaed6b9161efcef129302394a9ec1d20d", "card_number": "001/165", "name": "Bulbasaur - 001/165", "variant": "Normal", "product_type": "card", "tcgplayer": { "low_price": 0.05, "mid_price": 0.20, "high_price": 2.00, "market_price": 0.15, "direct_low_price": 0.10, "updated_at": "2026-05-04T07:43:36.088579" }, "cardmarket": { "avg": 0.10, "low": 0.04, "trend": 0.09, "avg1": 0.08, "avg7": 0.09, "avg30": 0.11, "updated_at": "2026-05-04T06:47:05.90041" } }, { "id": "pk_72046138a4c1908a9f27c93fdd8189ba4ac8e683efaed6b9161efcef129302394a9ec1d20d", "card_number": "001/165", "name": "Bulbasaur - 001/165", "variant": "Reverse Holofoil", "product_type": "card", "tcgplayer": { "market_price": 0.30, ... }, "cardmarket": null }, { "id": "pk_9a1c2e7f4b0d8365a1f2e9c7b4a08d6e1f3c5a7b9d0e2f4a6c8b0d2e4f6a8c0b", "card_number": null, "name": "Mew Booster Box", "variant": "products", "product_type": "sealed", "tcgplayer": { "market_price": 145.0, ... }, "cardmarket": null } ] } ``` ### Disambiguation (300): If `:setCode` matches multiple sets (e.g. same code in different languages), a `300` is returned. Pass the numeric `group_id` directly to disambiguate. *300 Multiple Choices* ```json { "disambiguation": true, "message": "Multiple sets found for 'SVI'. Use the numeric group_id to specify which one.", "matches": [ { "group_id": "22873", "set_code": "SVI" }, { "group_id": "23822", "set_code": "svI" } ] } ``` ### Error Codes: | HTTP | Condition | | --- | --- | | `400` | Invalid `source` value | | `401` | Missing or invalid API key | | `403` | Plan does not include this endpoint — upgrade to Pro or activate the 7-day trial | | `404` | Set not found, or `source=tcg` on a CM-only set | > For CM-only sets (`group_id < 0`): `tcgplayer: null` on all cards and `variant: null`. For Japanese sets, `cardmarket: null` is expected as CM only covers the EU market. Response is cached for 15 minutes. **Sealed Products:** sealed rows (`product_type: "sealed"`) stay in the list, priced via TCGPlayer only — `cardmarket` is always `null` for them, on both TCG and CM-only sets. See [Product Types](https://pokewallet.io/api-docs#product-types). ## Analytics Endpoints > **Authentication Required:** All Analytics endpoints require an API key. ### GET /analytics/top-cards (Pro) Get the top N cards ranked by current price or 7-day percentage growth, from TCGPlayer or CardMarket. > **Pro feature — 7-day free trial available.** Activate your free trial from the [dashboard](https://pokewallet.io/dashboard) to access this endpoint at no cost. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `metric` | string | Optional | Ranking metric. One of `price` (default) or `growth` (7-day % change). Any other value returns 400. | | `source` | string | Optional | Price source. One of `tcg` (default) or `cm`. Any other value returns 400. | | `limit` | number | Optional | Number of results to return (default: 20, max: 100). | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/analytics/top-cards?metric=growth&source=cm&limit=10" ``` ### Response Example — `metric=price&source=tcg`: *200 OK* ```json { "metric": "price", "source": "tcg", "top_cards": [ { "id": "pk_abc123", "card_info": { "name": "Charizard VSTAR", "set_name": "Brilliant Stars", "card_number": "018/172", "rarity": "Ultra Rare" }, "current_price": 42.50 } ] } ``` ### Response Example — `metric=growth&source=cm`: *200 OK* ```json { "metric": "growth", "source": "cm", "top_cards": [ { "id": "pk_def456", "card_info": { "name": "Charizard ex (SV3 125)", "set_code": "SV3", "card_number": "125" }, "current_price": 18.50, "change_7d": "+54.2%" } ] } ``` > `metric=growth` ranks by 7-day change. For `source=tcg` uses `price_7d` snapshots — cards without 7-day history are excluded. For `source=cm` uses CardMarket's native `avg7`. > **Sealed products excluded:** booster boxes, ETBs and displays are left out of both rankings — they'd otherwise dominate by price. See [Product Types](https://pokewallet.io/api-docs#product-types). ### Trial Response Headers: When accessing this endpoint during an active trial, two extra headers are included: ``` X-Trial-Expires-At: 2026-05-01T00:00:00.000Z X-Trial-Days-Remaining: 7 ``` ### Error Responses: | Status | Description | | --- | --- | | `403` — trial not activated | `{ "error": "Trial not activated", "redeem_url": "https://pokewallet.io/dashboard" }` | | `403` — trial expired | `{ "error": "Pro plan required", "upgrade_url": "https://pokewallet.io/pricing" }` | ## Images Endpoint > **Authentication Required:** The Images endpoint requires an API key. ### GET /images/:id Retrieve card images by card ID with automatic fallback system. Returns binary image data (JPEG, or WebP for localized images). Supports both TCG card IDs (`pk_xxx`) and CardMarket-only card IDs (no prefix). Localized card artwork is available in 5 European languages via the `lang` parameter. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Required | Card ID - Two formats supported: **TCG cards:** `pk_xxx` (with prefix); **CardMarket-only:** hexadecimal hash (no prefix) Obtained from `/search`, `/cards/:id`, or `/sets/:setCode` | | `size` | string | Optional | Image size: `low` (~500px, ~50KB) or `high` (~1000px, ~200KB). Default: `low` | | `lang` | string | Optional | Localized image language: `it`, `fr`, `de`, `es`, or `pt`. If a localized version exists, it is served as WebP; otherwise the request silently falls back to the card's default image (never a 404 because of the language). Check the card's `images.languages` field to know which languages are available. | ### Response Headers: - `Content-Type`: `image/jpeg`, or `image/webp` (localized images) - `X-Image-Lang`: language code of the served image (only present on localized responses, e.g. `it`) - `Cache-Control`: `public, max-age=31536000, immutable` ### Localized Images (Multi-Language): By default, each card is served with its original artwork: **English** for international sets, **Japanese** for Japanese sets. For English-language cards, localized European variants may also be available where a translated print exists: Italian (`it`), French (`fr`), German (`de`), Spanish (`es`) and Portuguese (`pt`). The recommended flow: 1. Fetch the card from `/cards/:id`, `/search`, or `/sets/:setCode` and read its `images.languages` array (e.g. `["en", "it", "de"]`). 2. If it contains your user's language, request `/images/:id?lang=xx` to get the localized WebP. 3. If it doesn't (or the localized file is missing), the API serves the card's default image (English or Japanese) — requests with `lang` are always safe. > **Backward Compatible:** requests without `lang` behave exactly as before. The `X-Image-Lang` header tells you when a localized WebP was served; its absence means the card's default image (English or Japanese) was returned. ### Example Requests: #### TCG Card (with pk_ prefix): *High Resolution TCG Card* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/images/pk_72046138a4c1908a9f27c93fdd8189ba4ac8e683efaed6b9161efcef129302394a9ec1d20d?size=high" \ --output pikachu_tcg.jpg ``` #### Localized Card Image (Italian): *Localized Card Image* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/images/pk_72046138a4c1908a9f27c93fdd8189ba4ac8e683efaed6b9161efcef129302394a9ec1d20d?size=high&lang=it" \ --output pikachu_it.webp ``` #### CardMarket-Only Card (no prefix): *CardMarket-Only Card Image* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/images/8eb728bd59d4e1a0d94c354e4cc65a7465b55cfa4261bfa93301faa5ec921f97?size=high" \ --output cubone_v1.jpg ``` > **Unique IDs for Variants:** Each CardMarket variant (V1, V2, etc.) has its own unique ID, so you don't need to use a `set` parameter for disambiguation. The ID itself uniquely identifies the exact card variant you want. ### Example Response (Headers): ``` HTTP/1.1 200 OK Content-Type: image/jpeg Content-Length: 123456 Cache-Control: public, max-age=31536000, immutable [Binary image data] ``` ### Example Response (Localized, Headers): ``` HTTP/1.1 200 OK Content-Type: image/webp Content-Length: 98765 X-Image-Lang: it Cache-Control: public, max-age=31536000, immutable [Binary image data] ``` ## Code Examples *JavaScript (Fetch)* ```javascript const API_KEY = process.env.POKEWALLET_API_KEY; const BASE_URL = 'https://api.pokewallet.io'; async function searchCards(query) { const response = await fetch(`${BASE_URL}/search?q=${encodeURIComponent(query)}`, { headers: { 'X-API-Key': API_KEY } }); if (!response.ok) { if (response.status === 429) { throw new Error('Rate limit exceeded'); } throw new Error(`API error: ${response.status}`); } const data = await response.json(); return data; } async function getCardImage(cardId, size = 'high') { const url = `${BASE_URL}/images/${cardId}?size=${size}`; const response = await fetch(url, { headers: { 'X-API-Key': API_KEY } }); if (!response.ok) { throw new Error(`Failed to fetch image: ${response.status}`); } // Return blob for display or download const blob = await response.blob(); return blob; } // Usage - Search TCG cards searchCards('pikachu') .then(data => { console.log('TCG card results:', data); // IDs will have pk_ prefix }) .catch(error => console.error(error)); // Usage - Search CardMarket-only cards searchCards('cubone cbb3c') .then(data => { console.log('CardMarket-only results:', data); // IDs will NOT have pk_ prefix }) .catch(error => console.error(error)); // Usage - Get Image (TCG card with pk_ prefix) getCardImage('pk_72046138a4c1908a9f27c93fdd8189ba...', 'high') .then(blob => { const imageUrl = URL.createObjectURL(blob); document.querySelector('img').src = imageUrl; }) .catch(error => console.error(error)); // Usage - Get Image (CardMarket-only, no prefix) getCardImage('8eb728bd59d4e1a0d94c354e4cc65a74...', 'high') .then(blob => { const imageUrl = URL.createObjectURL(blob); document.querySelector('img').src = imageUrl; }) .catch(error => console.error(error)); ``` *Python (Requests)* ```python import os import requests API_KEY = os.getenv('POKEWALLET_API_KEY') BASE_URL = 'https://api.pokewallet.io' def search_cards(query): headers = { 'X-API-Key': API_KEY } response = requests.get( f'{BASE_URL}/search', params={'q': query}, headers=headers ) if response.status_code == 429: raise Exception('Rate limit exceeded') response.raise_for_status() return response.json() def get_card_image(card_id, size='high', set_code=None): headers = { 'X-API-Key': API_KEY } params = {'size': size} if set_code: params['set'] = set_code response = requests.get( f'{BASE_URL}/images/{card_id}', params=params, headers=headers ) if response.status_code == 429: raise Exception('Rate limit exceeded') response.raise_for_status() return response.content # Usage - Search try: data = search_cards('charizard ex') print(data) except Exception as e: print(f'Error: {e}') # Usage - Get Image try: image_data = get_card_image('pk_xxx', size='high', set_code='CBB3C') # Save to file with open('charizard.jpg', 'wb') as f: f.write(image_data) print('Image downloaded successfully') except Exception as e: print(f'Error: {e}') ``` *Node.js (Axios)* ```javascript const axios = require('axios'); const fs = require('fs'); const API_KEY = process.env.POKEWALLET_API_KEY; const BASE_URL = 'https://api.pokewallet.io'; async function searchCards(query) { try { const response = await axios.get(`${BASE_URL}/search`, { params: { q: query }, headers: { 'X-API-Key': API_KEY } }); return response.data; } catch (error) { if (error.response?.status === 429) { throw new Error('Rate limit exceeded'); } throw error; } } async function getCardImage(cardId, size = 'high', setCode = null) { try { const params = { size }; if (setCode) { params.set = setCode; } const response = await axios.get(`${BASE_URL}/images/${cardId}`, { params, headers: { 'X-API-Key': API_KEY }, responseType: 'arraybuffer' }); // Get image source const imageSource = response.headers['x-image-source']; console.log(`Image served from: ${imageSource}`); return response.data; } catch (error) { if (error.response?.status === 429) { throw new Error('Rate limit exceeded'); } throw error; } } // Usage - Search searchCards('charizard ex') .then(data => console.log(data)) .catch(error => console.error(error)); // Usage - Get Image getCardImage('pk_xxx', 'high', 'CBB3C') .then(imageBuffer => { fs.writeFileSync('charizard.jpg', imageBuffer); console.log('Image downloaded successfully'); }) .catch(error => console.error(error)); ``` *Go* ```go package main import ( "encoding/json" "fmt" "io" "net/http" "net/url" "os" ) const BaseURL = "https://api.pokewallet.io" func searchCards(query string) (map[string]interface{}, error) { apiKey := os.Getenv("POKEWALLET_API_KEY") params := url.Values{} params.Add("q", query) req, err := http.NewRequest("GET", BaseURL+"/search?"+params.Encode(), nil) if err != nil { return nil, err } req.Header.Set("X-API-Key", apiKey) client := &http.Client{} resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode == 429 { return nil, fmt.Errorf("rate limit exceeded") } body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } var result map[string]interface{} json.Unmarshal(body, &result) return result, nil } func getCardImage(cardID, size, setCode string) ([]byte, error) { apiKey := os.Getenv("POKEWALLET_API_KEY") params := url.Values{} params.Add("size", size) if setCode != "" { params.Add("set", setCode) } req, err := http.NewRequest("GET", BaseURL+"/images/"+cardID+"?"+params.Encode(), nil) if err != nil { return nil, err } req.Header.Set("X-API-Key", apiKey) client := &http.Client{} resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode == 429 { return nil, fmt.Errorf("rate limit exceeded") } if resp.StatusCode != 200 { return nil, fmt.Errorf("failed to fetch image: %d", resp.StatusCode) } imageData, err := io.ReadAll(resp.Body) if err != nil { return nil, err } return imageData, nil } func main() { // Search example data, err := searchCards("charizard ex") if err != nil { fmt.Println("Error:", err) return } fmt.Println(data) // Image example imageData, err := getCardImage("pk_xxx", "high", "CBB3C") if err != nil { fmt.Println("Error:", err) return } // Save to file err = os.WriteFile("charizard.jpg", imageData, 0644) if err != nil { fmt.Println("Error saving image:", err) return } fmt.Println("Image downloaded successfully") } ``` ## Error Handling The API uses standard HTTP status codes to indicate success or failure: - **200 OK** — Request successful - **400 Bad Request** — Invalid parameters or malformed request - **401 Unauthorized** — Missing or invalid API key - **403 Forbidden** — Paid endpoint without the required plan or an active trial: Pro for Pokémon and One Piece, Ultra for the other games. The body includes `redeem_url` (trial not activated yet) or `upgrade_url` (trial expired). - **404 Not Found** — Card, set or image does not exist - **405 Method Not Allowed** — The API only accepts `GET` requests. - **409 Conflict** — `/sets/:setCode/image`: the set code matches several sets. Retry with `?language=` or the numeric `set_id`. - **429 Too Many Requests** — Rate limit exceeded - **500 Internal Server Error** — Something went wrong on our side - **502 Bad Gateway** — An image could not be fetched from its source. Temporary: retry later. ### Errors on game endpoints (`/mtg`, `/ygo`, …) | Status | `error` | When | | --- | --- | --- | | 400 | `Invalid or corrupted card ID` | ID is neither `_…` nor 64 hex, or belongs to another game | | 400 | `Query parameter required` | `q` missing, shorter than 2 or longer than 100 characters | | 400 | `Search query rejected` | `q` contains SQL-like text: rephrase it | | 400 | `Invalid or corrupted card ID` + `did_you_mean` | The ID belongs to another game (e.g. a `lor_…` ID on `/mtg/cards`): `did_you_mean` has the right path | | 404 | `Set not found` + `suggestions` | No set with that `set_id`/`set_code`. If you wrote the set *name*, `suggestions` lists the matching sets with their `set_id` | | 404 | `Card not found`, `Image not found` | Card or image does not exist | | 502 | `Image not available` | Image source temporarily unreachable | | 503 | `Search temporarily unavailable` | The search took too long under load. Retry after the seconds in the `Retry-After` header, or use more specific words | ### Error Response Format Every error has `error` (short, stable) and `message` (what to fix). When the API can tell what you meant, `did_you_mean` contains the corrected path: ``` // GET /magic/sets { "error": "Endpoint not found", "message": "Did you mean /mtg/sets?", "did_you_mean": "/mtg/sets", "docs": "https://pokewallet.io/api-docs" } ``` Authentication errors (401) also include an `example` request. A trailing slash is ignored: `/sets/` and `/sets` are the same endpoint. ## Best Practices ### Use Environment Variables Never hardcode API keys. Always use environment variables or secure secret management. ### Handle Rate Limits Gracefully Implement exponential backoff when you receive a 429 response. Check rate limit headers to avoid hitting limits. ### Cache Results Cache API responses when appropriate to reduce requests and improve performance. ### Use Search Endpoint Always use `/search` for the most complete and accurate data. ### Monitor Your Usage Check your dashboard regularly to track API usage and avoid unexpected rate limit hits. ### Error Handling Always implement proper error handling for network failures, rate limits, and invalid responses. > **Security Reminder:** Keep your API keys secure. If you suspect a key has been compromised, revoke it immediately from your dashboard and generate a new one. ## Pokémon TCG API FAQ ### Is the Pokémon TCG API free? Yes. The free tier (100 requests/hour, 1,000/day) covers sets, set cards, card details, search and images, with TCGPlayer and CardMarket prices. Price history, prices by set, set statistics, completion value, trending sets and top cards need the Pro plan (€20/month); a 7-day free trial starts from the dashboard. ### Does the Pokémon TCG API include CardMarket prices? Yes. Cards return TCGPlayer (USD) prices for each variant (Normal, Holofoil, Reverse Holofoil, 1st Edition…) and CardMarket (EUR) prices for normal and holo. Cards sold only on CardMarket, such as Japanese sets and European promos, have an id without the pk_ prefix. ### Can I get the price history of a Pokémon card? Yes. GET /cards/:id/price-history returns TCGPlayer and CardMarket price snapshots with the percentage change over 7, 14, 30, 60 and 120 days. It needs the Pro plan (€20/month) or its 7-day trial. ### Can I use the same API key for other games? Yes. One PokéWallet API key works for all 12 games, Pokémon and One Piece included, and the rate limits are shared across them. ## Need Help? If you have questions or run into issues, we're here to help! [Go to Dashboard](https://pokewallet.io/dashboard) [Contact Support](mailto:hello@pokewallet.io) [Join Discord](https://discord.gg/znDxEjmDVP) --- # One Piece API Documentation Source: https://pokewallet.io/api-docs/one-piece Complete REST reference for the One Piece Card Game API. Real-time prices from TCGPlayer and CardMarket, full card and set database for all OPCG sets. In short The One Piece Card Game API returns every OPCG set and card, from OP01 to the latest releases, with TCGPlayer (USD) and CardMarket (EUR) prices refreshed daily. Sets, cards, search and images are free (100 requests/hour); prices by set, set statistics and the other analytics endpoints need the Pro plan (€20/month) or its 7-day trial. At a glance - **Base path:** `https://api.pokewallet.io/op` - **Sets:** All OPCG sets, from OP01 to the latest releases - **Card IDs:** `op_` + hex - **Prices:** TCGPlayer (USD) and CardMarket (EUR), refreshed daily - **Free on every plan:** Sets, set cards, card details, search and images - **Pro plan or 7-day trial:** Prices by set, set statistics, completion value, trending sets and top cards - **API key:** The same key as the Pokémon API and the other games, with shared rate limits Updated Oct 19, 2026 ## Quick Start Start fetching One Piece card data in seconds: ### Get an API Key Sign up for free to get your API key. No credit card required. [Sign Up Free](https://pokewallet.io/auth/login?source=one_piece) ### Make Your First Request Fetch all One Piece sets with a single call: *cURL* ```bash curl https://api.pokewallet.io/op/sets \ -H "X-API-Key: YOUR_API_KEY" ``` ### Fetch a Specific Set Get all cards in OP01 — Romance Dawn: *cURL* ```bash curl https://api.pokewallet.io/op/sets/OP01 \ -H "X-API-Key: YOUR_API_KEY" ``` > **One Piece Card Game PRO endpoints: Pro or Ultra plan** > > Pro (€20/month) covers Pokémon and One Piece only. Ultra (€29/month) includes everything in Pro plus the paid endpoints of the other 10 games: Magic, Yu-Gi-Oh!, Lorcana and more. > > [Compare plans →](https://pokewallet.io/pricing) ## Sets Endpoints ### GET /op/sets Returns all One Piece sets ordered by release date. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `language` | string | Optional | Filter by language: `en` or `jp` | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/op/sets?language=en" ``` ### Response Example: *200 OK* ```json { "success": true, "data": [ { "name": "Romance Dawn", "set_code": "OP01", "group_id": "3188", "language": "en", "release_date": "2022-12-02" }, { "name": "Paramount War", "set_code": "OP02", "group_id": "3189", "language": "en", "release_date": "2023-03-10" } ], "total": 100 } ``` > `group_id` is the numeric identifier for the set in the DB. Positive = TCG set, negative = CM-only set (no TCGPlayer data). Set images are not available for One Piece sets. ### GET /op/sets/:setCode Returns a paginated card list for a specific One Piece set. ### Path Parameter: | Value | Behavior | | --- | --- | | `OP01` | Lookup by `set_code` (case-insensitive) | | `3188` | Lookup by numeric `group_id` | | `-8` | CM-only set (negative group_id) | | `EB01` | Fuzzy fallback: automatically tries `EB-01` | ### Query Parameters: | Parameter | Default | Max | | --- | --- | --- | | `page` | 1 | — | | `limit` | 50 | 200 | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/op/sets/OP01?page=1&limit=50" ``` ### Response Example: *200 OK* ```json { "success": true, "set": { "set_code": "OP01", "group_id": "3188", "name": "Romance Dawn", "language": "en", "release_date": "2022-12-02" }, "total": 50, "page": 1, "limit": 50, "data": [ { "id": "op_3f8a12c4e9b7d02f...", "card_number": "OP01-001", "name": "Roronoa Zoro", "clean_name": "Roronoa Zoro", "sub_type_name": "Normal", "rarity": "L", "card_type": "Leader", "ext_color": "Red", "ext_cost": null, "ext_power": "5000", "ext_life": "5", "ext_subtypes": "Straw Hat Crew;Supernovas", "ext_attribute": "Slash", "ext_counterplus": null, "ext_description": "[DON!! x1] ...", "tcgplayer": { "url": "https://www.tcgplayer.com/product/...", "prices": { "low_price": 1.20, "market_price": 1.76, "high_price": 3.50 } }, "cardmarket": { "product_name": "Roronoa Zoro (OP01-001)", "product_url": "https://www.cardmarket.com/...", "prices": { "avg": 1.64, "low": 0.50, "trend": 1.70 } } } ] } ``` > **CM-only sets** (negative `group_id`): cards have `tcgplayer: null` and no `ext_*` fields. `total` is the full card count for the set (not just the current page). Each card also includes a `clean_name` field (normalized name without special characters). ## Cards Endpoints ### GET /op/cards/:id Returns details for a single One Piece card. The `id` must use the `op_` prefix. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `id` | string | Required | Card ID with `op_` prefix. Obtained from `/op/search`, `/op/sets/:setCode`, or `/op/prices`. | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/op/cards/op_3f8a12c4e9b7d02f..." ``` ### Response Example: *200 OK* ```json { "id": "op_3f8a12c4e9b7d02f...", "card_number": "OP01-001", "name": "Roronoa Zoro", "clean_name": "Roronoa Zoro", "sub_type_name": "Normal", "rarity": "L", "card_type": "Leader", "ext_color": "Red", "ext_cost": null, "ext_power": "5000", "ext_life": "5", "ext_subtypes": "Straw Hat Crew;Supernovas", "ext_attribute": "Slash", "ext_counterplus": null, "ext_description": "[DON!! x1] [Activate: Main] ...", "tcgplayer": { "url": "https://www.tcgplayer.com/product/...", "prices": { "low_price": 1.20, "market_price": 1.76, "high_price": 3.50 } }, "cardmarket": { "product_name": "Roronoa Zoro (OP01-001)", "product_url": "https://www.cardmarket.com/...", "prices": { "avg": 1.64, "low": 0.50, "trend": 1.70 } } } ``` ### Error Codes: | HTTP | Condition | | --- | --- | | `400` | ID missing `op_` prefix | | `400` | Corrupted or undecryptable payload | | `404` | Card not found in DB | > **CM-only cards** (`group_id < 0`): `tcgplayer: null`, all `ext_*` fields are `null`. **SP reprints**: cards whose `card_number` belongs to a different set return `cardmarket: null` to avoid cross-set price collisions. ## Search Endpoints ### GET /op/search Full-text search on One Piece card name and `card_number`. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | Required | `ILIKE %q%` on card name and `card_number` (e.g. `zoro`, `OP01-001`) | | `page` | number | Optional | Page number (default: 1, min: 1) | | `limit` | number | Optional | Results per page (default: 20, max: 100) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/op/search?q=zoro&page=1&limit=20" ``` ### Response Example: *200 OK* ```json { "success": true, "data": [ { "id": "op_3f8a12c4e9b7d02f...", "card_number": "OP01-001", "name": "Roronoa Zoro", "sub_type_name": "Normal", "rarity": "L", "card_type": "Leader", "tcgplayer": { "url": "https://www.tcgplayer.com/product/...", "prices": { "low_price": 1.20, "market_price": 1.76, "high_price": 3.50 } }, "cardmarket": { "product_name": "Roronoa Zoro (OP01-001)", "product_url": "https://www.cardmarket.com/...", "prices": { "avg": 1.64, "low": 0.50, "trend": 1.70 } } } ], "total": 12, "page": 1, "limit": 20 } ``` > **Known limitation:** Queries containing apostrophes (e.g. `d'artagnan`) return 0 results due to `ILIKE` handling of special characters. CM-only cards are not indexed for name search — only TCG cards appear in results. ## Prices Endpoints ### GET /op/prices?set_code={set_code} (PRO) Raw prices for an entire One Piece set, all variants, no filtering. The set is identified via **query parameters** — `set_code` or `group_id` — not as a path segment. At least one is required. > **Query parameters only.** `/op/prices?set_code=OP01` ✓ `/op/prices/OP01` ✗ > **Pro feature — 7-day free trial available.** Activate your free trial from the [dashboard](https://pokewallet.io/dashboard) to access this endpoint at no cost. ### Parameters: | Parameter | Type | Required | Examples | | --- | --- | --- | --- | | `set_code` | string | One of these | `OP01`, `EB-01`, `EB01` (fuzzy → `EB-01`) | | `group_id` | number | One of these | `3188`, `-8` (CM-only set) | ### Example Request: *cURL* ```bash # by set_code (case-insensitive) curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/op/prices?set_code=OP01" # by group_id (numeric) curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/op/prices?group_id=3188" ``` ### Response Example: *200 OK* ```json { "success": true, "group_id": "3188", "total": 159, "data": [ { "card_number": "OP01-001", "name": "Roronoa Zoro (001)", "variant": "Normal", "tcgplayer": { "low_price": 1.20, "market_price": 1.76, "high_price": 3.50, "mid_price": 2.10, "direct_low_price": 1.50, "updated_at": "2026-05-14T00:00:00Z" }, "cardmarket": { "avg": 1.64, "low": 0.50, "trend": 1.70, "avg1": 1.60, "avg7": 1.65, "avg30": 1.70, "updated_at": "2026-05-14T00:00:00Z" } }, { "card_number": "OP01-001", "name": "Roronoa Zoro (001) (Foil)", "variant": "Foil", "tcgplayer": { "low_price": 3.50, "market_price": 4.20, "high_price": 6.00, "...": "..." }, "cardmarket": { "avg": 3.80, "low": 2.50, "trend": 3.90, "...": "..." } } ] } ``` ### Error Codes: | HTTP | Condition | | --- | --- | | `400` | Neither `set_code` nor `group_id` provided | | `404` | Set not found | > For CM-only sets (`group_id < 0`): `tcgplayer: null` on all cards and `variant: null` (CM does not expose `sub_type_name`). The `cardmarket` object is always present with real prices. ## One Piece Pro endpoints Available on Pro, Ultra and Business plans, or during the 7-day trial. Same rules and response format as the Pokémon and other games' endpoints of the same name. Sealed products (booster boxes, packs) are excluded from statistics, completion value and rankings; DON!! cards count as cards. | Endpoint | What it returns | | --- | --- | | `GET /op/sets/:set/statistics` | Price statistics and rarity breakdown of a set. `:set` = set code (`OP01`) or group id. `?variant=normal\|foil` | | `GET /op/sets/:set/completion-value` | Cost of one copy of every card in the set, TCGPlayer (USD) and CardMarket (EUR) | | `GET /op/sets/trending` | Sets whose CardMarket prices moved most: 7-day average against 30-day average, cards from 1 € up. `?period=7d` `?limit=` (max 50) | | `GET /op/analytics/top-cards` | Most expensive cards, or fastest-growing on CardMarket. `?metric=price\|growth` `?source=tcg\|cm` (growth: `cm` only) `?limit=` (max 100) | > Price history is a Pokémon feature: `/op/cards/:id/price-history` answers 404. Current prices are in `/op/cards/:id` and `/op/prices`. ### Statistics *200 OK — /op/sets/OP01/statistics* ```json { "set_info": { "name": "Romance Dawn", "set_code": "OP01", "set_id": "3188", "total_cards": 159 }, "price_statistics": { "tcgplayer": { "avg_market_price": "53.37", "min_price": 0.07, "max_price": 3998.74, "most_expensive": { "id": "op_7816ebfb908c6a34cd6feabbf11c84943582bbc7d8109009e47917e7e499e84b245a31a536a5865d5663ccaa201c9f7f", "name": "Shanks (Parallel) (Manga) (Alternate Art)", "price": 3998.74 } }, "cardmarket": { "avg_price": "59.17", "min_price": 0.03, "max_price": 4566.67, "most_expensive": { "id": "op_7816ebfb908c6a34cd6feabbf11c84943582bbc7d8109009e47917e7e499e84b245a31a536a5865d5663ccaa201c9f7f", "name": "Shanks (Parallel) (Manga) (Alternate Art)", "price": 4566.67 }, "trend_direction": "up" } }, "rarity_breakdown": { "L": 16, "R": 35, "UC": 32, "C": 49, "SR": 20, "SEC": 5, "DON!!": 2 } } ``` ### Completion value *200 OK — /op/sets/OP01/completion-value* ```json { "set_info": { "name": "Romance Dawn", "set_code": "OP01", "set_id": "3188", "total_cards": 159 }, "completion_cost": { "tcgplayer": { "currency": "USD", "low_estimate": 7238.83, "market_estimate": 8485.5, "high_estimate": 38920.95 }, "cardmarket": { "currency": "EUR", "low_estimate": 6489.33, "avg_estimate": 9408, "trend_estimate": 9123.63 }, "note": "One copy per card (base finish). TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available." }, "breakdown_by_rarity": { "L": { "count": 16, "total_cost": 2758.99 }, "R": { "count": 35, "total_cost": 567.22 }, "UC": { "count": 32, "total_cost": 47.61 }, "C": { "count": 49, "total_cost": 21.23 }, "SR": { "count": 20, "total_cost": 859.62 }, "SEC": { "count": 5, "total_cost": 4225.13 }, "DON!!": { "count": 2, "total_cost": 5.7 } } } ``` ### Trending sets (first entry) *200 OK — /op/sets/trending?limit=3* ```json { "period": "7d", "trending_sets": [ { "set_name": "Extra Booster: Anime 25th Collection (Japanese)", "set_code": "EB-02-JP", "set_id": "-7", "card_count": 46, "cardmarket": { "price_change": "+91.3%", "avg_price_current": 208.2, "avg_price_previous": 108.85, "top_movers": [ { "name": "Monkey.D.Luffy (OP05-060)", "change": "+197.9%" }, { "name": "Tony Tony.Chopper (OP08-001)", "change": "+191.2%" }, { "name": "Hannyabal (EB01-021)", "change": "+163.1%" } ] }, "tcgplayer": null } ] } ``` ### Top cards by price (first entry) *200 OK — /op/analytics/top-cards?limit=3* ```json { "metric": "price", "source": "tcg", "top_cards": [ { "id": "op_4efc83a71371699af41ffc592c2c1c2076567bcff30c224518260e7ad036150f0156f916c677e9abc3804cefaaf233c9c9", "card_info": { "name": "Monkey.D.Luffy (119) (SP) (Gold)", "clean_name": "Monkey.D.Luffy (119) (SP) (Gold)", "set_name": "A Fist of Divine Speed", "set_code": "OP11", "set_id": "24241", "card_number": "OP05-119", "rarity": "SEC", "card_type": null, "product_type": "card", "variants": [ "Foil" ], "card_text": null }, "current_price": 13000 } ] } ``` ## Images Endpoint ### GET /images/:id Returns card images served via CDN. Use the card's `id` as the path parameter. ### Path Parameters | Parameter | Type | Description | | --- | --- | --- | | `id` | string | Card identifier (e.g. `OP01-001`) | ### Example Request: *cURL* ```bash curl https://api.pokewallet.io/images/OP01-001 \ -H "X-API-Key: YOUR_API_KEY" ``` > Images are served as binary content. Use the `image_url` field returned by card endpoints to construct the URL directly. ## Code Examples ### JavaScript / Node.js *javascript* ```javascript const API_KEY = 'YOUR_API_KEY'; const BASE_URL = 'https://api.pokewallet.io'; // Fetch all OP sets const res = await fetch(`${BASE_URL}/op/sets`, { headers: { 'X-API-Key': API_KEY } }); const { sets } = await res.json(); // Get a specific set const setRes = await fetch(`${BASE_URL}/op/sets/OP01`, { headers: { 'X-API-Key': API_KEY } }); const setData = await setRes.json(); // Search for a card const searchRes = await fetch( `${BASE_URL}/op/search?q=Luffy`, { headers: { 'X-API-Key': API_KEY } } ); const { results } = await searchRes.json(); ``` ### Python *python* ```python import requests API_KEY = 'YOUR_API_KEY' BASE_URL = 'https://api.pokewallet.io' HEADERS = {'X-API-Key': API_KEY} # Fetch all OP sets sets = requests.get(f'{BASE_URL}/op/sets', headers=HEADERS).json() # Get bulk prices for OP07 prices = requests.get( f'{BASE_URL}/op/prices', params={'set_code': 'OP07'}, headers=HEADERS ).json() ``` ## One Piece Card Game API FAQ ### Is there a One Piece Card Game API? Yes. BerryWallet, the One Piece Card Game API of PokéWallet, is a REST API with TCGPlayer and CardMarket prices for every English and Japanese set from OP01 Romance Dawn onward. The free tier needs no credit card. ### Is there a free One Piece card price API? Yes. The free tier (100 requests/hour, 1,000/day) opens /op/sets, /op/cards/:id, /op/search and the card images, with TCGPlayer and CardMarket prices refreshed daily. Prices by set, set statistics, completion value, trending sets and top cards need the Pro plan (€20/month) or its 7-day trial. ### Does the One Piece Card Game API include CardMarket prices? Yes. Every card returns its TCGPlayer (USD) and CardMarket (EUR) prices where that market lists it, refreshed daily. Card ids start with op_ and work with /op/cards/:id. ### Is BerryWallet the same as the PokéWallet One Piece API? Yes. BerryWallet is the One Piece Card Game API of PokéWallet: same account, same API key and the /op/ endpoints documented on this page. ### Can I use the same API key for other games? Yes. One PokéWallet API key works for all 12 games, Pokémon and One Piece included, and the rate limits are shared across them. --- # Magic: The Gathering API Documentation Source: https://pokewallet.io/api-docs/magic-the-gathering REST reference for the Magic: The Gathering API: sets, cards, search and images, with prices from TCGPlayer and CardMarket. Same API key as the Pokémon and One Piece APIs. In short The Magic: The Gathering API returns 514 sets with their cards, search and images, and TCGPlayer (USD) and CardMarket (EUR) prices refreshed daily. These endpoints are free (100 requests/hour) with the same key as the other 11 games; prices by set and set analytics need the Ultra plan (€29/month) or its 7-day trial. At a glance - **Base path:** `https://api.pokewallet.io/mtg` - **Sets:** 514 Magic: The Gathering sets - **Card IDs:** `mtg_` + hex for cards on TCGPlayer; 64 hex characters for CardMarket-only cards - **Prices:** TCGPlayer (USD) for every finish and CardMarket (EUR) for `normal` and `foil`, refreshed daily - **Free on every plan:** Sets, set cards, card details, search and images - **Ultra plan or 7-day trial:** Prices by set, set statistics, completion value, trending sets and top cards - **API key:** The same key as the Pokémon and One Piece APIs, with shared rate limits Updated Oct 19, 2026 ## Quick Start Get started with PokéWallet API in 4 simple steps: ### Create an Account Sign up for free to start using the API. Upgrade anytime from your dashboard. [Sign Up Now](https://pokewallet.io/auth/login?source=pokemon) ### Generate an API Key Create your first API key from the dashboard. ### Make Your First Request Start querying the API with your key. *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/mtg/sets" ``` ### Join the Discord Community Stay up to date with new features, ask for help, and connect with other developers. [Join Discord](https://discord.gg/znDxEjmDVP) > **Magic: The Gathering PRO endpoints: Ultra plan required** > > The **Pro plan does not include them**: Pro covers Pokémon and One Piece only. Ultra (€29/month) includes everything in Pro plus the paid endpoints of **all 12 games**. Free endpoints (sets, cards, search, images) work on every plan. > > [Compare plans →](https://pokewallet.io/pricing) ## Magic: The Gathering All Magic: The Gathering endpoints live under `/mtg`. Same API key, same rate limits and the same response format as the Pokémon endpoints. ### Card IDs | Format | Example | Used for | | --- | --- | --- | | `mtg_` + hex | `mtg_2c2bae815d1b5d823542…` | Every card with a TCGPlayer product, even if it also has CardMarket data | | 64 hex characters, no prefix | `e26f12b8b1fabf19…` | Cards that exist only on CardMarket | > A `mtg_…` ID only works under `/mtg/`. Finishes of the same product (Normal, Foil, …) are one card with one ID; each finish has its own TCGPlayer price. If you request a card by its CardMarket ID and it is linked to a TCGPlayer product, the response uses the canonical `mtg_…` ID. ### Response Format Same shape as the Pokémon API: `card_info`, `images`, `tcgplayer.prices` and `cardmarket.prices` as arrays, `pagination`, errors as `{ "error", "message" }`. Differences: | Field | Magic: The Gathering | | --- | --- | | Game fields in `card_info` | Instead of Pokémon's `hp`, `stage`, `attacks`…, the game's own fields in snake_case (present when the card has them): `sub_type`, `flavor_text`, `p`, `t`, `upc` | | `card_type`, `card_text` | Filled from the game's card type and rules text. `card_text` may contain HTML (``, ``…) as provided by TCGPlayer. | | `card_info.variants`, `card_info.set_id` | Always present, on every endpoint | | `product_type` | `"card"`, `"sealed"` or `null` when unknown — see [Data Notes](https://pokewallet.io/api-docs/magic-the-gathering#mtg-data-notes) | | `release_date` | ISO format, e.g. `"2025-03-07T00:00:00"` (Pokémon uses `"16th June, 2023"`) | | `images.languages` | `["en"]`, or `[]` when there is no image | ## Magic: The Gathering Endpoints ### GET /mtg/sets All Magic: The Gathering sets. ### Response Fields: | Field | Type | Description | | --- | --- | --- | | `name` | string | Set name | | `set_code` | string \| null | Short code. **Not unique**: several sets can share it. | | `set_id` | string | Unique set identifier. Negative for sets that exist only on CardMarket. | | `card_count` | integer | Cards in the set (sealed products excluded). Omitted, not 0, if temporarily unavailable. | | `sealed_count` | integer | Sealed products in the set (booster boxes, displays, decks). Omitted, not 0, if temporarily unavailable. | | `language` | string \| null | Set language | | `release_date` | string \| null | ISO date | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/mtg/sets" ``` ### Response Example (first two sets): *200 OK* ```json { "success": true, "data": [ { "name": "10th Edition", "set_code": "10E", "set_id": "1", "card_count": 389, "sealed_count": 9, "language": "eng", "release_date": "2007-07-13T00:00:00" }, { "name": "2021 Lunar New Year", "set_code": "pl21", "set_id": "-42", "card_count": 1, "sealed_count": 0, "language": "eng", "release_date": null } ], "total": 514 } ``` ### GET /mtg/sets/:set Cards of one set, paginated. Prices are empty in set listings, as on the Pokémon API: use `/mtg/cards/:id` for prices. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `set` | string | Required | `set_id` (recommended, always unique) or `set_code` (exact match, case-insensitive) | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 50, max: 200) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/mtg/sets/24684?limit=1" ``` ### Response Example: *200 OK* ```json { "success": true, "set": { "name": "Reality Fracture", "set_code": "FRA", "set_id": "24684", "total_cards": 782, "language": "eng", "release_date": "2026-10-02T00:00:00" }, "cards": [ { "id": "mtg_2c2bae815d1b5d8235423b0c89f43f5383afbff3adbe2b6a895216ea36ddb4f83d2fec580f087b6707d9", "card_info": { "name": "Emrakul, the Exigent Doom", "clean_name": "Emrakul the Exigent Doom", "set_name": "Reality Fracture", "set_code": "FRA", "set_id": "24684", "card_number": "1", "rarity": "M", "card_type": null, "product_type": "card", "variants": [ "Normal", "Foil" ], "card_text": "When you cast this spell, untap all lands you control.
\r\nFlying, trample
\r\nWard—Sacrifice three permanents.
\r\n3, Exile this card from your hand: Target land gains \"T: Add CC\" until this card is cast from exile. You may cast this card for as long as it remains exiled.", "p": "12", "t": "12", "sub_type": "Legendary Creature — Eldrazi" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/716715/magic-reality-fracture-emrakul-the-exigent-doom" }, "cardmarket": { "product_name": "Emrakul, the Exigent Doom", "prices": [], "product_url": "https://www.cardmarket.com/en/Magic/Products/Singles/Reality-Fracture/Emrakul-the-Exigent-Doom" } } ], "pagination": { "page": 1, "limit": 1, "total": 782, "total_pages": 782 } } ``` ### Disambiguation Response: When a `set_code` is shared by several sets, the API returns the candidates instead of a set (status 200, as on the Pokémon API). Call again with the `set_id` you need. *200 OK — /mtg/sets/MOC* ```json { "disambiguation": true, "message": "Multiple sets found for set_code 'MOC'. Use set_id to specify which one.", "matches": [ { "set_id": "22979", "set_code": "MOC", "name": "Commander: March of the Machine", "language": "eng", "release_date": "2023-04-21T00:00:00" }, { "set_id": "23109", "set_code": "MOC", "name": "Planechase: March of the Machine", "language": "eng", "release_date": "2023-04-21T00:00:00" } ], "total": 2 } ``` ### GET /mtg/cards/:id Full card with prices. `id` is a `mtg_…` ID or a 64-character CardMarket ID. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/mtg/cards/mtg_2c2bae815d1b5d8235423b0c89f43f5383afbff3adbe2b6a895216ea36ddb4f83d2fec580f087b6707d9" ``` ### Response Example: *200 OK* ```json { "id": "mtg_2c2bae815d1b5d8235423b0c89f43f5383afbff3adbe2b6a895216ea36ddb4f83d2fec580f087b6707d9", "card_info": { "name": "Emrakul, the Exigent Doom", "clean_name": "Emrakul the Exigent Doom", "set_name": "Reality Fracture", "set_code": "FRA", "set_id": "24684", "card_number": "1", "rarity": "M", "card_type": null, "product_type": "card", "variants": [ "Normal", "Foil" ], "card_text": "When you cast this spell, untap all lands you control.
\r\nFlying, trample
\r\nWard—Sacrifice three permanents.
\r\n3, Exile this card from your hand: Target land gains \"T: Add CC\" until this card is cast from exile. You may cast this card for as long as it remains exiled.", "p": "12", "t": "12", "sub_type": "Legendary Creature — Eldrazi" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 28.08, "mid_price": 32.62, "high_price": 58.92, "market_price": 29.08, "direct_low_price": 29.48, "updated_at": "2026-09-30T20:37:36.812579+00:00", "sub_type_name": "Normal" }, { "low_price": 33.01, "mid_price": 42.3, "high_price": 94.97, "market_price": 39.85, "direct_low_price": null, "updated_at": "2026-09-30T20:37:36.812579+00:00", "sub_type_name": "Foil" } ], "url": "https://www.tcgplayer.com/product/716715/magic-reality-fracture-emrakul-the-exigent-doom" }, "cardmarket": { "product_name": "Emrakul, the Exigent Doom", "prices": [ { "variant_type": "normal", "avg": 34.79, "low": 14.3, "trend": 16.27, "avg1": 29.45, "avg7": 31.97, "avg30": 31.97, "updated_at": "2026-09-30T14:49:39.980453+00:00" }, { "variant_type": "foil", "avg": 59.99, "low": 19.5, "trend": 18.78, "avg1": 54.99, "avg7": 58.32, "avg30": 58.32, "updated_at": "2026-09-30T14:49:39.980453+00:00" } ], "product_url": "https://www.cardmarket.com/en/Magic/Products/Singles/Reality-Fracture/Emrakul-the-Exigent-Doom" } } ``` > One entry in `tcgplayer.prices` per finish, identified by `sub_type_name`, and one entry in `cardmarket.prices` per finish, identified by `variant_type` (`normal`, `foil`). `updated_at` is when that price last changed, not when it was last checked. A CardMarket-only card has `tcgplayer: null` and empty `variants`. ### GET /mtg/search Search cards by name or card number. Results have the same shape as `/mtg/cards/:id`, prices included. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | Required | 2–100 characters. Card name (all words, any order) or card number | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 20, max: 100) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/mtg/search?q=Emrakul&limit=2" ``` ### Response Example (`results` omitted): *200 OK* ```json { "query": "Emrakul", "results": [ { "id": "mtg_a226650648bfbc74a51c389551e67786144bc98133f32b8812acf122033bde69de7cce366aa417", "card_info": { "name": "Emrakul, the Aeons Torn", "clean_name": "Emrakul the Aeons Torn", "set_name": "Pro Tour Promos", "set_code": "PTP", "set_id": "93", "card_number": "1", "rarity": "P", "card_type": null, "product_type": "card", "variants": [ "Foil" ], "card_text": "Emrakul, the Aeons Torn can't be countered. \r\n
\r\nWhen you cast Emrakul, take an extra turn after this one.\r\n
\r\nFlying, protection from colored spells, Annihilator 6 \r\n
\r\nWhen Emrakul is put into a graveyard from anywhere, its owner shuffles his or her graveyard into his or her library.", "p": "15", "t": "15", "sub_type": "Legendary Creature — Eldrazi" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 104.13, "mid_price": 124.86, "high_price": 231.5, "market_price": 123.86, "direct_low_price": null, "updated_at": "2026-09-30T20:37:32.272128+00:00", "sub_type_name": "Foil" } ], "url": "https://www.tcgplayer.com/product/128632/magic-pro-tour-promos-emrakul-the-aeons-torn" }, "cardmarket": { "product_name": "Emrakul, the Aeons Torn", "prices": [ { "variant_type": "normal", "avg": null, "low": 36.05, "trend": null, "avg1": null, "avg7": null, "avg30": null, "updated_at": "2026-09-30T14:49:31.144302+00:00" }, { "variant_type": "foil", "avg": 48.99, "low": 36.05, "trend": 47.18, "avg1": 42.98, "avg7": 46.05, "avg30": 51.83, "updated_at": "2026-09-30T14:49:31.144302+00:00" } ], "product_url": "https://www.cardmarket.com/en/Magic/Products/Singles/Pro-Tour-Promos/Emrakul-the-Aeons-Torn" } } ], "pagination": { "page": 1, "limit": 2, "total": 53, "total_pages": 27 }, "metadata": { "total_count": 53, "tcg": 51, "cardmarket": 47, "tcg_only": 6, "cardmarket_only": 2, "both_sources": 45, "truncated": false } } ``` > `metadata.truncated: true` means more cards match than the search returns: add words to narrow it down. Words match anywhere in the name; a query shorter than 3 characters matches names and card numbers that **start** with it (`27` finds `27`, `027/264`, `0027`). Quotes are ignored; `*`, `%` and `_` are plain text, not wildcards. ### GET /mtg/images/:id The card image, one resolution (`X-Image-Size: unsized`): the `size` parameter of the Pokémon image endpoint does not apply. Cached for 24 hours. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/mtg/images/mtg_2c2bae815d1b5d8235423b0c89f43f5383afbff3adbe2b6a895216ea36ddb4f83d2fec580f087b6707d9" \ --output card ``` ## Ultra endpoints Available on Ultra and Business plans, or during the 7-day trial. The Pro plan covers Pokémon and One Piece only: with Pro these endpoints answer 403 with an `upgrade_url`. Ultra includes everything in Pro. Same parameters and response format as the Pokémon endpoints of the same name. | Endpoint | What it returns | | --- | --- | | `GET /mtg/prices/:set` | TCGPlayer and CardMarket prices for every card of a set, one row per finish. `?source=tcg\|cm` | | `GET /mtg/sets/:set/statistics` | Price statistics and rarity breakdown. Sealed products excluded. `?variant=normal\|foil` | | `GET /mtg/sets/:set/completion-value` | Cost of one copy of every card in the set. Sealed products excluded. | | `GET /mtg/sets/trending` | Sets whose CardMarket prices moved most: 7-day average against 30-day average, cards from 1 € up. `?period=7d` `?limit=` | | `GET /mtg/analytics/top-cards` | Most expensive cards, or fastest-growing on CardMarket (7-day average against 30-day average, cards from 1 € up; `current_price` is the 7-day average). `?metric=price\|growth` `?source=tcg\|cm` `?limit=` | > Price history is a Pokémon feature: for this game there is no `/cards/:id/price-history`. Current prices are in the card detail and in `/mtg/prices/:set`; `metric=growth` works with `source=cm` only, and trending supports `period=7d` only. ### GET /mtg/prices/:set (first rows) *200 OK* ```json { "success": true, "source": "both", "set_code": "FRA", "set_id": "24684", "data": [ { "id": "mtg_2c2bae815d1b5d8235423b0c89f43f5383afbff3adbe2b6a895216ea36ddb4f83d2fec580f087b6707d9", "card_number": "1", "name": "Emrakul, the Exigent Doom", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 28.08, "mid_price": 32.62, "high_price": 58.92, "market_price": 29.08, "direct_low_price": 29.48, "updated_at": "2026-09-30T20:37:36.812579+00:00" }, "cardmarket": { "avg": 34.79, "low": 14.3, "trend": 16.27, "avg1": 29.45, "avg7": 31.97, "avg30": 31.97, "updated_at": "2026-09-30T14:49:39.980453+00:00" } }, { "id": "mtg_2c2bae815d1b5d8235423b0c89f43f5383afbff3adbe2b6a895216ea36ddb4f83d2fec580f087b6707d9", "card_number": "1", "name": "Emrakul, the Exigent Doom", "product_type": "card", "variant": "Foil", "tcgplayer": { "low_price": 33.01, "mid_price": 42.3, "high_price": 94.97, "market_price": 39.85, "direct_low_price": null, "updated_at": "2026-09-30T20:37:36.812579+00:00" }, "cardmarket": { "avg": 59.99, "low": 19.5, "trend": 18.78, "avg1": 54.99, "avg7": 58.32, "avg30": 58.32, "updated_at": "2026-09-30T14:49:39.980453+00:00" } }, { "id": "mtg_e4c34bcb45c655b0a16dead271fb9b06485f40592248f6d84d707822665da561a1e9164f1de7c0ad0f5e61cde70601", "card_number": "1 // 5", "name": "Cadet // Jace Double-Sided Token", "product_type": "card", "variant": "Normal", "tcgplayer": null, "cardmarket": null } ], "total": 1226 } ``` ### GET /mtg/sets/:set/statistics *200 OK* ```json { "set_info": { "name": "Reality Fracture", "set_code": "FRA", "set_id": "24684", "total_cards": 767 }, "price_statistics": { "tcgplayer": { "avg_market_price": "17.01", "min_price": 0.12, "max_price": 880, "most_expensive": { "id": "mtg_ec52a22ab58717a79d0006db028c7112b5e228b08893577d810b8a171d3ec22b2a6ea80e47e2ba4462fa7e17", "name": "Omnipresence (Borderless) (Facet Foil) (0459)", "price": 880 } }, "cardmarket": { "avg_price": "12.32", "min_price": 0.03, "max_price": 452.25, "most_expensive": { "id": "mtg_dbc07746db9723d9ba428f50cb6da85211bd1e7658f51bd599bccdcfffb190b95cc00b858dd59296cb227408", "name": "Hexhaven Invigorator (Borderless) (Facet Foil)", "price": 452.25 }, "trend_direction": "stable" } }, "rarity_breakdown": { "M": 90, "T": 15, "C": 71, "R": 134, "U": 124, "L": 35 } } ``` ### GET /mtg/sets/:set/completion-value *200 OK* ```json { "set_info": { "name": "Reality Fracture", "set_code": "FRA", "set_id": "24684", "total_cards": 767 }, "completion_cost": { "tcgplayer": { "currency": "USD", "low_estimate": 18286.81, "market_estimate": 14069.58, "high_estimate": 31790.08 }, "cardmarket": { "currency": "EUR", "low_estimate": 11034.06, "avg_estimate": 12255.16, "trend_estimate": 652.2 }, "note": "One copy per card (base finish). TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available." }, "breakdown_by_rarity": { "M": { "count": 90, "total_cost": 4775.17 }, "T": { "count": 15, "total_cost": 0 }, "C": { "count": 71, "total_cost": 30.63 }, "R": { "count": 134, "total_cost": 1681.23 }, "U": { "count": 124, "total_cost": 56.88 }, "L": { "count": 35, "total_cost": 19.74 } } } ``` ### GET /mtg/analytics/top-cards *200 OK* ```json { "metric": "price", "source": "tcg", "top_cards": [ { "id": "mtg_b12d1c3adb12f714026300db18765591e37f7dd47cacf8cf89e5629aa6d55d188c39a0e63173fa43b8708aff", "card_info": { "name": "Smaug the Magnificent (Borderless)", "clean_name": "Smaug the Magnificent Borderless", "set_name": "The Hobbit", "set_code": "HOB", "set_id": "24683", "card_number": "249", "rarity": "M", "card_type": null, "product_type": "card", "variants": [ "Foil" ], "card_text": null, "p": "4", "t": "3", "sub_type": "Legendary Creature — Dragon" }, "current_price": 24500 }, { "id": "mtg_26dcb8609b2fa021e26275d3499b7285040f5369a7f3a65e5b060a78ba625682b13416d8e411", "card_info": { "name": "Time Walk", "clean_name": "Time Walk", "set_name": "Unlimited Edition", "set_code": "2ED", "set_id": "115", "card_number": null, "rarity": "R", "card_type": null, "product_type": "card", "variants": [ "Normal" ], "card_text": "Take an extra turn after this one.", "sub_type": "Sorcery" }, "current_price": 5719.99 }, { "id": "mtg_57bae78cb8333bb2eeae88837fdc4effdbb2484ca38e6809bac1b402b458ecb45a630b2de42c", "card_info": { "name": "Ancestral Recall", "clean_name": "Ancestral Recall", "set_name": "Unlimited Edition", "set_code": "2ED", "set_id": "115", "card_number": null, "rarity": "R", "card_type": null, "product_type": "card", "variants": [ "Normal" ], "card_text": "Draw 3 cards or force opponent to draw 3 cards.", "sub_type": "Instant" }, "current_price": 4999.95 } ] } ``` ### GET /mtg/analytics/top-cards?metric=growth&source=cm *200 OK* ```json { "metric": "growth", "source": "cm", "top_cards": [ { "id": "mtg_8520f6fbf81704e0fb46e01d98c7c7638da8abf6935f5c521b4087185b688a6c39fd22156233fb", "card_info": { "name": "Sandstorm Eidolon", "clean_name": "Sandstorm Eidolon", "set_name": "Dissension", "set_code": "DIS", "set_id": "28", "card_number": "70", "rarity": "C", "card_type": null, "product_type": "card", "variants": [ "Normal", "Foil" ], "card_text": "R, Sacrifice Sandstorm Eidolon: Target creature can't block this turn.\r\n
\r\nWhenever you play a multicolored spell, you may return Sandstorm Eidolon from your graveyard to your hand.", "p": "2", "t": "2", "sub_type": "Creature — Spirit" }, "current_price": 14.43, "change_7d": "+753.8%" }, { "id": "mtg_b59d5b2762759eb692e40e10c8eabe055a4ffc833efc2f5929d218f12611cb03054fdcfe0e2e", "card_info": { "name": "Aurora Eidolon", "clean_name": "Aurora Eidolon", "set_name": "Dissension", "set_code": "DIS", "set_id": "28", "card_number": "1", "rarity": "C", "card_type": null, "product_type": "card", "variants": [ "Normal", "Foil" ], "card_text": "W, Sacrifice Aurora Eidolon: Prevent the next 3 damage that would be dealt to target creature or player this turn.\r\n
\r\nWhenever you play a multicolored spell, you may return Aurora Eidolon from your graveyard to your hand.", "p": "2", "t": "2", "sub_type": "Creature — Spirit" }, "current_price": 15.87, "change_7d": "+479.2%" }, { "id": "aaf47baa7bfde1c553a099b9f510e8f716667f2e8314a889624547b3a902202d", "card_info": { "name": "Black Border Foil Filler Card", "clean_name": "Black Border Foil Filler Card", "set_name": "Filler Cards", "set_code": "filler", "set_id": "-35", "card_number": null, "rarity": null, "card_type": null, "product_type": "card", "variants": [], "card_text": null }, "current_price": 49.48, "change_7d": "+451.0%" } ] } ``` ### GET /mtg/sets/trending *200 OK* ```json { "period": "7d", "trending_sets": [ { "set_name": "WCD 2002: Brian Kibler", "set_code": "wc02bk", "set_id": "-24", "card_count": 10, "cardmarket": { "price_change": "+112.1%", "avg_price_current": 8.04, "avg_price_previous": 3.79, "top_movers": [ { "name": "Plains", "change": "+189.6%" }, { "name": "Plains", "change": "+168.7%" }, { "name": "Forest", "change": "+147.9%" } ] }, "tcgplayer": null }, { "set_name": "Alpha Edition", "set_code": "LEA", "set_id": "7", "card_count": 295, "cardmarket": { "price_change": "+78.9%", "avg_price_current": 930.31, "avg_price_previous": 519.91, "top_movers": [ { "name": "Timetwister", "change": "+191.4%" }, { "name": "Ancestral Recall", "change": "+189.7%" }, { "name": "Mox Emerald", "change": "+178.7%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } } ] } ``` ## Data Notes > **Prices.** TCGPlayer and CardMarket prices are refreshed daily. CardMarket has one entry per finish (`normal`, `foil`); a finish CardMarket does not price is left out, so `cardmarket.prices` can be empty. `updated_at` is when that price last changed, not when it was last checked: a stable price keeps an older date. > **`product_type`.** Cards and sealed products are told apart using TCGPlayer data, then CardTrader. Tokens, emblems and oversized cards count as `"card"`. For the very few products whose type cannot be determined, `product_type` is `null`, not `"card"`. > **CardMarket-only sets.** Sets with a negative `set_id` exist only on CardMarket: their cards have 64-character IDs and `tcgplayer: null`. > **Missing links.** `cardmarket.product_url` is absent for some cards; the card data is still valid. Sets with no cards are not listed: they appear as soon as cards are added. ## Magic: The Gathering API FAQ ### Is there a free Magic: The Gathering price API? Yes. The free tier (100 requests/hour, 1,000/day) opens the Magic: The Gathering sets, cards, search and images endpoints, with TCGPlayer and CardMarket prices refreshed daily. Prices by set, set statistics, completion value, trending sets and top cards need the Ultra plan (€29/month) or its 7-day trial. ### Does the Magic: The Gathering API include CardMarket prices? Yes. Cards return TCGPlayer (USD) prices for every finish and CardMarket (EUR) prices for normal and foil, where that market lists the card. Cards sold only on CardMarket have a 64-character hex id and no TCGPlayer price. ### How do I find the id of a Magic: The Gathering card? Search with /mtg/search?q=… or list a set with /mtg/sets/:set. Each card has an id (mtg_ + hex for cards on TCGPlayer) to pass to /mtg/cards/:id and /mtg/images/:id. ### Can I use the same API key for other games? Yes. One PokéWallet API key works for all 12 games, Pokémon and One Piece included, and the rate limits are shared across them. --- # Yu-Gi-Oh! API Documentation Source: https://pokewallet.io/api-docs/yugioh REST reference for the Yu-Gi-Oh! API: sets, cards, search and images, with prices from TCGPlayer and CardMarket. Same API key as the Pokémon and One Piece APIs. In short The Yu-Gi-Oh! API returns 706 sets with their cards, search and images, and TCGPlayer (USD) and CardMarket (EUR) prices refreshed daily. These endpoints are free (100 requests/hour) with the same key as the other 11 games; prices by set and set analytics need the Ultra plan (€29/month) or its 7-day trial. At a glance - **Base path:** `https://api.pokewallet.io/ygo` - **Sets:** 706 Yu-Gi-Oh! sets - **Card IDs:** `ygo_` + hex for cards on TCGPlayer; 64 hex characters for CardMarket-only cards - **Prices:** TCGPlayer (USD) for every finish and CardMarket (EUR) for `normal` and `foil`, refreshed daily - **Free on every plan:** Sets, set cards, card details, search and images - **Ultra plan or 7-day trial:** Prices by set, set statistics, completion value, trending sets and top cards - **API key:** The same key as the Pokémon and One Piece APIs, with shared rate limits Updated Oct 19, 2026 ## Quick Start Get started with PokéWallet API in 4 simple steps: ### Create an Account Sign up for free to start using the API. Upgrade anytime from your dashboard. [Sign Up Now](https://pokewallet.io/auth/login?source=pokemon) ### Generate an API Key Create your first API key from the dashboard. ### Make Your First Request Start querying the API with your key. *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/ygo/sets" ``` ### Join the Discord Community Stay up to date with new features, ask for help, and connect with other developers. [Join Discord](https://discord.gg/znDxEjmDVP) > **Yu-Gi-Oh! PRO endpoints: Ultra plan required** > > The **Pro plan does not include them**: Pro covers Pokémon and One Piece only. Ultra (€29/month) includes everything in Pro plus the paid endpoints of **all 12 games**. Free endpoints (sets, cards, search, images) work on every plan. > > [Compare plans →](https://pokewallet.io/pricing) ## Yu-Gi-Oh! All Yu-Gi-Oh! endpoints live under `/ygo`. Same API key, same rate limits and the same response format as the Pokémon endpoints. ### Card IDs | Format | Example | Used for | | --- | --- | --- | | `ygo_` + hex | `ygo_9a3718ca91c2b4423f3b…` | Every card with a TCGPlayer product, even if it also has CardMarket data | | 64 hex characters, no prefix | `e26f12b8b1fabf19…` | Cards that exist only on CardMarket | > A `ygo_…` ID only works under `/ygo/`. Finishes of the same product (Normal, Foil, …) are one card with one ID; each finish has its own TCGPlayer price. If you request a card by its CardMarket ID and it is linked to a TCGPlayer product, the response uses the canonical `ygo_…` ID. ### Response Format Same shape as the Pokémon API: `card_info`, `images`, `tcgplayer.prices` and `cardmarket.prices` as arrays, `pagination`, errors as `{ "error", "message" }`. Differences: | Field | Yu-Gi-Oh! | | --- | --- | | Game fields in `card_info` | Instead of Pokémon's `hp`, `stage`, `attacks`…, the game's own fields in snake_case (present when the card has them): `attribute`, `attack`, `defense`, `monster_type`, `link_rating`, `link_arrows`, `upc` | | `card_type`, `card_text` | Filled from the game's card type and rules text. `card_text` may contain HTML (``, ``…) as provided by TCGPlayer. | | `card_info.variants`, `card_info.set_id` | Always present, on every endpoint | | `product_type` | `"card"`, `"sealed"` or `null` when unknown — see [Data Notes](https://pokewallet.io/api-docs/yugioh#ygo-data-notes) | | `release_date` | ISO format, e.g. `"2025-03-07T00:00:00"` (Pokémon uses `"16th June, 2023"`) | | `images.languages` | `["en"]`, or `[]` when there is no image | ## Yu-Gi-Oh! Endpoints ### GET /ygo/sets All Yu-Gi-Oh! sets. ### Response Fields: | Field | Type | Description | | --- | --- | --- | | `name` | string | Set name | | `set_code` | string \| null | Short code. **Not unique**: several sets can share it. | | `set_id` | string | Unique set identifier. Negative for sets that exist only on CardMarket. | | `card_count` | integer | Cards in the set (sealed products excluded). Omitted, not 0, if temporarily unavailable. | | `sealed_count` | integer | Sealed products in the set (booster boxes, displays, decks). Omitted, not 0, if temporarily unavailable. | | `language` | string \| null | Set language | | `release_date` | string \| null | ISO date | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/ygo/sets" ``` ### Response Example (first two sets): *200 OK* ```json { "success": true, "data": [ { "name": "2-Player Starter Deck Yuya & Declan", "set_code": "ys15", "set_id": "-70", "card_count": 42, "sealed_count": 0, "language": "eng", "release_date": null }, { "name": "2-Player Starter Set", "set_code": "TPSS", "set_id": "23269", "card_count": 88, "sealed_count": 2, "language": "eng", "release_date": "2024-01-26T00:00:00" } ], "total": 706 } ``` ### GET /ygo/sets/:set Cards of one set, paginated. Prices are empty in set listings, as on the Pokémon API: use `/ygo/cards/:id` for prices. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `set` | string | Required | `set_id` (recommended, always unique) or `set_code` (exact match, case-insensitive) | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 50, max: 200) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/ygo/sets/24707?limit=1" ``` ### Response Example: *200 OK* ```json { "success": true, "set": { "name": "Magnificent Monsters", "set_code": "MAMO", "set_id": "24707", "total_cards": 231, "language": "eng", "release_date": "2026-09-04T00:00:00" }, "cards": [ { "id": "ygo_9a3718ca91c2b4423f3bd02f650c59e4ee88601dc34d7cf38563f2a33db17bebe508528b418815d5975ee98f02fa261d04cec9", "card_info": { "name": "Dark Magician, the Pharaoh's Servant", "clean_name": "Dark Magician the Pharaohs Servant", "set_name": "Magnificent Monsters", "set_code": "MAMO", "set_id": "24707", "card_number": "MAMO-EN001", "rarity": "Ultra Rare", "card_type": "Effect Monster", "product_type": "card", "variants": [ "1st Edition" ], "card_text": "This card's name becomes \"Dark Magician\" while on the field or in the GY. You can only use 1 of the following effects of \"Dark Magician, the Pharaoh's Servant\" per turn, and only once that turn. If this card is in your hand: You can reveal 1 Spell in your hand; Special Summon this card, then you can Set 1 Spell/Trap that mentions \"Dark Magician\" from your Deck. (Quick Effect): You can discard 1 Spell; destroy all Spells/Traps your opponent controls.", "attack": "2500", "defense": "2100", "attribute": "DARK", "monster_type": "Spellcaster" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/714701/yugioh-magnificent-monsters-dark-magician-the-pharaohs-servant" }, "cardmarket": { "product_name": "Dark Magician, the Pharaoh's Servant (V.1 - Ultra Rare)", "prices": [], "product_url": "https://www.cardmarket.com/en/YuGiOh/Products/Singles/Magnificent-Monsters/Dark-Magician-the-Pharaohs-Servant-V1-Ultra-Rare" } } ], "pagination": { "page": 1, "limit": 1, "total": 231, "total_pages": 231 } } ``` ### Disambiguation Response: When a `set_code` is shared by several sets, the API returns the candidates instead of a set (status 200, as on the Pokémon API). Call again with the `set_id` you need. *200 OK — /ygo/sets/BPT* ```json { "disambiguation": true, "message": "Multiple sets found for set_code 'BPT'. Use set_id to specify which one.", "matches": [ { "set_id": "126", "set_code": "BPT", "name": "2003 Collectors Tin", "language": "eng", "release_date": "2003-09-01T00:00:00" }, { "set_id": "1341", "set_code": "BPT", "name": "2002 Collectors Tin", "language": "eng", "release_date": "2002-10-04T00:00:00" } ], "total": 2 } ``` ### GET /ygo/cards/:id Full card with prices. `id` is a `ygo_…` ID or a 64-character CardMarket ID. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/ygo/cards/ygo_9a3718ca91c2b4423f3bd02f650c59e4ee88601dc34d7cf38563f2a33db17bebe508528b418815d5975ee98f02fa261d04cec9" ``` ### Response Example: *200 OK* ```json { "id": "ygo_9a3718ca91c2b4423f3bd02f650c59e4ee88601dc34d7cf38563f2a33db17bebe508528b418815d5975ee98f02fa261d04cec9", "card_info": { "name": "Dark Magician, the Pharaoh's Servant", "clean_name": "Dark Magician the Pharaohs Servant", "set_name": "Magnificent Monsters", "set_code": "MAMO", "set_id": "24707", "card_number": "MAMO-EN001", "rarity": "Ultra Rare", "card_type": "Effect Monster", "product_type": "card", "variants": [ "1st Edition" ], "card_text": "This card's name becomes \"Dark Magician\" while on the field or in the GY. You can only use 1 of the following effects of \"Dark Magician, the Pharaoh's Servant\" per turn, and only once that turn. If this card is in your hand: You can reveal 1 Spell in your hand; Special Summon this card, then you can Set 1 Spell/Trap that mentions \"Dark Magician\" from your Deck. (Quick Effect): You can discard 1 Spell; destroy all Spells/Traps your opponent controls.", "attack": "2500", "defense": "2100", "attribute": "DARK", "monster_type": "Spellcaster" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 2.6, "mid_price": 4.99, "high_price": 40, "market_price": 3.23, "direct_low_price": null, "updated_at": "2026-09-30T20:39:18.568656+00:00", "sub_type_name": "1st Edition" } ], "url": "https://www.tcgplayer.com/product/714701/yugioh-magnificent-monsters-dark-magician-the-pharaohs-servant" }, "cardmarket": { "product_name": "Dark Magician, the Pharaoh's Servant (V.1 - Ultra Rare)", "prices": [ { "variant_type": "normal", "avg": 6.26, "low": 1.25, "trend": 0.02, "avg1": 6.41, "avg7": 9.47, "avg30": 9.66, "updated_at": "2026-09-30T14:49:49.858181+00:00" } ], "product_url": "https://www.cardmarket.com/en/YuGiOh/Products/Singles/Magnificent-Monsters/Dark-Magician-the-Pharaohs-Servant-V1-Ultra-Rare" } } ``` > One entry in `tcgplayer.prices` per finish, identified by `sub_type_name`, and one entry in `cardmarket.prices` per finish, identified by `variant_type` (`normal`, `foil`). `updated_at` is when that price last changed, not when it was last checked. A CardMarket-only card has `tcgplayer: null` and empty `variants`. ### GET /ygo/search Search cards by name or card number. Results have the same shape as `/ygo/cards/:id`, prices included. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | Required | 2–100 characters. Card name (all words, any order) or card number | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 20, max: 100) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/ygo/search?q=Magician&limit=2" ``` ### Response Example (`results` omitted): *200 OK* ```json { "query": "Magician", "results": [ { "id": "e26f12b8b1fabf19be743d13a53fe800a0f50b780e8a6373434800cff136540b", "card_info": { "name": "Dark Magician Knight", "clean_name": "Dark Magician Knight", "set_name": "Reshef of Destruction Promos", "set_code": "rod", "set_id": "-15", "card_number": "001", "rarity": null, "card_type": null, "product_type": "card", "variants": [], "card_text": null }, "images": { "languages": [ "en" ] }, "tcgplayer": null, "cardmarket": { "product_name": "Dark Magician Knight", "prices": [ { "variant_type": "normal", "avg": 16.57, "low": 4.99, "trend": 12.27, "avg1": 13.14, "avg7": 12.15, "avg30": 12.05, "updated_at": "2026-09-30T14:49:46.350963+00:00" }, { "variant_type": "foil", "avg": null, "low": null, "trend": 7.9, "avg1": 7.9, "avg7": 7.9, "avg30": 7.9, "updated_at": "2026-09-30T14:49:46.350963+00:00" } ] } } ], "pagination": { "page": 1, "limit": 2, "total": 300, "total_pages": 150 }, "metadata": { "total_count": 300, "tcg": 284, "cardmarket": 288, "tcg_only": 12, "cardmarket_only": 16, "both_sources": 272, "truncated": true } } ``` > `metadata.truncated: true` means more cards match than the search returns: add words to narrow it down. Words match anywhere in the name; a query shorter than 3 characters matches names and card numbers that **start** with it (`27` finds `27`, `027/264`, `0027`). Quotes are ignored; `*`, `%` and `_` are plain text, not wildcards. ### GET /ygo/images/:id The card image, one resolution (`X-Image-Size: unsized`): the `size` parameter of the Pokémon image endpoint does not apply. Cached for 24 hours. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/ygo/images/ygo_9a3718ca91c2b4423f3bd02f650c59e4ee88601dc34d7cf38563f2a33db17bebe508528b418815d5975ee98f02fa261d04cec9" \ --output card ``` ## Ultra endpoints Available on Ultra and Business plans, or during the 7-day trial. The Pro plan covers Pokémon and One Piece only: with Pro these endpoints answer 403 with an `upgrade_url`. Ultra includes everything in Pro. Same parameters and response format as the Pokémon endpoints of the same name. | Endpoint | What it returns | | --- | --- | | `GET /ygo/prices/:set` | TCGPlayer and CardMarket prices for every card of a set, one row per finish. `?source=tcg\|cm` | | `GET /ygo/sets/:set/statistics` | Price statistics and rarity breakdown. Sealed products excluded. `?variant=normal\|foil` | | `GET /ygo/sets/:set/completion-value` | Cost of one copy of every card in the set. Sealed products excluded. | | `GET /ygo/sets/trending` | Sets whose CardMarket prices moved most: 7-day average against 30-day average, cards from 1 € up. `?period=7d` `?limit=` | | `GET /ygo/analytics/top-cards` | Most expensive cards, or fastest-growing on CardMarket (7-day average against 30-day average, cards from 1 € up; `current_price` is the 7-day average). `?metric=price\|growth` `?source=tcg\|cm` `?limit=` | > Price history is a Pokémon feature: for this game there is no `/cards/:id/price-history`. Current prices are in the card detail and in `/ygo/prices/:set`; `metric=growth` works with `source=cm` only, and trending supports `period=7d` only. ### GET /ygo/prices/:set (first rows) *200 OK* ```json { "success": true, "source": "both", "set_code": "MAMO", "set_id": "24707", "data": [ { "id": "ygo_9a3718ca91c2b4423f3bd02f650c59e4ee88601dc34d7cf38563f2a33db17bebe508528b418815d5975ee98f02fa261d04cec9", "card_number": "MAMO-EN001", "name": "Dark Magician, the Pharaoh's Servant", "product_type": "card", "variant": "1st Edition", "tcgplayer": { "low_price": 2.6, "mid_price": 4.99, "high_price": 40, "market_price": 3.23, "direct_low_price": null, "updated_at": "2026-09-30T20:39:18.568656+00:00" }, "cardmarket": { "avg": 6.26, "low": 1.25, "trend": 0.02, "avg1": 6.41, "avg7": 9.47, "avg30": 9.66, "updated_at": "2026-09-30T14:49:49.858181+00:00" } }, { "id": "ygo_57511f682870f1384352f6179ca6b07c0d21be965845052bd23653b88bdf3cae3bc36087a7037b5c5c9dd76464aa97b253e1d9", "card_number": "MAMO-EN001", "name": "Dark Magician, the Pharaoh's Servant (Extended Art)", "product_type": "card", "variant": "1st Edition", "tcgplayer": { "low_price": 137.99, "mid_price": 178.96, "high_price": 450, "market_price": 149.33, "direct_low_price": null, "updated_at": "2026-09-30T20:39:18.568656+00:00" }, "cardmarket": { "avg": 120.19, "low": 99.95, "trend": 101.9, "avg1": 134.3, "avg7": 130.47, "avg30": 130.47, "updated_at": "2026-09-30T14:49:49.858181+00:00" } }, { "id": "ygo_c5442172fc9e80d37925fe3a4edc43fd0bff86dbb230e48cf302839f18edc6ee77da2da647cd60895f91d21d2595e74ebf9fdd", "card_number": "MAMO-EN001", "name": "Dark Magician, the Pharaoh's Servant (GMR)", "product_type": "card", "variant": "Normal", "tcgplayer": null, "cardmarket": { "avg": 15000, "low": 24989.49, "trend": 15000, "avg1": null, "avg7": null, "avg30": null, "updated_at": "2026-09-30T14:49:49.858181+00:00" } } ], "total": 234 } ``` ### GET /ygo/sets/:set/statistics *200 OK* ```json { "set_info": { "name": "Magnificent Monsters", "set_code": "MAMO", "set_id": "24707", "total_cards": 228 }, "price_statistics": { "tcgplayer": { "avg_market_price": "66.09", "min_price": 0.1, "max_price": 5000, "most_expensive": { "id": "ygo_8223703af179aafc319780b7a0da99f0b25cc80d7c0770fec800f85cd6b1c1b2b4726f9f6990db204a4ca9a38984ed8d480a38", "name": "Winged Kuriboh Sabatiel LV10 (GMR)", "price": 5000 } }, "cardmarket": { "avg_price": "252.54", "min_price": 0.11, "max_price": 15000, "most_expensive": { "id": "ygo_c5442172fc9e80d37925fe3a4edc43fd0bff86dbb230e48cf302839f18edc6ee77da2da647cd60895f91d21d2595e74ebf9fdd", "name": "Dark Magician, the Pharaoh's Servant (GMR)", "price": 15000 }, "trend_direction": "stable" } }, "rarity_breakdown": { "Ultra Rare": 138, "Grand Master Rare": 18, "Starlight Rare": 46, "Secret Rare": 26 } } ``` ### GET /ygo/sets/:set/completion-value *200 OK* ```json { "set_info": { "name": "Magnificent Monsters", "set_code": "MAMO", "set_id": "24707", "total_cards": 228 }, "completion_cost": { "tcgplayer": { "currency": "USD", "low_estimate": 189772.1, "market_estimate": 171007.03, "high_estimate": 375141.96 }, "cardmarket": { "currency": "EUR", "low_estimate": 118951.11, "avg_estimate": 101620.96, "trend_estimate": 37853.28 }, "note": "One copy per card (base finish). TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available." }, "breakdown_by_rarity": { "Ultra Rare": { "count": 138, "total_cost": 993.78 }, "Grand Master Rare": { "count": 18, "total_cost": 5001 }, "Starlight Rare": { "count": 46, "total_cost": 8002.46 }, "Secret Rare": { "count": 26, "total_cost": 13.49 } } } ``` ### GET /ygo/analytics/top-cards *200 OK* ```json { "metric": "price", "source": "tcg", "top_cards": [ { "id": "ygo_8223703af179aafc319780b7a0da99f0b25cc80d7c0770fec800f85cd6b1c1b2b4726f9f6990db204a4ca9a38984ed8d480a38", "card_info": { "name": "Winged Kuriboh Sabatiel LV10 (GMR)", "clean_name": "Winged Kuriboh Sabatiel LV10 GMR", "set_name": "Magnificent Monsters", "set_code": "MAMO", "set_id": "24707", "card_number": "MAMO-EN006", "rarity": "Grand Master Rare", "card_type": "Effect Monster", "product_type": "card", "variants": [ "1st Edition" ], "card_text": "You can reveal this card in your hand and pay half your LP; add 1 \"Polymerization\" Spell or \"Fusion\" Spell from your Deck to your hand, and if you do, shuffle this card into the Deck, also for the rest of this turn, you cannot Special Summon from the Extra Deck, except \"HERO\" monsters. During your opponent's turn, if your LP are 1000 or less (Quick Effect): You can Special Summon this card from your hand, then you can inflict damage to your opponent equal to the highest ATK among the monsters they control. You can only use each effect of \"Winged Kuriboh Sabatiel LV10\" once per turn.", "attack": "300", "defense": "200", "attribute": "LIGHT", "monster_type": "Fairy" }, "current_price": 5000 }, { "id": "ygo_d83dc4e4fa55aa433ac4605dd7b2753e9090c2b1abba39583707349e938d7c13b50f8bf48cddf05fce458cdf800bcc91", "card_info": { "name": "Black Rose Dragon (Ghost Rare)", "clean_name": "Black Rose Dragon Ghost Rare", "set_name": "Crossroads of Chaos", "set_code": "CSOC", "set_id": "158", "card_number": "CSOC-EN039", "rarity": "Ghost Rare", "card_type": "Synchro/Effect Monster", "product_type": "card", "variants": [ "1st Edition", "Unlimited" ], "card_text": "1 Tuner + 1 or more non-Tuner monsters\r\n
When this card is Synchro Summoned, you can destroy all cards on the field. Once per turn, you can remove from play 1 Plant-Type monster from your Graveyard to change 1 monster your opponent controls to face-up Attack Position, and reduce its ATK to 0 until the End Phase.", "attack": "2400", "defense": "1800", "attribute": "FIRE", "monster_type": "Dragon" }, "current_price": 1499.09 }, { "id": "ygo_7ff73e5dab2d5fead97db9c226bdd065649303f1759447a621567f33e9e737b06695cc65a9cc5a2e823b0f2b46ae", "card_info": { "name": "Blue-Eyes White Dragon (Dark Duel Stories)", "clean_name": "Blue Eyes White Dragon Dark Duel Stories", "set_name": "Yu-Gi-Oh! Video Game Promotional Cards", "set_code": "VDP", "set_id": "1921", "card_number": "DDS-001", "rarity": "Prismatic Secret Rare", "card_type": "Normal Monster", "product_type": "card", "variants": [ "Unlimited" ], "card_text": "This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.", "attack": "3000", "defense": "2500", "attribute": "LIGHT", "monster_type": "Dragon" }, "current_price": 1450.56 } ] } ``` ### GET /ygo/analytics/top-cards?metric=growth&source=cm *200 OK* ```json { "metric": "growth", "source": "cm", "top_cards": [ { "id": "ygo_f260d6bf06b66ba33234a65e4ab1a3419645ee082a8be0c264a95d961c69c44b1cf89c231a079f65f27aabf1caf86e0616", "card_info": { "name": "Jerry Beans Man", "clean_name": "Jerry Beans Man", "set_name": "Dark Revelation Volume 4", "set_code": "DR04", "set_id": "1279", "card_number": "DR04-EN004", "rarity": "Common", "card_type": "Normal Monster", "product_type": "card", "variants": [ "Unlimited" ], "card_text": "Jerry, a bean soldier, believes he is the strongest warrior in the world, but his true abilities are still untested.", "attack": "1750", "defense": "0", "attribute": "EARTH", "monster_type": "Plant" }, "current_price": 134.11, "change_7d": "+433.9%" }, { "id": "d069f3c9f9d02f573d7ba6f3d8754adfd22f17c08cb626bda54d425ca33573ea", "card_info": { "name": "Worm Bait", "clean_name": "Worm Bait", "set_name": "5D's Tag Force 4 Promotional Cards", "set_code": "tf04", "set_id": "-45", "card_number": "002", "rarity": null, "card_type": null, "product_type": "card", "variants": [], "card_text": null }, "current_price": 9.69, "change_7d": "+402.1%" }, { "id": "ygo_22e2be379321c4d637efb9921ebb8e167caf0fd8cc35d04f02757713a561bc15981a94fd1e816427351fca8b91", "card_info": { "name": "The Statue of Easter Island", "clean_name": "The Statue of Easter Island", "set_name": "Tournament Pack 1", "set_code": "TP1", "set_id": "333", "card_number": "TP1-019", "rarity": "Common", "card_type": "Normal Monster", "product_type": "card", "variants": [ "Unlimited" ], "card_text": "A stone monument from Easter Island that launches laser blasts from its rock-hewn lips.", "attack": "1100", "defense": "1400", "attribute": "EARTH", "monster_type": "Rock" }, "current_price": 12.76, "change_7d": "+381.5%" } ] } ``` ### GET /ygo/sets/trending *200 OK* ```json { "period": "7d", "trending_sets": [ { "set_name": "World Championship 2011 Card Pack", "set_code": "WP11", "set_id": "1929", "card_count": 20, "cardmarket": { "price_change": "+119.9%", "avg_price_current": 96.57, "avg_price_previous": 43.9, "top_movers": [ { "name": "Great Bill", "change": "+186.3%" }, { "name": "Meteor Dragon", "change": "+181.6%" }, { "name": "Goblin Fan", "change": "+178.7%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } }, { "set_name": "Starter Deck: Kaiba", "set_code": "SDK", "set_id": "294", "card_count": 11, "cardmarket": { "price_change": "+74.4%", "avg_price_current": 10.61, "avg_price_previous": 6.08, "top_movers": [ { "name": "Blue-Eyes White Dragon (V.2 - Ultra Rare)", "change": "+165.7%" }, { "name": "Blue-Eyes White Dragon (V.3 - Ultra Rare)", "change": "+68.7%" }, { "name": "Blue-Eyes White Dragon (V.1 - Ultra Rare)", "change": "-42.6%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } } ] } ``` ## Data Notes > **Prices.** TCGPlayer and CardMarket prices are refreshed daily. CardMarket has one entry per finish (`normal`, `foil`); a finish CardMarket does not price is left out, so `cardmarket.prices` can be empty. `updated_at` is when that price last changed, not when it was last checked: a stable price keeps an older date. > **`product_type`.** Cards and sealed products are told apart using TCGPlayer data, then CardTrader. Tokens, emblems and oversized cards count as `"card"`. For the very few products whose type cannot be determined, `product_type` is `null`, not `"card"`. > **CardMarket-only sets.** Sets with a negative `set_id` exist only on CardMarket: their cards have 64-character IDs and `tcgplayer: null`. > **Missing links.** `cardmarket.product_url` is absent for some cards; the card data is still valid. Sets with no cards are not listed: they appear as soon as cards are added. ## Yu-Gi-Oh! API FAQ ### Is there a free Yu-Gi-Oh! price API? Yes. The free tier (100 requests/hour, 1,000/day) opens the Yu-Gi-Oh! sets, cards, search and images endpoints, with TCGPlayer and CardMarket prices refreshed daily. Prices by set, set statistics, completion value, trending sets and top cards need the Ultra plan (€29/month) or its 7-day trial. ### Does the Yu-Gi-Oh! API include CardMarket prices? Yes. Cards return TCGPlayer (USD) prices for every finish and CardMarket (EUR) prices for normal and foil, where that market lists the card. Cards sold only on CardMarket have a 64-character hex id and no TCGPlayer price. ### How do I find the id of a Yu-Gi-Oh! card? Search with /ygo/search?q=… or list a set with /ygo/sets/:set. Each card has an id (ygo_ + hex for cards on TCGPlayer) to pass to /ygo/cards/:id and /ygo/images/:id. ### Can I use the same API key for other games? Yes. One PokéWallet API key works for all 12 games, Pokémon and One Piece included, and the rate limits are shared across them. --- # Disney Lorcana API Documentation Source: https://pokewallet.io/api-docs/lorcana REST reference for the Disney Lorcana API: sets, cards, search and images, with prices from TCGPlayer and CardMarket. Same API key as the Pokémon and One Piece APIs. In short The Disney Lorcana API returns 24 sets with their cards, search and images, and TCGPlayer (USD) and CardMarket (EUR) prices refreshed daily. These endpoints are free (100 requests/hour) with the same key as the other 11 games; prices by set and set analytics need the Ultra plan (€29/month) or its 7-day trial. At a glance - **Base path:** `https://api.pokewallet.io/lor` - **Sets:** 24 Disney Lorcana sets - **Card IDs:** `lor_` + hex for cards on TCGPlayer; 64 hex characters for CardMarket-only cards - **Prices:** TCGPlayer (USD) for every finish and CardMarket (EUR) for `normal` and `foil`, refreshed daily - **Free on every plan:** Sets, set cards, card details, search and images - **Ultra plan or 7-day trial:** Prices by set, set statistics, completion value, trending sets and top cards - **API key:** The same key as the Pokémon and One Piece APIs, with shared rate limits Updated Oct 19, 2026 ## Quick Start Get started with PokéWallet API in 4 simple steps: ### Create an Account Sign up for free to start using the API. Upgrade anytime from your dashboard. [Sign Up Now](https://pokewallet.io/auth/login?source=pokemon) ### Generate an API Key Create your first API key from the dashboard. ### Make Your First Request Start querying the API with your key. *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/lor/sets" ``` ### Join the Discord Community Stay up to date with new features, ask for help, and connect with other developers. [Join Discord](https://discord.gg/znDxEjmDVP) > **Disney Lorcana PRO endpoints: Ultra plan required** > > The **Pro plan does not include them**: Pro covers Pokémon and One Piece only. Ultra (€29/month) includes everything in Pro plus the paid endpoints of **all 12 games**. Free endpoints (sets, cards, search, images) work on every plan. > > [Compare plans →](https://pokewallet.io/pricing) ## Disney Lorcana All Disney Lorcana endpoints live under `/lor`. Same API key, same rate limits and the same response format as the Pokémon endpoints. ### Card IDs | Format | Example | Used for | | --- | --- | --- | | `lor_` + hex | `lor_c90d1341d751d70cfa4e…` | Every card with a TCGPlayer product, even if it also has CardMarket data | | 64 hex characters, no prefix | `e26f12b8b1fabf19…` | Cards that exist only on CardMarket | > A `lor_…` ID only works under `/lor/`. Finishes of the same product (Normal, Foil, …) are one card with one ID; each finish has its own TCGPlayer price. If you request a card by its CardMarket ID and it is linked to a TCGPlayer product, the response uses the canonical `lor_…` ID. ### Response Format Same shape as the Pokémon API: `card_info`, `images`, `tcgplayer.prices` and `cardmarket.prices` as arrays, `pagination`, errors as `{ "error", "message" }`. Differences: | Field | Disney Lorcana | | --- | --- | | Game fields in `card_info` | Instead of Pokémon's `hp`, `stage`, `attacks`…, the game's own fields in snake_case (present when the card has them): `inkwell_iconon_card`, `property`, `cost_ink`, `ink_type`, `classification`, `willpower`, `lore_value`, `character_version`, `strength`, `flavor_text`, `move_cost`, `promo_type` | | `card_type`, `card_text` | Filled from the game's card type and rules text. `card_text` may contain HTML (``, ``…) as provided by TCGPlayer. | | `card_info.variants`, `card_info.set_id` | Always present, on every endpoint | | `product_type` | `"card"`, `"sealed"` or `null` when unknown — see [Data Notes](https://pokewallet.io/api-docs/lorcana#lor-data-notes) | | `release_date` | ISO format, e.g. `"2025-03-07T00:00:00"` (Pokémon uses `"16th June, 2023"`) | | `images.languages` | `["en"]`, or `[]` when there is no image | ## Disney Lorcana Endpoints ### GET /lor/sets All Disney Lorcana sets. ### Response Fields: | Field | Type | Description | | --- | --- | --- | | `name` | string | Set name | | `set_code` | string \| null | Short code. **Not unique**: several sets can share it. | | `set_id` | string | Unique set identifier. Negative for sets that exist only on CardMarket. | | `card_count` | integer | Cards in the set (sealed products excluded). Omitted, not 0, if temporarily unavailable. | | `sealed_count` | integer | Sealed products in the set (booster boxes, displays, decks). Omitted, not 0, if temporarily unavailable. | | `language` | string \| null | Set language | | `release_date` | string \| null | ISO date | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/lor/sets" ``` ### Response Example (first two sets): *200 OK* ```json { "success": true, "data": [ { "name": "Archazia's Island", "set_code": "7", "set_id": "24011", "card_count": 222, "sealed_count": 36, "language": "eng", "release_date": "2025-03-07T00:00:00" }, { "name": "Attack of the Vine!", "set_code": "13", "set_id": "24666", "card_count": 252, "sealed_count": 18, "language": "eng", "release_date": "2026-07-17T00:00:00" } ], "total": 24 } ``` ### GET /lor/sets/:set Cards of one set, paginated. Prices are empty in set listings, as on the Pokémon API: use `/lor/cards/:id` for prices. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `set` | string | Required | `set_id` (recommended, always unique) or `set_code` (exact match, case-insensitive) | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 50, max: 200) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/lor/sets/24666?limit=1" ``` ### Response Example: *200 OK* ```json { "success": true, "set": { "name": "Attack of the Vine!", "set_code": "13", "set_id": "24666", "total_cards": 270, "language": "eng", "release_date": "2026-07-17T00:00:00" }, "cards": [ { "id": "lor_c90d1341d751d70cfa4e0f5185655b07157821be2491b59a6d3e5a2d0b7ad781ced4871d9b135bf47694ccaab5cb", "card_info": { "name": "Woody - Helping a Friend", "clean_name": "Woody Helping a Friend", "set_name": "Attack of the Vine!", "set_code": "13", "set_id": "24666", "card_number": "1/207", "rarity": "Rare", "card_type": "Character", "product_type": "card", "variants": [ "Normal", "Cold Foil" ], "card_text": "[Hang On!] When you play this character, choose one of the following. If you have another Toy character in play, choose both instead:
• You may return a character card with cost 2 or less from your discard to your hand.
• You may play a character with cost 2 or less for free.", "ink_type": "Amber", "cost_ink": "4", "property": "Toy Story", "strength": "2", "willpower": "4", "lore_value": "2", "classification": "Storyborn;Hero;Toy", "character_version": "Helping a Friend", "inkwell_iconon_card": "No" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/702669/lorcana-tcg-attack-of-the-vine-woody-helping-a-friend" }, "cardmarket": { "product_name": "Woody - Helping a Friend", "prices": [], "product_url": "https://www.cardmarket.com/en/Lorcana/Products/Singles/Attack-of-the-Vine/Woody-Helping-a-Friend" } } ], "pagination": { "page": 1, "limit": 1, "total": 270, "total_pages": 270 } } ``` ### GET /lor/cards/:id Full card with prices. `id` is a `lor_…` ID or a 64-character CardMarket ID. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/lor/cards/lor_c90d1341d751d70cfa4e0f5185655b07157821be2491b59a6d3e5a2d0b7ad781ced4871d9b135bf47694ccaab5cb" ``` ### Response Example: *200 OK* ```json { "id": "lor_c90d1341d751d70cfa4e0f5185655b07157821be2491b59a6d3e5a2d0b7ad781ced4871d9b135bf47694ccaab5cb", "card_info": { "name": "Woody - Helping a Friend", "clean_name": "Woody Helping a Friend", "set_name": "Attack of the Vine!", "set_code": "13", "set_id": "24666", "card_number": "1/207", "rarity": "Rare", "card_type": "Character", "product_type": "card", "variants": [ "Normal", "Cold Foil" ], "card_text": "[Hang On!] When you play this character, choose one of the following. If you have another Toy character in play, choose both instead:
• You may return a character card with cost 2 or less from your discard to your hand.
• You may play a character with cost 2 or less for free.", "ink_type": "Amber", "cost_ink": "4", "property": "Toy Story", "strength": "2", "willpower": "4", "lore_value": "2", "classification": "Storyborn;Hero;Toy", "character_version": "Helping a Friend", "inkwell_iconon_card": "No" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 0.01, "mid_price": 0.5, "high_price": 4.81, "market_price": 0.33, "direct_low_price": null, "updated_at": "2026-09-30T20:41:20.855498+00:00", "sub_type_name": "Normal" }, { "low_price": 0.48, "mid_price": 0.91, "high_price": 6, "market_price": 0.77, "direct_low_price": null, "updated_at": "2026-09-30T20:41:20.855498+00:00", "sub_type_name": "Cold Foil" } ], "url": "https://www.tcgplayer.com/product/702669/lorcana-tcg-attack-of-the-vine-woody-helping-a-friend" }, "cardmarket": { "product_name": "Woody - Helping a Friend", "prices": [ { "variant_type": "normal", "avg": 0.25, "low": 0.02, "trend": 0.19, "avg1": 0.12, "avg7": 0.29, "avg30": 0.3, "updated_at": "2026-09-30T14:50:06.484302+00:00" }, { "variant_type": "foil", "avg": 0.73, "low": 0.35, "trend": 0.88, "avg1": 0.83, "avg7": 0.79, "avg30": 0.83, "updated_at": "2026-09-30T14:50:06.484302+00:00" } ], "product_url": "https://www.cardmarket.com/en/Lorcana/Products/Singles/Attack-of-the-Vine/Woody-Helping-a-Friend" } } ``` > One entry in `tcgplayer.prices` per finish, identified by `sub_type_name`, and one entry in `cardmarket.prices` per finish, identified by `variant_type` (`normal`, `foil`). `updated_at` is when that price last changed, not when it was last checked. A CardMarket-only card has `tcgplayer: null` and empty `variants`. ### GET /lor/search Search cards by name or card number. Results have the same shape as `/lor/cards/:id`, prices included. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | Required | 2–100 characters. Card name (all words, any order) or card number | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 20, max: 100) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/lor/search?q=Helping&limit=2" ``` ### Response Example (`results` omitted): *200 OK* ```json { "query": "Helping", "results": [ { "id": "lor_c90d1341d751d70cfa4e0f5185655b07157821be2491b59a6d3e5a2d0b7ad781ced4871d9b135bf47694ccaab5cb", "card_info": { "name": "Woody - Helping a Friend", "clean_name": "Woody Helping a Friend", "set_name": "Attack of the Vine!", "set_code": "13", "set_id": "24666", "card_number": "1/207", "rarity": "Rare", "card_type": "Character", "product_type": "card", "variants": [ "Normal", "Cold Foil" ], "card_text": "[Hang On!] When you play this character, choose one of the following. If you have another Toy character in play, choose both instead:
• You may return a character card with cost 2 or less from your discard to your hand.
• You may play a character with cost 2 or less for free.", "ink_type": "Amber", "cost_ink": "4", "property": "Toy Story", "strength": "2", "willpower": "4", "lore_value": "2", "classification": "Storyborn;Hero;Toy", "character_version": "Helping a Friend", "inkwell_iconon_card": "No" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 0.01, "mid_price": 0.5, "high_price": 4.81, "market_price": 0.33, "direct_low_price": null, "updated_at": "2026-09-30T20:41:20.855498+00:00", "sub_type_name": "Normal" }, { "low_price": 0.48, "mid_price": 0.91, "high_price": 6, "market_price": 0.77, "direct_low_price": null, "updated_at": "2026-09-30T20:41:20.855498+00:00", "sub_type_name": "Cold Foil" } ], "url": "https://www.tcgplayer.com/product/702669/lorcana-tcg-attack-of-the-vine-woody-helping-a-friend" }, "cardmarket": { "product_name": "Woody - Helping a Friend", "prices": [ { "variant_type": "normal", "avg": 0.25, "low": 0.02, "trend": 0.19, "avg1": 0.12, "avg7": 0.29, "avg30": 0.3, "updated_at": "2026-09-30T14:50:06.484302+00:00" }, { "variant_type": "foil", "avg": 0.73, "low": 0.35, "trend": 0.88, "avg1": 0.83, "avg7": 0.79, "avg30": 0.83, "updated_at": "2026-09-30T14:50:06.484302+00:00" } ], "product_url": "https://www.cardmarket.com/en/Lorcana/Products/Singles/Attack-of-the-Vine/Woody-Helping-a-Friend" } } ], "pagination": { "page": 1, "limit": 2, "total": 4, "total_pages": 2 }, "metadata": { "total_count": 4, "tcg": 4, "cardmarket": 3, "tcg_only": 1, "cardmarket_only": 0, "both_sources": 3, "truncated": false } } ``` > `metadata.truncated: true` means more cards match than the search returns: add words to narrow it down. Words match anywhere in the name; a query shorter than 3 characters matches names and card numbers that **start** with it (`27` finds `27`, `027/264`, `0027`). Quotes are ignored; `*`, `%` and `_` are plain text, not wildcards. ### GET /lor/images/:id The card image, one resolution (`X-Image-Size: unsized`): the `size` parameter of the Pokémon image endpoint does not apply. Cached for 24 hours. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/lor/images/lor_c90d1341d751d70cfa4e0f5185655b07157821be2491b59a6d3e5a2d0b7ad781ced4871d9b135bf47694ccaab5cb" \ --output card ``` ## Ultra endpoints Available on Ultra and Business plans, or during the 7-day trial. The Pro plan covers Pokémon and One Piece only: with Pro these endpoints answer 403 with an `upgrade_url`. Ultra includes everything in Pro. Same parameters and response format as the Pokémon endpoints of the same name. | Endpoint | What it returns | | --- | --- | | `GET /lor/prices/:set` | TCGPlayer and CardMarket prices for every card of a set, one row per finish. `?source=tcg\|cm` | | `GET /lor/sets/:set/statistics` | Price statistics and rarity breakdown. Sealed products excluded. `?variant=normal\|foil` | | `GET /lor/sets/:set/completion-value` | Cost of one copy of every card in the set. Sealed products excluded. | | `GET /lor/sets/trending` | Sets whose CardMarket prices moved most: 7-day average against 30-day average, cards from 1 € up. `?period=7d` `?limit=` | | `GET /lor/analytics/top-cards` | Most expensive cards, or fastest-growing on CardMarket (7-day average against 30-day average, cards from 1 € up; `current_price` is the 7-day average). `?metric=price\|growth` `?source=tcg\|cm` `?limit=` | > Price history is a Pokémon feature: for this game there is no `/cards/:id/price-history`. Current prices are in the card detail and in `/lor/prices/:set`; `metric=growth` works with `source=cm` only, and trending supports `period=7d` only. ### GET /lor/prices/:set (first rows) *200 OK* ```json { "success": true, "source": "both", "set_code": "13", "set_id": "24666", "data": [ { "id": "lor_c90d1341d751d70cfa4e0f5185655b07157821be2491b59a6d3e5a2d0b7ad781ced4871d9b135bf47694ccaab5cb", "card_number": "1/207", "name": "Woody - Helping a Friend", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.01, "mid_price": 0.5, "high_price": 4.81, "market_price": 0.33, "direct_low_price": null, "updated_at": "2026-09-30T20:41:20.855498+00:00" }, "cardmarket": { "avg": 0.25, "low": 0.02, "trend": 0.19, "avg1": 0.12, "avg7": 0.29, "avg30": 0.3, "updated_at": "2026-09-30T14:50:06.484302+00:00" } }, { "id": "lor_c90d1341d751d70cfa4e0f5185655b07157821be2491b59a6d3e5a2d0b7ad781ced4871d9b135bf47694ccaab5cb", "card_number": "1/207", "name": "Woody - Helping a Friend", "product_type": "card", "variant": "Cold Foil", "tcgplayer": { "low_price": 0.48, "mid_price": 0.91, "high_price": 6, "market_price": 0.77, "direct_low_price": null, "updated_at": "2026-09-30T20:41:20.855498+00:00" }, "cardmarket": { "avg": 0.73, "low": 0.35, "trend": 0.88, "avg1": 0.83, "avg7": 0.79, "avg30": 0.83, "updated_at": "2026-09-30T14:50:06.484302+00:00" } }, { "id": "lor_c459d1f837e15a29c5331858f64c68e2313d3813248813cbe2fd1f9b42067296e6454dd0c3dcb4bbe16886cef913", "card_number": "2/207", "name": "Ming Lee - Proud Parent", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.01, "mid_price": 0.24, "high_price": 2.89, "market_price": 0.16, "direct_low_price": null, "updated_at": "2026-09-20T12:33:00.05056+00:00" }, "cardmarket": { "avg": 0.14, "low": 0.02, "trend": 0.09, "avg1": 0.07, "avg7": 0.23, "avg30": 0.15, "updated_at": "2026-09-30T14:50:06.484302+00:00" } } ], "total": 471 } ``` ### GET /lor/sets/:set/statistics *200 OK* ```json { "set_info": { "name": "Attack of the Vine!", "set_code": "13", "set_id": "24666", "total_cards": 252 }, "price_statistics": { "tcgplayer": { "avg_market_price": "29.46", "min_price": 0.03, "max_price": 2008.2, "most_expensive": { "id": "lor_a2da81fb0588eb50017a64cec25d464864f8827e6a5cdbde409dbae765ed6852d0ebd0fa160fa5eccb799fa3286b0f01", "name": "Belle & Beast - Certain as the Sun (Iconic)", "price": 2008.2 } }, "cardmarket": { "avg_price": "10.60", "min_price": 0.03, "max_price": 1177, "most_expensive": { "id": "lor_a2da81fb0588eb50017a64cec25d464864f8827e6a5cdbde409dbae765ed6852d0ebd0fa160fa5eccb799fa3286b0f01", "name": "Belle & Beast - Certain as the Sun (Iconic)", "price": 1177 }, "trend_direction": "down" } }, "rarity_breakdown": { "Rare": 52, "Common": 75, "Uncommon": 56, "Super Rare": 18, "Legendary": 12, "Epic": 18, "Enchanted": 18, "Iconic": 2, "None": 1 } } ``` ### GET /lor/sets/:set/completion-value *200 OK* ```json { "set_info": { "name": "Attack of the Vine!", "set_code": "13", "set_id": "24666", "total_cards": 252 }, "completion_cost": { "tcgplayer": { "currency": "USD", "low_estimate": 5697.04, "market_estimate": 7274.63, "high_estimate": 31349.89 }, "cardmarket": { "currency": "EUR", "low_estimate": 3081.32, "avg_estimate": 3126.15, "trend_estimate": 210.32 }, "note": "One copy per card (base finish). TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available." }, "breakdown_by_rarity": { "Rare": { "count": 52, "total_cost": 15.41 }, "Common": { "count": 75, "total_cost": 4.98 }, "Uncommon": { "count": 56, "total_cost": 11.41 }, "Super Rare": { "count": 18, "total_cost": 9.69 }, "Legendary": { "count": 12, "total_cost": 16.74 }, "Epic": { "count": 18, "total_cost": 50.28 }, "Enchanted": { "count": 18, "total_cost": 3527.69 }, "Iconic": { "count": 2, "total_cost": 3637.54 }, "None": { "count": 1, "total_cost": 0.89 } } } ``` ### GET /lor/analytics/top-cards *200 OK* ```json { "metric": "price", "source": "tcg", "top_cards": [ { "id": "lor_61a99b80aad2648e9cf5505cc26c230654079b3c74214de589006bba0df085a5de66d94ba8a10dcef02b", "card_info": { "name": "Elsa - Ice Maker (Foil)", "clean_name": "Elsa Ice Maker Foil", "set_name": "Disney Lorcana Promo Cards", "set_code": "DLPC", "set_id": "23234", "card_number": "2", "rarity": "Promo", "card_type": "Character", "product_type": "card", "variants": [ "Holofoil" ], "card_text": "Shift 4 (You may pay 4 Ink to play this on top of one of your characters named Elsa.)\r\n
[Winter Wall] Whenever this character quests, you may exert chosen character. If you do, and you have a character named Anna in play, the chosen character can't ready at the start of their next turn.", "ink_type": "Amethyst;Sapphire", "cost_ink": "7", "property": "Frozen", "strength": "5", "promo_type": "Disney Lorcana Challenge", "willpower": "5", "lore_value": "2", "classification": "Floodborn;Hero;Queen;Sorcerer", "character_version": "Ice Maker", "inkwell_iconon_card": "No" }, "current_price": 3979 }, { "id": "lor_aa88142032a55df7cd6b503cc2b898fd9f5c3a6bee8337d6e20404ade276d814e89c0fd76892b09638c57b98149bf115", "card_info": { "name": "Mickey Mouse - Brave Little Prince (Iconic)", "clean_name": "Mickey Mouse Brave Little Prince Iconic", "set_name": "Fabled", "set_code": "9", "set_id": "24348", "card_number": "242/204", "rarity": "Iconic", "card_type": "Character", "product_type": "card", "variants": [ "Holofoil" ], "card_text": "Shift 5\r\n
\r\nEvasive\r\n
\r\n[Crowning Achievement] While this character has a card under him, he gets +3 Strength, +3 Willpower, and +3 Lore.", "ink_type": "Ruby", "cost_ink": "3", "property": "Standard Characters", "strength": "2", "willpower": "2", "lore_value": "1", "classification": "Floodborn;Hero", "character_version": "Brave Little Prince", "inkwell_iconon_card": "Yes" }, "current_price": 3803.12 }, { "id": "lor_d118c5c714fb1fb326d83c45c2d98ee1c242208fcfba32f327f2d8626488e7742c33232380c63e9c83ae08b040c7db47", "card_info": { "name": "Buzz Lightyear - Jungle Ranger (Iconic)", "clean_name": "Buzz Lightyear Jungle Ranger Iconic", "set_name": "Wilds Unknown", "set_code": "12", "set_id": "24617", "card_number": "241/204", "rarity": "Iconic", "card_type": "Character", "product_type": "card", "variants": [ "Holofoil" ], "card_text": "Shift 5 Ink
\n[Take Charge] When you play this character, you may return an action card with cost 7 or less from your discard to your hand.
\n[Advanced Training] Whenever you play an action, chosen character gets +1 Lore this turn.", "ink_type": "Emerald", "cost_ink": "7", "property": "Toy Story", "strength": "7", "willpower": "5", "lore_value": "2", "classification": "Floodborn;Hero;Toy;Captain", "character_version": "Jungle Ranger", "inkwell_iconon_card": "No" }, "current_price": 3621.08 } ] } ``` ### GET /lor/analytics/top-cards?metric=growth&source=cm *200 OK* ```json { "metric": "growth", "source": "cm", "top_cards": [ { "id": "0fdbd1c462d6cc5e268b2dc76a3278d9088943f58347fd219a519e0cc4b90c43", "card_info": { "name": "Bucky - Squirrel Squeak Tutor (V.2)", "clean_name": "Bucky - Squirrel Squeak Tutor (V.2)", "set_name": "Rise of the Floodborn", "set_code": "2", "set_id": "23303", "card_number": "073", "rarity": null, "card_type": null, "product_type": "card", "variants": [], "card_text": null }, "current_price": 6.95, "change_7d": "+595.0%" }, { "id": "lor_fbf58ec03597f5448f28e150cd31ef7a69c6df94cd6d2d58df4e13d9ec7ca7530826fa7bba1a696bf1fcaeae973a", "card_info": { "name": "Minnie Mouse - Wild-Eyed Diver", "clean_name": "Minnie Mouse Wild Eyed Diver", "set_name": "Illumineer's Quest: Deep Trouble", "set_code": "Q1", "set_id": "23528", "card_number": "12/31", "rarity": "Quest", "card_type": "Character", "product_type": "card", "variants": [ "Normal" ], "card_text": "This card features a gold back and is not tournament legal.\r\n
\r\n
[Confusing Presence] When you play this character, each opposing player loses 2 lore.", "cost_ink": "7", "property": "Standard Characters", "strength": "6", "willpower": "7", "lore_value": "2", "flavor_text": "“The first—and best—of my entangled glimmers.”
—Ursula
", "classification": "Hero;Entangled", "character_version": "Wild-Eyed Diver", "inkwell_iconon_card": "Yes" }, "current_price": 14.97, "change_7d": "+226.1%" }, { "id": "lor_efd8665c54c9cf1a08dc85833c91c19ce9450f1e8a93bea34d4eafd3d6d91db396434fe3e3e3f9f18eb4aa", "card_info": { "name": "Yzma - Alchemist", "clean_name": "Yzma Alchemist", "set_name": "Disney Lorcana Promo Cards", "set_code": "DLPC", "set_id": "23234", "card_number": "10", "rarity": "Promo", "card_type": "Character", "product_type": "card", "variants": [ "Cold Foil" ], "card_text": "[You're Excused] Whenever this character quests, look at the top card of your deck. Put it on either the top or the bottom of your deck.", "ink_type": "Amethyst", "cost_ink": "2", "property": "Emperor's New Groove", "strength": "2", "promo_type": "League Promo", "willpower": "2", "lore_value": "1", "flavor_text": "\"When I want your opinion, I will give it to you!\"", "classification": "Dreamborn;Villain;Sorcerer", "character_version": "Alchemist", "inkwell_iconon_card": "Yes" }, "current_price": 23.9, "change_7d": "+213.2%" } ] } ``` ### GET /lor/sets/trending *200 OK* ```json { "period": "7d", "trending_sets": [ { "set_name": "Illumineer's Quest: Deep Trouble", "set_code": "Q1", "set_id": "23528", "card_count": 7, "cardmarket": { "price_change": "+32.5%", "avg_price_current": 5.11, "avg_price_previous": 3.86, "top_movers": [ { "name": "Minnie Mouse - Wild-Eyed Diver", "change": "+226.1%" }, { "name": "Ursula - Ruler of Lorcana", "change": "-64.0%" }, { "name": "Mulan - Elite Archer (V.2)", "change": "+16.3%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } }, { "set_name": "Archazia's Island", "set_code": "7", "set_id": "24011", "card_count": 15, "cardmarket": { "price_change": "+7.1%", "avg_price_current": 2.81, "avg_price_previous": 2.62, "top_movers": [ { "name": "Lady - Miss Park Avenue", "change": "-20.1%" }, { "name": "Ratigan - Nefarious Criminal (V.1)", "change": "+19.5%" }, { "name": "Donald Duck - Flustered Sorcerer (V.1)", "change": "+18.8%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } } ] } ``` ## Data Notes > **Prices.** TCGPlayer and CardMarket prices are refreshed daily. CardMarket has one entry per finish (`normal`, `foil`); a finish CardMarket does not price is left out, so `cardmarket.prices` can be empty. `updated_at` is when that price last changed, not when it was last checked: a stable price keeps an older date. > **`product_type`.** Cards and sealed products are told apart using TCGPlayer data, then CardTrader. Tokens, emblems and oversized cards count as `"card"`. For the very few products whose type cannot be determined, `product_type` is `null`, not `"card"`. > **CardMarket-only sets.** Sets with a negative `set_id` exist only on CardMarket: their cards have 64-character IDs and `tcgplayer: null`. > **Missing links.** `cardmarket.product_url` is absent for some cards; the card data is still valid. Sets with no cards are not listed: they appear as soon as cards are added. ## Disney Lorcana API FAQ ### Is there a free Disney Lorcana price API? Yes. The free tier (100 requests/hour, 1,000/day) opens the Disney Lorcana sets, cards, search and images endpoints, with TCGPlayer and CardMarket prices refreshed daily. Prices by set, set statistics, completion value, trending sets and top cards need the Ultra plan (€29/month) or its 7-day trial. ### Does the Disney Lorcana API include CardMarket prices? Yes. Cards return TCGPlayer (USD) prices for every finish and CardMarket (EUR) prices for normal and foil, where that market lists the card. Cards sold only on CardMarket have a 64-character hex id and no TCGPlayer price. ### How do I find the id of a Disney Lorcana card? Search with /lor/search?q=… or list a set with /lor/sets/:set. Each card has an id (lor_ + hex for cards on TCGPlayer) to pass to /lor/cards/:id and /lor/images/:id. ### Can I use the same API key for other games? Yes. One PokéWallet API key works for all 12 games, Pokémon and One Piece included, and the rate limits are shared across them. --- # Flesh and Blood API Documentation Source: https://pokewallet.io/api-docs/flesh-and-blood REST reference for the Flesh and Blood API: sets, cards, search and images, with prices from TCGPlayer and CardMarket. Same API key as the Pokémon and One Piece APIs. In short The Flesh and Blood API returns 128 sets with their cards, search and images, and TCGPlayer (USD) and CardMarket (EUR) prices refreshed daily. These endpoints are free (100 requests/hour) with the same key as the other 11 games; prices by set and set analytics need the Ultra plan (€29/month) or its 7-day trial. At a glance - **Base path:** `https://api.pokewallet.io/fab` - **Sets:** 128 Flesh and Blood sets - **Card IDs:** `fab_` + hex for cards on TCGPlayer; 64 hex characters for CardMarket-only cards - **Prices:** TCGPlayer (USD) for every finish and CardMarket (EUR) for `normal` and `foil`, refreshed daily - **Free on every plan:** Sets, set cards, card details, search and images - **Ultra plan or 7-day trial:** Prices by set, set statistics, completion value, trending sets and top cards - **API key:** The same key as the Pokémon and One Piece APIs, with shared rate limits Updated Oct 19, 2026 ## Quick Start Get started with PokéWallet API in 4 simple steps: ### Create an Account Sign up for free to start using the API. Upgrade anytime from your dashboard. [Sign Up Now](https://pokewallet.io/auth/login?source=pokemon) ### Generate an API Key Create your first API key from the dashboard. ### Make Your First Request Start querying the API with your key. *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/fab/sets" ``` ### Join the Discord Community Stay up to date with new features, ask for help, and connect with other developers. [Join Discord](https://discord.gg/znDxEjmDVP) > **Flesh and Blood PRO endpoints: Ultra plan required** > > The **Pro plan does not include them**: Pro covers Pokémon and One Piece only. Ultra (€29/month) includes everything in Pro plus the paid endpoints of **all 12 games**. Free endpoints (sets, cards, search, images) work on every plan. > > [Compare plans →](https://pokewallet.io/pricing) ## Flesh and Blood All Flesh and Blood endpoints live under `/fab`. Same API key, same rate limits and the same response format as the Pokémon endpoints. ### Card IDs | Format | Example | Used for | | --- | --- | --- | | `fab_` + hex | `fab_cbeed215ffe6d1c92272…` | Every card with a TCGPlayer product, even if it also has CardMarket data | | 64 hex characters, no prefix | `e26f12b8b1fabf19…` | Cards that exist only on CardMarket | > A `fab_…` ID only works under `/fab/`. Finishes of the same product (Normal, Foil, …) are one card with one ID; each finish has its own TCGPlayer price. If you request a card by its CardMarket ID and it is linked to a TCGPlayer product, the response uses the canonical `fab_…` ID. ### Response Format Same shape as the Pokémon API: `card_info`, `images`, `tcgplayer.prices` and `cardmarket.prices` as arrays, `pagination`, errors as `{ "error", "message" }`. Differences: | Field | Flesh and Blood | | --- | --- | | Game fields in `card_info` | Instead of Pokémon's `hp`, `stage`, `attacks`…, the game's own fields in snake_case (present when the card has them): `class`, `pitch_value`, `defense_value`, `cost`, `card_sub_type`, `power`, `talent`, `flavor_text`, `life`, `intellect` | | `card_type`, `card_text` | Filled from the game's card type and rules text. `card_text` may contain HTML (``, ``…) as provided by TCGPlayer. | | `card_info.variants`, `card_info.set_id` | Always present, on every endpoint | | `product_type` | `"card"`, `"sealed"` or `null` when unknown — see [Data Notes](https://pokewallet.io/api-docs/flesh-and-blood#fab-data-notes) | | `release_date` | ISO format, e.g. `"2025-03-07T00:00:00"` (Pokémon uses `"16th June, 2023"`) | | `images.languages` | `["en"]`, or `[]` when there is no image | ## Flesh and Blood Endpoints ### GET /fab/sets All Flesh and Blood sets. ### Response Fields: | Field | Type | Description | | --- | --- | --- | | `name` | string | Set name | | `set_code` | string \| null | Short code. **Not unique**: several sets can share it. | | `set_id` | string | Unique set identifier. Negative for sets that exist only on CardMarket. | | `card_count` | integer | Cards in the set (sealed products excluded). Omitted, not 0, if temporarily unavailable. | | `sealed_count` | integer | Sealed products in the set (booster boxes, displays, decks). Omitted, not 0, if temporarily unavailable. | | `language` | string \| null | Set language | | `release_date` | string \| null | ISO date | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/fab/sets" ``` ### Response Example (first two sets): *200 OK* ```json { "success": true, "data": [ { "name": "1st Strike", "set_code": null, "set_id": "23548", "card_count": 62, "sealed_count": 3, "language": "eng", "release_date": "2024-08-23T00:00:00" }, { "name": "Arcane Rising", "set_code": "ARC", "set_id": "2725", "card_count": 284, "sealed_count": 6, "language": "eng", "release_date": "2020-03-27T00:00:00" } ], "total": 128 } ``` ### GET /fab/sets/:set Cards of one set, paginated. Prices are empty in set listings, as on the Pokémon API: use `/fab/cards/:id` for prices. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `set` | string | Required | `set_id` (recommended, always unique) or `set_code` (exact match, case-insensitive) | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 50, max: 200) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/fab/sets/24762?limit=1" ``` ### Response Example: *200 OK* ```json { "success": true, "set": { "name": "Usurp the Shadow Throne", "set_code": "IAR", "set_id": "24762", "total_cards": 289, "language": "eng", "release_date": "2026-09-25T00:00:00" }, "cards": [ { "id": "fab_cbeed215ffe6d1c92272094b6604811d66d9c6ce057aff7ca9d37636f0929c568cebf5ee17615d17780a3561ff762f", "card_info": { "name": "Soul of Existence", "clean_name": "Soul of Existence", "set_name": "Usurp the Shadow Throne", "set_code": "IAR", "set_id": "24762", "card_number": "IAR000", "rarity": "Fabled", "card_type": "Resource", "product_type": "card", "variants": [ "Rainbow Foil" ], "card_text": "Legendary (You may only have 1 Soul of Existence in your deck.)
When this is pitched, lose 1LIFE.", "talent": "Shadow", "card_sub_type": "Gem", "pitch_value": "4" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/706637/flesh-and-blood-tcg-usurp-the-shadow-throne-soul-of-existence" }, "cardmarket": { "product_name": "Soul of Existence (Rainbow Foil)", "prices": [], "product_url": "https://www.cardmarket.com/en/FleshAndBlood/Products/Singles/Usurp-the-Shadow-Throne/Soul-of-Existence-Rainbow-Foil" } } ], "pagination": { "page": 1, "limit": 1, "total": 289, "total_pages": 289 } } ``` ### Disambiguation Response: When a `set_code` is shared by several sets, the API returns the candidates instead of a set (status 200, as on the Pokémon API). Call again with the `set_id` you need. *200 OK — /fab/sets/GEM* ```json { "disambiguation": true, "message": "Multiple sets found for set_code 'GEM'. Use set_id to specify which one.", "matches": [ { "set_id": "24176", "set_code": "GEM", "name": "GEM Pack 1", "language": "eng", "release_date": "2025-02-01T00:00:00" }, { "set_id": "24334", "set_code": "GEM", "name": "GEM Pack 2", "language": "eng", "release_date": "2025-06-02T00:00:00" } ], "total": 6 } ``` ### GET /fab/cards/:id Full card with prices. `id` is a `fab_…` ID or a 64-character CardMarket ID. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/fab/cards/fab_cbeed215ffe6d1c92272094b6604811d66d9c6ce057aff7ca9d37636f0929c568cebf5ee17615d17780a3561ff762f" ``` ### Response Example: *200 OK* ```json { "id": "fab_cbeed215ffe6d1c92272094b6604811d66d9c6ce057aff7ca9d37636f0929c568cebf5ee17615d17780a3561ff762f", "card_info": { "name": "Soul of Existence", "clean_name": "Soul of Existence", "set_name": "Usurp the Shadow Throne", "set_code": "IAR", "set_id": "24762", "card_number": "IAR000", "rarity": "Fabled", "card_type": "Resource", "product_type": "card", "variants": [ "Rainbow Foil" ], "card_text": "Legendary (You may only have 1 Soul of Existence in your deck.)
When this is pitched, lose 1LIFE.", "talent": "Shadow", "card_sub_type": "Gem", "pitch_value": "4" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 178.45, "mid_price": 217.75, "high_price": 390, "market_price": 217.75, "direct_low_price": null, "updated_at": "2026-09-30T20:40:53.537305+00:00", "sub_type_name": "Rainbow Foil" } ], "url": "https://www.tcgplayer.com/product/706637/flesh-and-blood-tcg-usurp-the-shadow-throne-soul-of-existence" }, "cardmarket": { "product_name": "Soul of Existence (Rainbow Foil)", "prices": [ { "variant_type": "normal", "avg": 198, "low": 169, "trend": 161.96, "avg1": null, "avg7": null, "avg30": null, "updated_at": "2026-09-30T14:50:02.568852+00:00" } ], "product_url": "https://www.cardmarket.com/en/FleshAndBlood/Products/Singles/Usurp-the-Shadow-Throne/Soul-of-Existence-Rainbow-Foil" } } ``` > One entry in `tcgplayer.prices` per finish, identified by `sub_type_name`, and one entry in `cardmarket.prices` per finish, identified by `variant_type` (`normal`, `foil`). `updated_at` is when that price last changed, not when it was last checked. A CardMarket-only card has `tcgplayer: null` and empty `variants`. ### GET /fab/search Search cards by name or card number. Results have the same shape as `/fab/cards/:id`, prices included. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | Required | 2–100 characters. Card name (all words, any order) or card number | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 20, max: 100) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/fab/search?q=Existence&limit=2" ``` ### Response Example (`results` omitted): *200 OK* ```json { "query": "Existence", "results": [ { "id": "42c7548d4561800f59e5a6e3ead9bcbacc1d987a057246c4bc456456b88a0067", "card_info": { "name": "Invert Existence", "clean_name": "Invert Existence", "set_name": "History Pack 2 - Black Label", "set_code": "2hp-bl", "set_id": "-11", "card_number": "2HP248", "rarity": null, "card_type": null, "product_type": "card", "variants": [], "card_text": null }, "images": { "languages": [ "en" ] }, "tcgplayer": null, "cardmarket": { "product_name": "Invert Existence", "prices": [ { "variant_type": "normal", "avg": 1.83, "low": 0.2, "trend": 0.91, "avg1": 0.5, "avg7": 0.6, "avg30": 0.55, "updated_at": "2026-09-30T14:50:02.240156+00:00" } ] } } ], "pagination": { "page": 1, "limit": 2, "total": 12, "total_pages": 6 }, "metadata": { "total_count": 12, "tcg": 6, "cardmarket": 12, "tcg_only": 0, "cardmarket_only": 6, "both_sources": 6, "truncated": false } } ``` > `metadata.truncated: true` means more cards match than the search returns: add words to narrow it down. Words match anywhere in the name; a query shorter than 3 characters matches names and card numbers that **start** with it (`27` finds `27`, `027/264`, `0027`). Quotes are ignored; `*`, `%` and `_` are plain text, not wildcards. ### GET /fab/images/:id The card image, one resolution (`X-Image-Size: unsized`): the `size` parameter of the Pokémon image endpoint does not apply. Cached for 24 hours. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/fab/images/fab_cbeed215ffe6d1c92272094b6604811d66d9c6ce057aff7ca9d37636f0929c568cebf5ee17615d17780a3561ff762f" \ --output card ``` ## Ultra endpoints Available on Ultra and Business plans, or during the 7-day trial. The Pro plan covers Pokémon and One Piece only: with Pro these endpoints answer 403 with an `upgrade_url`. Ultra includes everything in Pro. Same parameters and response format as the Pokémon endpoints of the same name. | Endpoint | What it returns | | --- | --- | | `GET /fab/prices/:set` | TCGPlayer and CardMarket prices for every card of a set, one row per finish. `?source=tcg\|cm` | | `GET /fab/sets/:set/statistics` | Price statistics and rarity breakdown. Sealed products excluded. `?variant=normal\|foil` | | `GET /fab/sets/:set/completion-value` | Cost of one copy of every card in the set. Sealed products excluded. | | `GET /fab/sets/trending` | Sets whose CardMarket prices moved most: 7-day average against 30-day average, cards from 1 € up. `?period=7d` `?limit=` | | `GET /fab/analytics/top-cards` | Most expensive cards, or fastest-growing on CardMarket (7-day average against 30-day average, cards from 1 € up; `current_price` is the 7-day average). `?metric=price\|growth` `?source=tcg\|cm` `?limit=` | > Price history is a Pokémon feature: for this game there is no `/cards/:id/price-history`. Current prices are in the card detail and in `/fab/prices/:set`; `metric=growth` works with `source=cm` only, and trending supports `period=7d` only. ### GET /fab/prices/:set (first rows) *200 OK* ```json { "success": true, "source": "both", "set_code": "IAR", "set_id": "24762", "data": [ { "id": "fab_cbeed215ffe6d1c92272094b6604811d66d9c6ce057aff7ca9d37636f0929c568cebf5ee17615d17780a3561ff762f", "card_number": "IAR000", "name": "Soul of Existence", "product_type": "card", "variant": "Rainbow Foil", "tcgplayer": { "low_price": 178.45, "mid_price": 217.75, "high_price": 390, "market_price": 217.75, "direct_low_price": null, "updated_at": "2026-09-30T20:40:53.537305+00:00" }, "cardmarket": null }, { "id": "fab_073536990a0158ac4bfaf9f657e23e4b6626c514aeab971f5ab7a651a20aa632559bdcbfea962c6198aefa74301098", "card_number": "IAR001", "name": "Arknight Shard (Blue)", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 450, "mid_price": 474.99, "high_price": 500, "market_price": 424.63, "direct_low_price": null, "updated_at": "2026-09-30T20:40:53.537305+00:00" }, "cardmarket": { "avg": null, "low": 340, "trend": 299, "avg1": null, "avg7": null, "avg30": null, "updated_at": "2026-09-30T14:50:02.568852+00:00" } }, { "id": "fab_bb2df53d370865ff255cc1667bee6660edfb7c063919d1532a46cec83c6ffcb1287ed6566d89d53d8707b8cbd99cb3", "card_number": "IAR002", "name": "Levia", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.09, "mid_price": 0.3, "high_price": 0.4, "market_price": 0.29, "direct_low_price": null, "updated_at": "2026-09-30T20:40:53.537305+00:00" }, "cardmarket": { "avg": 0.73, "low": 0.02, "trend": 0.73, "avg1": null, "avg7": null, "avg30": null, "updated_at": "2026-09-30T14:50:02.568852+00:00" } } ], "total": 498 } ``` ### GET /fab/sets/:set/statistics *200 OK* ```json { "set_info": { "name": "Usurp the Shadow Throne", "set_code": "IAR", "set_id": "24762", "total_cards": 286 }, "price_statistics": { "tcgplayer": { "avg_market_price": "10.91", "min_price": 0.12, "max_price": 424.63, "most_expensive": { "id": "fab_073536990a0158ac4bfaf9f657e23e4b6626c514aeab971f5ab7a651a20aa632559bdcbfea962c6198aefa74301098", "name": "Arknight Shard (Blue)", "price": 424.63 } }, "cardmarket": { "avg_price": "6.86", "min_price": 0.04, "max_price": 198, "most_expensive": { "id": "fab_cbeed215ffe6d1c92272094b6604811d66d9c6ce057aff7ca9d37636f0929c568cebf5ee17615d17780a3561ff762f", "name": "Soul of Existence", "price": 198 }, "trend_direction": null } }, "rarity_breakdown": { "Fabled": 3, "Basic": 16, "Marvel": 16, "Majestic": 46, "Rare": 67, "Common": 133, "Legendary": 5 } } ``` ### GET /fab/sets/:set/completion-value *200 OK* ```json { "set_info": { "name": "Usurp the Shadow Throne", "set_code": "IAR", "set_id": "24762", "total_cards": 286 }, "completion_cost": { "tcgplayer": { "currency": "USD", "low_estimate": 3197.98, "market_estimate": 3474.94, "high_estimate": 19630.93 }, "cardmarket": { "currency": "EUR", "low_estimate": 1676.1, "avg_estimate": 2061.88, "trend_estimate": 1760.26 }, "note": "One copy per card (base finish). TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available." }, "breakdown_by_rarity": { "Fabled": { "count": 3, "total_cost": 642.38 }, "Basic": { "count": 16, "total_cost": 15.31 }, "Marvel": { "count": 16, "total_cost": 1018.06 }, "Majestic": { "count": 46, "total_cost": 465.19 }, "Rare": { "count": 67, "total_cost": 59.05 }, "Common": { "count": 133, "total_cost": 26.15 }, "Legendary": { "count": 5, "total_cost": 401.92 } } } ``` ### GET /fab/analytics/top-cards *200 OK* ```json { "metric": "price", "source": "tcg", "top_cards": [ { "id": "fab_8bdfd3eae23f9a91b4acf860f6b4516074c3ee03c16530abef7ae66d4722056488febdcf38d6e51d8fbd1c634aaf", "card_info": { "name": "Fyendal's Spring Tunic", "clean_name": "Fyendals Spring Tunic", "set_name": "Welcome to Rathe", "set_code": "WTR", "set_id": "2726", "card_number": "WTR150", "rarity": "Legendary", "card_type": "Equipment", "product_type": "card", "variants": [ "1st Edition Cold Foil", "Unlimited Edition Rainbow Foil" ], "card_text": "At the start of your turn, if Fyendal's Spring Tunic has less than 3 energy counters on it, you may put an energy counter on it.\r\n
Instant - Remove 3 energy counters from Fyendal's Spring Tunic: Gain [1 Resource]\r\n
Blade Break (If you defend with Fyendal's Spring Tunic, destroy it when the combat chain closes.)", "class": "Generic", "card_sub_type": "Chest", "defense_value": "1" }, "current_price": 3999.99 }, { "id": "fab_780e20bb93f42bc27d6dd27577c0ec360899a1590a9af51af652908ae8c30478edb4a6e590117198fb01bbc8e3438c", "card_info": { "name": "Testament of Valahai (Marvel)", "clean_name": "Testament of Valahai Marvel", "set_name": "Mastery Pack Guardian", "set_code": null, "set_id": "24330", "card_number": "MPG004", "rarity": "Marvel", "card_type": "Hero", "product_type": "card", "variants": [ "Cold Foil" ], "card_text": "If you control three or more Seismic Surge tokens, this gets +2DEFENSE. If you control six or more, instead this gets +4DEFENSE.\r\n
\r\nGuardwell (When the combat chain closes, if this defended, put -1DEFENSE counters on it equal to its DEFENSE.)", "class": "Guardian", "defense_value": "1" }, "current_price": 1669.69 }, { "id": "fab_beaac845846588893b9c714cadabbf32ad3e3e0dd6c04c9c62a55d095c10ac60aaf77e210b2e4f2de206f67a42f796be45a2", "card_info": { "name": "Baalghor, Omen of the End (Marvel)", "clean_name": "Baalghor Omen of the End Marvel", "set_name": "Omens of the Third Age", "set_code": "OMN", "set_id": "24640", "card_number": "IAR159-MV", "rarity": "Marvel", "card_type": "Hero", "product_type": "card", "variants": [ "Cold Foil" ], "card_text": "Whenever you pitch a card, banish it.
Attack action cards played from your banished zone get +3POWER.", "life": "33", "talent": "Shadow", "intellect": "3", "card_sub_type": "Young;Demon" }, "current_price": 1624 } ] } ``` ### GET /fab/analytics/top-cards?metric=growth&source=cm *200 OK* ```json { "metric": "growth", "source": "cm", "top_cards": [ { "id": "fab_cf301a611a02829a730a5c52456190fd729f149d3aaf659732da48b7bd868885b16904de44ad9ae069fab048f13350", "card_info": { "name": "Heirloom of Rabbit Hide", "clean_name": "Heirloom of Rabbit Hide", "set_name": "Part the Mistveil", "set_code": "MST", "set_id": "23476", "card_number": "MST028", "rarity": "Rare", "card_type": "Equipment", "product_type": "card", "variants": [ "Normal", "Cold Foil" ], "card_text": "Cloaked (Equip this face-down.)
\r\nWhile this is equipped face-down, at the start of your turn, if you have exactly 1LIFE, you may turn this face-up.
\r\nWard 4 (If you would be dealt damage, destroy this to prevent 4 of that damage.)", "class": "Illusionist", "talent": "Mystic", "card_sub_type": "Chest", "pitch_value": "-" }, "current_price": 10.6, "change_7d": "+259.3%" }, { "id": "fab_406e20cef157e6f5438a456842b70026c712db5d41b09c5de4c5f8af3854f9f9aa4ef26c0f279da3456064d79b2a41", "card_info": { "name": "Silverwind Shuriken", "clean_name": "Silverwind Shuriken", "set_name": "Outsiders", "set_code": "OUT", "set_id": "22893", "card_number": "OUT054", "rarity": "Majestic", "card_type": "Action", "product_type": "card", "variants": [ "Normal", "Cold Foil", "Rainbow Foil" ], "card_text": "Attack Reaction — Destroy Silverwind Shuriken: Target attack action card with combo gains +1 [Power].", "cost": "0", "class": "Ninja", "card_sub_type": "Shuriken Item", "pitch_value": "3" }, "current_price": 15.73, "change_7d": "+163.0%" }, { "id": "fab_0fdf91c9810d825b2ffb86202713a70ef416b8bee56d54a013b873e7679c01ffe16eb052636b6f83c4993c8176f085", "card_info": { "name": "Ominous Excavation (Blue)", "clean_name": "Ominous Excavation Blue", "set_name": "Omens of the Third Age", "set_code": "OMN", "set_id": "24640", "card_number": "OMN217", "rarity": "Rare", "card_type": "Instant", "product_type": "card", "variants": [ "Normal", "Rainbow Foil" ], "card_text": "You may shuffle an instant card from your graveyard into your deck.
If an aura you control was destroyed this turn, create a Ponder token.", "class": "Generic", "pitch_value": "3" }, "current_price": 6.44, "change_7d": "+153.5%" } ] } ``` ### GET /fab/sets/trending *200 OK* ```json { "period": "7d", "trending_sets": [ { "set_name": "Armory Deck: Maxx Nitro", "set_code": null, "set_id": "24253", "card_count": 11, "cardmarket": { "price_change": "-21.8%", "avg_price_current": 3.29, "avg_price_previous": 4.21, "top_movers": [ { "name": "Clamp Press (Rainbow Foil)", "change": "-73.6%" }, { "name": "Clamp Press (Regular)", "change": "-55.9%" }, { "name": "T-Bone (Red) (Regular)", "change": "+32.4%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } }, { "set_name": "Armory Deck: Dash", "set_code": "ADD", "set_id": "23738", "card_count": 6, "cardmarket": { "price_change": "-20.2%", "avg_price_current": 2.3, "avg_price_previous": 2.88, "top_movers": [ { "name": "Heavy Industry Surveillance (Rainbow Foil)", "change": "-36.4%" }, { "name": "Cerebellum Processor (Rainbow Foil)", "change": "-27.0%" }, { "name": "Fast and Furious (Rainbow Foil)", "change": "-26.1%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } } ] } ``` ## Data Notes > **Prices.** TCGPlayer and CardMarket prices are refreshed daily. CardMarket has one entry per finish (`normal`, `foil`); a finish CardMarket does not price is left out, so `cardmarket.prices` can be empty. `updated_at` is when that price last changed, not when it was last checked: a stable price keeps an older date. > **`product_type`.** Cards and sealed products are told apart using TCGPlayer data, then CardTrader. Tokens, emblems and oversized cards count as `"card"`. For the very few products whose type cannot be determined, `product_type` is `null`, not `"card"`. > **CardMarket-only sets.** Sets with a negative `set_id` exist only on CardMarket: their cards have 64-character IDs and `tcgplayer: null`. > **Missing links.** `cardmarket.product_url` is absent for some cards; the card data is still valid. Sets with no cards are not listed: they appear as soon as cards are added. ## Flesh and Blood API FAQ ### Is there a free Flesh and Blood price API? Yes. The free tier (100 requests/hour, 1,000/day) opens the Flesh and Blood sets, cards, search and images endpoints, with TCGPlayer and CardMarket prices refreshed daily. Prices by set, set statistics, completion value, trending sets and top cards need the Ultra plan (€29/month) or its 7-day trial. ### Does the Flesh and Blood API include CardMarket prices? Yes. Cards return TCGPlayer (USD) prices for every finish and CardMarket (EUR) prices for normal and foil, where that market lists the card. Cards sold only on CardMarket have a 64-character hex id and no TCGPlayer price. ### How do I find the id of a Flesh and Blood card? Search with /fab/search?q=… or list a set with /fab/sets/:set. Each card has an id (fab_ + hex for cards on TCGPlayer) to pass to /fab/cards/:id and /fab/images/:id. ### Can I use the same API key for other games? Yes. One PokéWallet API key works for all 12 games, Pokémon and One Piece included, and the rate limits are shared across them. --- # Dragon Ball Super API Documentation Source: https://pokewallet.io/api-docs/dragon-ball-super REST reference for the Dragon Ball Super API: sets, cards, search and images, with prices from TCGPlayer and CardMarket. Same API key as the Pokémon and One Piece APIs. In short The Dragon Ball Super API returns 198 sets with their cards, search and images, and TCGPlayer (USD) and CardMarket (EUR) prices refreshed daily. These endpoints are free (100 requests/hour) with the same key as the other 11 games; prices by set and set analytics need the Ultra plan (€29/month) or its 7-day trial. At a glance - **Base path:** `https://api.pokewallet.io/dbs` - **Sets:** 198 Dragon Ball Super sets - **Card IDs:** `dbs_` + hex for cards on TCGPlayer; 64 hex characters for CardMarket-only cards - **Prices:** TCGPlayer (USD) for every finish and CardMarket (EUR) for `normal` and `foil`, refreshed daily - **Free on every plan:** Sets, set cards, card details, search and images - **Ultra plan or 7-day trial:** Prices by set, set statistics, completion value, trending sets and top cards - **API key:** The same key as the Pokémon and One Piece APIs, with shared rate limits Updated Oct 19, 2026 ## Quick Start Get started with PokéWallet API in 4 simple steps: ### Create an Account Sign up for free to start using the API. Upgrade anytime from your dashboard. [Sign Up Now](https://pokewallet.io/auth/login?source=pokemon) ### Generate an API Key Create your first API key from the dashboard. ### Make Your First Request Start querying the API with your key. *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/dbs/sets" ``` ### Join the Discord Community Stay up to date with new features, ask for help, and connect with other developers. [Join Discord](https://discord.gg/znDxEjmDVP) > **Dragon Ball Super PRO endpoints: Ultra plan required** > > The **Pro plan does not include them**: Pro covers Pokémon and One Piece only. Ultra (€29/month) includes everything in Pro plus the paid endpoints of **all 12 games**. Free endpoints (sets, cards, search, images) work on every plan. > > [Compare plans →](https://pokewallet.io/pricing) ## Dragon Ball Super All Dragon Ball Super endpoints live under `/dbs`. Same API key, same rate limits and the same response format as the Pokémon endpoints. ### Card IDs | Format | Example | Used for | | --- | --- | --- | | `dbs_` + hex | `dbs_0990dc88bb22b009f369…` | Every card with a TCGPlayer product, even if it also has CardMarket data | | 64 hex characters, no prefix | `e26f12b8b1fabf19…` | Cards that exist only on CardMarket | > A `dbs_…` ID only works under `/dbs/`. Finishes of the same product (Normal, Foil, …) are one card with one ID; each finish has its own TCGPlayer price. If you request a card by its CardMarket ID and it is linked to a TCGPlayer product, the response uses the canonical `dbs_…` ID. ### Response Format Same shape as the Pokémon API: `card_info`, `images`, `tcgplayer.prices` and `cardmarket.prices` as arrays, `pagination`, errors as `{ "error", "message" }`. Differences: | Field | Dragon Ball Super | | --- | --- | | Game fields in `card_info` | Instead of Pokémon's `hp`, `stage`, `attacks`…, the game's own fields in snake_case (present when the card has them): `color`, `power`, `combo_power`, `energy_color_cost`, `character`, `era`, `special_trait`, `combo_energy`, `character_traits`, `cost`, `bandai_disclaimer`, `z_energy_cost`, `gtin` | | `card_type`, `card_text` | Filled from the game's card type and rules text. `card_text` may contain HTML (``, ``…) as provided by TCGPlayer. | | `card_info.variants`, `card_info.set_id` | Always present, on every endpoint | | `product_type` | `"card"`, `"sealed"` or `null` when unknown — see [Data Notes](https://pokewallet.io/api-docs/dragon-ball-super#dbs-data-notes) | | `release_date` | ISO format, e.g. `"2025-03-07T00:00:00"` (Pokémon uses `"16th June, 2023"`) | | `images.languages` | `["en"]`, or `[]` when there is no image | ## Dragon Ball Super Endpoints ### GET /dbs/sets All Dragon Ball Super sets. ### Response Fields: | Field | Type | Description | | --- | --- | --- | | `name` | string | Set name | | `set_code` | string \| null | Short code. **Not unique**: several sets can share it. | | `set_id` | string | Unique set identifier. Negative for sets that exist only on CardMarket. | | `card_count` | integer | Cards in the set (sealed products excluded). Omitted, not 0, if temporarily unavailable. | | `sealed_count` | integer | Sealed products in the set (booster boxes, displays, decks). Omitted, not 0, if temporarily unavailable. | | `language` | string \| null | Set language | | `release_date` | string \| null | ISO date | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/dbs/sets" ``` ### Response Example (first two sets): *200 OK* ```json { "success": true, "data": [ { "name": "5th Anniversary Set", "set_code": "DBS-BE21", "set_id": "3109", "card_count": 79, "sealed_count": 5, "language": "eng", "release_date": "2022-10-28T00:00:00" }, { "name": "Assault of the Saiyans", "set_code": "DBS-B07", "set_id": "2473", "card_count": 181, "sealed_count": 5, "language": "eng", "release_date": "2019-08-02T00:00:00" } ], "total": 198 } ``` ### GET /dbs/sets/:set Cards of one set, paginated. Prices are empty in set listings, as on the Pokémon API: use `/dbs/cards/:id` for prices. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `set` | string | Required | `set_id` (recommended, always unique) or `set_code` (exact match, case-insensitive) | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 50, max: 200) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/dbs/sets/2565?limit=1" ``` ### Response Example: *200 OK* ```json { "success": true, "set": { "name": "Tournament Promotion Cards", "set_code": "TPR", "set_id": "2565", "total_cards": 1361, "language": "eng", "release_date": null }, "cards": [ { "id": "dbs_4d481cf07b7bc46288aae1a1739bc154ddb7f629fd7c61842c4f3dd5c9833f8fa23d49d019fcd59266", "card_info": { "name": "DBSCG Championship 2019 Warrior (Merit Card) - Universe 1 \"Iwan\"", "clean_name": "DBSCG Championship 2019 Warrior Merit Card Universe 1 Iwan", "set_name": "Tournament Promotion Cards", "set_code": "TPR", "set_id": "2565", "card_number": "1", "rarity": "Merit", "card_type": null, "product_type": "card", "variants": [ "Normal" ], "card_text": "Merit cards are proof that a player got to a certain place in a tournament. \r\nPlayers can't use them in their decks, but they can be used as tokens or other purposes.", "bandai_disclaimer": "This promotional card is marked “Not For Sale” by BANDAI, as the manufacturer prefers that Stores do not sell these cards." }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/191783/dragon-ball-super-ccg-tournament-promotion-cards-dbscg-championship-2019-warrior-merit-card-universe-1-iwan" }, "cardmarket": null } ], "pagination": { "page": 1, "limit": 1, "total": 1361, "total_pages": 1361 } } ``` ### Disambiguation Response: When a `set_code` is shared by several sets, the API returns the candidates instead of a set (status 200, as on the Pokémon API). Call again with the `set_id` you need. *200 OK — /dbs/sets/BT26* ```json { "disambiguation": true, "message": "Multiple sets found for set_code 'BT26'. Use set_id to specify which one.", "matches": [ { "set_id": "23646", "set_code": "BT26", "name": "Ultimate Advent", "language": "eng", "release_date": "2024-10-11T00:00:00" }, { "set_id": "23647", "set_code": "BT26", "name": "Ultimate Advent Pre-Release Cards", "language": "eng", "release_date": "2024-10-11T00:00:00" } ], "total": 2 } ``` ### GET /dbs/cards/:id Full card with prices. `id` is a `dbs_…` ID or a 64-character CardMarket ID. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/dbs/cards/dbs_0990dc88bb22b009f369d37790ffaa61304fd5329495c6fdbf9a9a5e38c5c42999ade67956e3d9f53069fc849ea923" ``` ### Response Example: *200 OK* ```json { "id": "dbs_0990dc88bb22b009f369d37790ffaa61304fd5329495c6fdbf9a9a5e38c5c42999ade67956e3d9f53069fc849ea923", "card_info": { "name": "Senzu Bean (Alt. Art Card Set 2023 Vol. 3)", "clean_name": "Senzu Bean Alt Art Card Set 2023 Vol 3", "set_name": "Tournament Promotion Cards", "set_code": "TPR", "set_id": "2565", "card_number": "BT1-053", "rarity": "Promo", "card_type": "Extra", "product_type": "card", "variants": [ "Foil" ], "card_text": "[Activate: Battle] Choose up to 1 of your cards. It gains +5000 power for the duration of the turn. Then, choose up to 2 of your energy and switch them to Active Mode.", "color": "Blue", "energy_color_cost": "1(B)", "bandai_disclaimer": "This promotional card is marked “Not For Sale” by BANDAI, as the manufacturer prefers that Stores do not sell these cards." }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 75, "mid_price": 75.28, "high_price": 200, "market_price": 43.24, "direct_low_price": null, "updated_at": "2026-09-20T12:41:45.471825+00:00", "sub_type_name": "Foil" } ], "url": "https://www.tcgplayer.com/product/517115/dragon-ball-super-ccg-tournament-promotion-cards-senzu-bean-alt-art-card-set-2023-vol-3" }, "cardmarket": { "product_name": "Senzu Bean", "prices": [ { "variant_type": "normal", "avg": 15, "low": 34, "trend": 16.87, "avg1": 15, "avg7": 22.75, "avg30": 22.75, "updated_at": "2026-09-30T14:49:58.736632+00:00" }, { "variant_type": "foil", "avg": 20.4, "low": 34, "trend": 18.25, "avg1": 20.49, "avg7": 26.23, "avg30": 24.63, "updated_at": "2026-09-30T14:49:58.736632+00:00" } ] } } ``` > One entry in `tcgplayer.prices` per finish, identified by `sub_type_name`, and one entry in `cardmarket.prices` per finish, identified by `variant_type` (`normal`, `foil`). `updated_at` is when that price last changed, not when it was last checked. A CardMarket-only card has `tcgplayer: null` and empty `variants`. ### GET /dbs/search Search cards by name or card number. Results have the same shape as `/dbs/cards/:id`, prices included. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | Required | 2–100 characters. Card name (all words, any order) or card number | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 20, max: 100) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/dbs/search?q=Senzu&limit=2" ``` ### Response Example (`results` omitted): *200 OK* ```json { "query": "Senzu", "results": [ { "id": "78940156b442c3dd7c5a6366d14204a1abf6350b4cb2c426685c52d23cfb4d77", "card_info": { "name": "Senzu Bean", "clean_name": "Senzu Bean", "set_name": "Galactic Battle", "set_code": "DBS-B01", "set_id": "1962", "card_number": "053", "rarity": null, "card_type": null, "product_type": "card", "variants": [], "card_text": null }, "images": { "languages": [ "en" ] }, "tcgplayer": null, "cardmarket": { "product_name": "Senzu Bean", "prices": [ { "variant_type": "normal", "avg": 32.75, "low": 0.02, "trend": 27.9, "avg1": 0.02, "avg7": 6.48, "avg30": 5.73, "updated_at": "2026-09-30T14:49:58.138293+00:00" }, { "variant_type": "foil", "avg": null, "low": 0.02, "trend": 3.48, "avg1": 0.05, "avg7": 1.36, "avg30": 2.02, "updated_at": "2026-09-30T14:49:58.138293+00:00" } ], "product_url": "https://www.cardmarket.com/en/DragonBallSuper/Products/Singles/Galactic-Battle/Senzu-Bean" } } ], "pagination": { "page": 1, "limit": 2, "total": 15, "total_pages": 8 }, "metadata": { "total_count": 15, "tcg": 13, "cardmarket": 10, "tcg_only": 5, "cardmarket_only": 2, "both_sources": 8, "truncated": false } } ``` > `metadata.truncated: true` means more cards match than the search returns: add words to narrow it down. Words match anywhere in the name; a query shorter than 3 characters matches names and card numbers that **start** with it (`27` finds `27`, `027/264`, `0027`). Quotes are ignored; `*`, `%` and `_` are plain text, not wildcards. ### GET /dbs/images/:id The card image, one resolution (`X-Image-Size: unsized`): the `size` parameter of the Pokémon image endpoint does not apply. Cached for 24 hours. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/dbs/images/dbs_0990dc88bb22b009f369d37790ffaa61304fd5329495c6fdbf9a9a5e38c5c42999ade67956e3d9f53069fc849ea923" \ --output card ``` ## Ultra endpoints Available on Ultra and Business plans, or during the 7-day trial. The Pro plan covers Pokémon and One Piece only: with Pro these endpoints answer 403 with an `upgrade_url`. Ultra includes everything in Pro. Same parameters and response format as the Pokémon endpoints of the same name. | Endpoint | What it returns | | --- | --- | | `GET /dbs/prices/:set` | TCGPlayer and CardMarket prices for every card of a set, one row per finish. `?source=tcg\|cm` | | `GET /dbs/sets/:set/statistics` | Price statistics and rarity breakdown. Sealed products excluded. `?variant=normal\|foil` | | `GET /dbs/sets/:set/completion-value` | Cost of one copy of every card in the set. Sealed products excluded. | | `GET /dbs/sets/trending` | Sets whose CardMarket prices moved most: 7-day average against 30-day average, cards from 1 € up. `?period=7d` `?limit=` | | `GET /dbs/analytics/top-cards` | Most expensive cards, or fastest-growing on CardMarket (7-day average against 30-day average, cards from 1 € up; `current_price` is the 7-day average). `?metric=price\|growth` `?source=tcg\|cm` `?limit=` | > Price history is a Pokémon feature: for this game there is no `/cards/:id/price-history`. Current prices are in the card detail and in `/dbs/prices/:set`; `metric=growth` works with `source=cm` only, and trending supports `period=7d` only. ### GET /dbs/prices/:set (first rows) *200 OK* ```json { "success": true, "source": "both", "set_code": "TPR", "set_id": "2565", "data": [ { "id": "dbs_4d481cf07b7bc46288aae1a1739bc154ddb7f629fd7c61842c4f3dd5c9833f8fa23d49d019fcd59266", "card_number": "1", "name": "DBSCG Championship 2019 Warrior (Merit Card) - Universe 1 \"Iwan\"", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.77, "mid_price": 1.18, "high_price": 1.79, "market_price": 1, "direct_low_price": null, "updated_at": "2026-09-30T20:40:32.208613+00:00" }, "cardmarket": null }, { "id": "dbs_f7869c0feb939f9e3a355fe025630793718f31f084339273d40056759eee2d774f2c6f3dfe3c2c3f8c", "card_number": "2", "name": "DBSCG Championship 2019 Warrior (Merit Card) - Universe 2 \"Heles\"", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.8, "mid_price": 1.79, "high_price": 1.79, "market_price": 1.79, "direct_low_price": null, "updated_at": "2026-09-20T12:41:45.329897+00:00" }, "cardmarket": null }, { "id": "dbs_589dde060b8190d11d9da43d7fd5d7b10fcd6fdf60f8c43ae9d55f3b4fd9fb63b2f7f88f9e2009c78b", "card_number": "3", "name": "DBSCG Championship 2019 Warrior (Merit Card) - Universe 3 \"Mosco\"", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.77, "mid_price": 1.44, "high_price": 3, "market_price": 1.58, "direct_low_price": null, "updated_at": "2026-09-30T20:40:32.208613+00:00" }, "cardmarket": null } ], "total": 1372 } ``` ### GET /dbs/sets/:set/statistics *200 OK* ```json { "set_info": { "name": "Tournament Promotion Cards", "set_code": "TPR", "set_id": "2565", "total_cards": 1314 }, "price_statistics": { "tcgplayer": { "avg_market_price": "13.87", "min_price": 0.1, "max_price": 2025, "most_expensive": { "id": "dbs_d1b4852567193dfa3157584f8069d628ef94af77c3d761dde99e18e2323cce47710e89ea7b87aa1d629ee6af4faecd9b", "name": "Son Goku, Adventure (Serial Numbered)", "price": 2025 } }, "cardmarket": { "avg_price": "11.65", "min_price": 0.02, "max_price": 1500, "most_expensive": { "id": "dbs_09a6e2ca49a7585e0d9e923ceb6232e0477d206d7e602a3c44d20dc4976c45b3b4e3e3d42c8cc5bf93f73bb476db1a", "name": "Vegito // Fusion Warrior Super Saiyan Vegito (Championship 2023 Golden Card Vol.3)", "price": 1500 }, "trend_direction": "stable" } }, "rarity_breakdown": { "Merit": 22, "Promo": 1030, "Secret Rare": 5, "Common": 19, "Uncommon": 104, "Rare": 32, "Super Rare": 45, "Special Rare": 2, "Son Gohan Rare": 1, "Dragon Ball Rare": 4, "Giant Force Rare": 1, "Expansion Rare": 7, "None": 16, "Starter Rare": 5, "Token": 21 } } ``` ### GET /dbs/sets/:set/completion-value *200 OK* ```json { "set_info": { "name": "Tournament Promotion Cards", "set_code": "TPR", "set_id": "2565", "total_cards": 1314 }, "completion_cost": { "tcgplayer": { "currency": "USD", "low_estimate": 223643.76, "market_estimate": 211171.96, "high_estimate": 461325.41 }, "cardmarket": { "currency": "EUR", "low_estimate": 16535.96, "avg_estimate": 16701.98, "trend_estimate": 1153.99 }, "note": "One copy per card (base finish). TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available." }, "breakdown_by_rarity": { "Merit": { "count": 22, "total_cost": 211.28 }, "Promo": { "count": 1030, "total_cost": 7073.09 }, "Secret Rare": { "count": 5, "total_cost": 2025 }, "Common": { "count": 19, "total_cost": 20.81 }, "Uncommon": { "count": 104, "total_cost": 710.81 }, "Rare": { "count": 32, "total_cost": 98.91 }, "Super Rare": { "count": 45, "total_cost": 1026.73 }, "Special Rare": { "count": 2, "total_cost": 18.21 }, "Son Gohan Rare": { "count": 1, "total_cost": 2.36 }, "Dragon Ball Rare": { "count": 4, "total_cost": 11.9 }, "Giant Force Rare": { "count": 1, "total_cost": 4.75 }, "Expansion Rare": { "count": 7, "total_cost": 22.93 }, "None": { "count": 16, "total_cost": 2024.27 }, "Starter Rare": { "count": 5, "total_cost": 22.29 }, "Token": { "count": 21, "total_cost": 52.29 } } } ``` ### GET /dbs/analytics/top-cards *200 OK* ```json { "metric": "price", "source": "tcg", "top_cards": [ { "id": "dbs_752e01e514d525b3efc0a9af04eeab239c627394e5ab9cff5080c87baa9b24d6c83ffc4ebb97cb179d6d828ea404f6", "card_info": { "name": "Son Goku - FP-001 (Serial Numbered)", "clean_name": "Son Goku FP 001 Serial Numbered", "set_name": "Fusion World Promotion Cards and Packs", "set_code": "DBSFW_PR", "set_id": "23428", "card_number": "FP-001", "rarity": "Promo", "card_type": "Battle", "product_type": "card", "variants": [ "Holofoil" ], "card_text": "[Permanent] If your Leader is awakened, this card gets +5000 power.\r\n
A numbered series of 777 copies of this card was given out as top event winner prizing for Awakened Pulse tournaments. The number on the card you receive will vary from the number pictured in the listing unless otherwise shown in a Listing with Photo.", "cost": "2(R)", "color": "Red", "power": "20000", "combo_power": "5000", "character_traits": "Saiyan" }, "current_price": 8000 }, { "id": "dbs_b22eedd43d2cb2fa99b05a4050fe4317fb28bade8e0a51985e18e7df2ae85452d9e59aa88ee7901ccbf5cf84f5", "card_info": { "name": "Energy Marker (E-48) (Gold)", "clean_name": "Energy Marker E 48 Gold", "set_name": "Fusion World Energy Markers", "set_code": "DBSFW_EM", "set_id": "23430", "card_number": "E-48", "rarity": "None", "card_type": null, "product_type": "card", "variants": [ "Holofoil" ], "card_text": "At the start of the game, the player who goes second places 1 Energy Marker in their Energy Area.
\nRemoving 1 Energy Marker from the game is equivalent to switching 1 card from your energy (with the same color as your Leader) to Rest Mode." }, "current_price": 2400 } ] } ``` ### GET /dbs/analytics/top-cards?metric=growth&source=cm *200 OK* ```json { "metric": "growth", "source": "cm", "top_cards": [ { "id": "dbs_fe2c5596629c9287d61cfaf1e0f2486106df2627ece9a542e6f32423dac88c35c04845f04f3af2bd2e855cc080018ece", "card_info": { "name": "SS3 Son Goku, Calamity Conqueror", "clean_name": "SS3 Son Goku Calamity Conqueror", "set_name": "Cross Spirits", "set_code": "DBS-B14", "set_id": "2858", "card_number": "BT14-035", "rarity": "Rare", "card_type": "Battle", "product_type": "card", "variants": [ "Normal", "Foil" ], "card_text": "[Deflect]\r\n
[Auto] [Limit 1] B, if your Leader Card is blue : When this card attacks, it gets +5000 power for the turn, and if you have a blue Unison Card with a specified cost of 3 in play, switch this card to Active Mode and it gains [Double Strike] for the turn.\r\n
[Activate:Main] [Spirit Boost 1] BBBB : Play this card from your hand.", "era": "Hirudegarn Saga", "color": "Blue", "power": "25000", "character": "Son Goku", "combo_power": "10000", "combo_energy": "1", "special_trait": "Saiyan", "energy_color_cost": "6(BBBB)" }, "current_price": 8.8, "change_7d": "+652.1%" }, { "id": "6b76487c06c479632562a30fe3b95d9dcaadb01b945fc718c5445a6af52a8c0c", "card_info": { "name": "Master Roshi, Masterly Majesty", "clean_name": "Master Roshi, Masterly Majesty", "set_name": "Malicious Machinations", "set_code": "DBS-B08", "set_id": "2536", "card_number": "032", "rarity": null, "card_type": null, "product_type": "card", "variants": [], "card_text": null }, "current_price": 20.27, "change_7d": "+422.4%" }, { "id": "dbs_53bd24aad0b0c55321a4ccbcae0dbcd397ecb0b61377366f042fe7aa4189df25d5d151d657f2f2b4f41a58598a2d5140", "card_info": { "name": "Zamasu // SS Rose Goku Black, Wishes Fulfilled", "clean_name": "Zamasu SS Rose Goku Black Wishes Fulfilled", "set_name": "Realm of the Gods", "set_code": "DBS-B16", "set_id": "2986", "card_number": "BT16-072", "rarity": "Uncommon", "card_type": "Leader", "product_type": "card", "variants": [ "Normal", "Foil" ], "card_text": "[Auto] When this card attacks, add up to 2 [Dragon Ball] cards from your deck and/or life to your hand; shuffle any areas you looked through using this skill.\r\n
[Wish] When your life is at 3 or less or there are 7 [Dragon Ball] cards in your Drop Area : Draw 1 card, then place all [Dragon Ball] cards from your Drop Area at the bottom of your deck in any order and flip this card over.\r\n

SS Rose Goku Black, Wishes Fulfilled\r\n
[Activate:Main] [Once per turn] Choose one—\r\n
• Draw 1 card.\r\n
• Add up to 1 [Dragon Ball] card from your deck to your hand, then shuffle your deck.\r\n
• Remove 7 [Dragon Ball] cards in your Drop Area from the game. If you do, play up to 1 \"Zamasu\" card with an energy cost of 2 or less and [Indestructible] from your Warp, and this card gains [Triple Attack] for the turn.", "era": "Future Trunks Saga", "color": "Yellow", "power": "10000/15000", "character": "Goku Black", "special_trait": "Saiyan/God/Shenron" }, "current_price": 7.17, "change_7d": "+391.1%" } ] } ``` ### GET /dbs/sets/trending *200 OK* ```json { "period": "7d", "trending_sets": [ { "set_name": "Vault Power Up Pack 2020", "set_code": "vpp2", "set_id": "-29", "card_count": 6, "cardmarket": { "price_change": "+83.2%", "avg_price_current": 4.33, "avg_price_previous": 2.37, "top_movers": [ { "name": "Familial Bonds", "change": "+298.0%" }, { "name": "Elegant Assistance Heles", "change": "+131.0%" }, { "name": "Hercule and Majin Buu, Friends Forever", "change": "-35.9%" } ] }, "tcgplayer": null }, { "set_name": "Theme Selection: History of Son Goku", "set_code": "TS01", "set_id": "3089", "card_count": 15, "cardmarket": { "price_change": "+67.7%", "avg_price_current": 8.5, "avg_price_previous": 5.07, "top_movers": [ { "name": "Son Goku, Allies in the Heart", "change": "+109.8%" }, { "name": "Desperate Measures", "change": "+105.5%" }, { "name": "Son Goku, Unwavering Conviction", "change": "+104.4%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } } ] } ``` ## Data Notes > **Prices.** TCGPlayer and CardMarket prices are refreshed daily. CardMarket has one entry per finish (`normal`, `foil`); a finish CardMarket does not price is left out, so `cardmarket.prices` can be empty. `updated_at` is when that price last changed, not when it was last checked: a stable price keeps an older date. > **`product_type`.** Cards and sealed products are told apart using TCGPlayer data, then CardTrader. Tokens, emblems and oversized cards count as `"card"`. For the very few products whose type cannot be determined, `product_type` is `null`, not `"card"`. > **CardMarket-only sets.** Sets with a negative `set_id` exist only on CardMarket: their cards have 64-character IDs and `tcgplayer: null`. > **Missing links.** `cardmarket.product_url` is absent for some cards; the card data is still valid. Sets with no cards are not listed: they appear as soon as cards are added. ## Dragon Ball Super API FAQ ### Is there a free Dragon Ball Super price API? Yes. The free tier (100 requests/hour, 1,000/day) opens the Dragon Ball Super sets, cards, search and images endpoints, with TCGPlayer and CardMarket prices refreshed daily. Prices by set, set statistics, completion value, trending sets and top cards need the Ultra plan (€29/month) or its 7-day trial. ### Does the Dragon Ball Super API include CardMarket prices? Yes. Cards return TCGPlayer (USD) prices for every finish and CardMarket (EUR) prices for normal and foil, where that market lists the card. Cards sold only on CardMarket have a 64-character hex id and no TCGPlayer price. ### How do I find the id of a Dragon Ball Super card? Search with /dbs/search?q=… or list a set with /dbs/sets/:set. Each card has an id (dbs_ + hex for cards on TCGPlayer) to pass to /dbs/cards/:id and /dbs/images/:id. ### Can I use the same API key for other games? Yes. One PokéWallet API key works for all 12 games, Pokémon and One Piece included, and the rate limits are shared across them. --- # Digimon API Documentation Source: https://pokewallet.io/api-docs/digimon REST reference for the Digimon API: sets, cards, search and images, with prices from TCGPlayer and CardMarket. Same API key as the Pokémon and One Piece APIs. In short The Digimon API returns 106 sets with their cards, search and images, and TCGPlayer (USD) and CardMarket (EUR) prices refreshed daily. These endpoints are free (100 requests/hour) with the same key as the other 11 games; prices by set and set analytics need the Ultra plan (€29/month) or its 7-day trial. At a glance - **Base path:** `https://api.pokewallet.io/dgm` - **Sets:** 106 Digimon sets - **Card IDs:** `dgm_` + hex for cards on TCGPlayer; 64 hex characters for CardMarket-only cards - **Prices:** TCGPlayer (USD) for every finish and CardMarket (EUR) for `normal` and `foil`, refreshed daily - **Free on every plan:** Sets, set cards, card details, search and images - **Ultra plan or 7-day trial:** Prices by set, set statistics, completion value, trending sets and top cards - **API key:** The same key as the Pokémon and One Piece APIs, with shared rate limits Updated Oct 19, 2026 ## Quick Start Get started with PokéWallet API in 4 simple steps: ### Create an Account Sign up for free to start using the API. Upgrade anytime from your dashboard. [Sign Up Now](https://pokewallet.io/auth/login?source=pokemon) ### Generate an API Key Create your first API key from the dashboard. ### Make Your First Request Start querying the API with your key. *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/dgm/sets" ``` ### Join the Discord Community Stay up to date with new features, ask for help, and connect with other developers. [Join Discord](https://discord.gg/znDxEjmDVP) > **Digimon PRO endpoints: Ultra plan required** > > The **Pro plan does not include them**: Pro covers Pokémon and One Piece only. Ultra (€29/month) includes everything in Pro plus the paid endpoints of **all 12 games**. Free endpoints (sets, cards, search, images) work on every plan. > > [Compare plans →](https://pokewallet.io/pricing) ## Digimon All Digimon endpoints live under `/dgm`. Same API key, same rate limits and the same response format as the Pokémon endpoints. ### Card IDs | Format | Example | Used for | | --- | --- | --- | | `dgm_` + hex | `dgm_8a6ca66bf034f86b91d1…` | Every card with a TCGPlayer product, even if it also has CardMarket data | | 64 hex characters, no prefix | `e26f12b8b1fabf19…` | Cards that exist only on CardMarket | > A `dgm_…` ID only works under `/dgm/`. Finishes of the same product (Normal, Foil, …) are one card with one ID; each finish has its own TCGPlayer price. If you request a card by its CardMarket ID and it is linked to a TCGPlayer product, the response uses the canonical `dgm_…` ID. ### Response Format Same shape as the Pokémon API: `card_info`, `images`, `tcgplayer.prices` and `cardmarket.prices` as arrays, `pagination`, errors as `{ "error", "message" }`. Differences: | Field | Digimon | | --- | --- | | Game fields in `card_info` | Instead of Pokémon's `hp`, `stage`, `attacks`…, the game's own fields in snake_case (present when the card has them): `color`, `play_cost`, `digimon_type`, `digimon_form`, `level_lv`, `digimon_power_dp`, `digimon_attribute`, `digivolve1_color`, `digivolve1_cost`, `digivolve1_level`, `inherited_effect`, `digivolve2_color`, `digivolve2_level`, `digivolve2_cost`, `security_effect`, `origins`, `digivolve3_level`, `disclaimer` | | `card_type`, `card_text` | Filled from the game's card type and rules text. `card_text` may contain HTML (``, ``…) as provided by TCGPlayer. | | `card_info.variants`, `card_info.set_id` | Always present, on every endpoint | | `product_type` | `"card"`, `"sealed"` or `null` when unknown — see [Data Notes](https://pokewallet.io/api-docs/digimon#dgm-data-notes) | | `release_date` | ISO format, e.g. `"2025-03-07T00:00:00"` (Pokémon uses `"16th June, 2023"`) | | `images.languages` | `["en"]`, or `[]` when there is no image | ## Digimon Endpoints ### GET /dgm/sets All Digimon sets. ### Response Fields: | Field | Type | Description | | --- | --- | --- | | `name` | string | Set name | | `set_code` | string \| null | Short code. **Not unique**: several sets can share it. | | `set_id` | string | Unique set identifier. Negative for sets that exist only on CardMarket. | | `card_count` | integer | Cards in the set (sealed products excluded). Omitted, not 0, if temporarily unavailable. | | `sealed_count` | integer | Sealed products in the set (booster boxes, displays, decks). Omitted, not 0, if temporarily unavailable. | | `language` | string \| null | Set language | | `release_date` | string \| null | ISO date | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/dgm/sets" ``` ### Response Example (first two sets): *200 OK* ```json { "success": true, "data": [ { "name": "Across Time", "set_code": "BT-12", "set_id": "23012", "card_count": 192, "sealed_count": 3, "language": "eng", "release_date": "2023-04-28T00:00:00" }, { "name": "Across Time Pre-Release Cards", "set_code": "BT-12_PR", "set_id": "23013", "card_count": 57, "sealed_count": 1, "language": "eng", "release_date": "2023-04-28T00:00:00" } ], "total": 106 } ``` ### GET /dgm/sets/:set Cards of one set, paginated. Prices are empty in set listings, as on the Pokémon API: use `/dgm/cards/:id` for prices. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `set` | string | Required | `set_id` (recommended, always unique) or `set_code` (exact match, case-insensitive) | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 50, max: 200) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/dgm/sets/2987?limit=1" ``` ### Response Example: *200 OK* ```json { "success": true, "set": { "name": "Revision Pack Cards", "set_code": "RPC", "set_id": "2987", "total_cards": 54, "language": "eng", "release_date": null }, "cards": [ { "id": "dgm_8a6ca66bf034f86b91d102c4d6e31169a41181937a3435202730dcf3fdd1d0ce9b73e9d3418074ec64d2741defa7eedaca", "card_info": { "name": "Lightning Paw", "clean_name": "Lightning Paw", "set_name": "Revision Pack Cards", "set_code": "RPC", "set_id": "2987", "card_number": "BT2-097 C", "rarity": "Common", "card_type": "Option", "product_type": "card", "variants": [ "Normal" ], "card_text": "[Main] 3 of your opponent's level 3 Digimon get -4000 DP for the turn.", "color": "Yellow", "play_cost": "3", "security_effect": "[Security] Activate this card's [Main] effect." }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/257742/digimon-card-game-revision-pack-cards-lightning-paw" }, "cardmarket": { "product_name": "Lightning Paw", "prices": [] } } ], "pagination": { "page": 1, "limit": 1, "total": 54, "total_pages": 54 } } ``` ### Disambiguation Response: When a `set_code` is shared by several sets, the API returns the candidates instead of a set (status 200, as on the Pokémon API). Call again with the `set_id` you need. *200 OK — /dgm/sets/BT-26* ```json { "disambiguation": true, "message": "Multiple sets found for set_code 'BT-26'. Use set_id to specify which one.", "matches": [ { "set_id": "24623", "set_code": "BT-26", "name": "Timeless Bonds", "language": "eng", "release_date": "2026-09-04T00:00:00" }, { "set_id": "24824", "set_code": "BT-26", "name": "Timeless Bonds Release Event Cards", "language": "eng", "release_date": "2026-08-28T00:00:00" } ], "total": 2 } ``` ### GET /dgm/cards/:id Full card with prices. `id` is a `dgm_…` ID or a 64-character CardMarket ID. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/dgm/cards/dgm_8a6ca66bf034f86b91d102c4d6e31169a41181937a3435202730dcf3fdd1d0ce9b73e9d3418074ec64d2741defa7eedaca" ``` ### Response Example: *200 OK* ```json { "id": "dgm_8a6ca66bf034f86b91d102c4d6e31169a41181937a3435202730dcf3fdd1d0ce9b73e9d3418074ec64d2741defa7eedaca", "card_info": { "name": "Lightning Paw", "clean_name": "Lightning Paw", "set_name": "Revision Pack Cards", "set_code": "RPC", "set_id": "2987", "card_number": "BT2-097 C", "rarity": "Common", "card_type": "Option", "product_type": "card", "variants": [ "Normal" ], "card_text": "[Main] 3 of your opponent's level 3 Digimon get -4000 DP for the turn.", "color": "Yellow", "play_cost": "3", "security_effect": "[Security] Activate this card's [Main] effect." }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 0.17, "mid_price": 0.49, "high_price": 2.47, "market_price": 0.24, "direct_low_price": null, "updated_at": "2026-09-30T20:41:10.523951+00:00", "sub_type_name": "Normal" } ], "url": "https://www.tcgplayer.com/product/257742/digimon-card-game-revision-pack-cards-lightning-paw" }, "cardmarket": { "product_name": "Lightning Paw", "prices": [ { "variant_type": "normal", "avg": 1.49, "low": 0.9, "trend": 1.27, "avg1": 0.99, "avg7": 1.65, "avg30": 1.65, "updated_at": "2026-09-30T14:50:04.161777+00:00" } ] } } ``` > One entry in `tcgplayer.prices` per finish, identified by `sub_type_name`, and one entry in `cardmarket.prices` per finish, identified by `variant_type` (`normal`, `foil`). `updated_at` is when that price last changed, not when it was last checked. A CardMarket-only card has `tcgplayer: null` and empty `variants`. ### GET /dgm/search Search cards by name or card number. Results have the same shape as `/dgm/cards/:id`, prices included. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | Required | 2–100 characters. Card name (all words, any order) or card number | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 20, max: 100) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/dgm/search?q=Lightning&limit=2" ``` ### Response Example (`results` omitted): *200 OK* ```json { "query": "Lightning", "results": [ { "id": "dgm_67dcdf17a0fe86cbc3c3c8967734865bf34a5873b6de166305cc60d5b73a87dd4dd00ef271a35fc325ce6e763aed75b26de9", "card_info": { "name": "Lightning Paw", "clean_name": "Lightning Paw", "set_name": "Release Special Booster 1.5", "set_code": "BT01-03B", "set_id": "24182", "card_number": "BT2-097 C", "rarity": "Common", "card_type": "Option", "product_type": "card", "variants": [ "Normal" ], "card_text": "[Main] Up to 3 of your opponent's level 3 Digimon get -4000 DP for the turn.", "color": "Yellow", "origins": "Release Special Booster V.1.5", "play_cost": "3", "security_effect": "[Security] Activate this card's [Main] effect." }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 0.01, "mid_price": 0.2, "high_price": 1.51, "market_price": 0.07, "direct_low_price": null, "updated_at": "2026-09-20T12:37:03.528756+00:00", "sub_type_name": "Normal" } ], "url": "https://www.tcgplayer.com/product/231717/digimon-card-game-release-special-booster-15-lightning-paw" }, "cardmarket": { "product_name": "Lightning Paw (BT2-097)", "prices": [ { "variant_type": "normal", "avg": 0.13, "low": 0.02, "trend": 0.1, "avg1": 0.02, "avg7": 0.04, "avg30": 0.06, "updated_at": "2026-09-30T14:50:03.973008+00:00" } ], "product_url": "https://www.cardmarket.com/en/Digimon/Products/Singles/Special-Release-Booster-v15/Lightning-Paw-BT2-097-C" } } ], "pagination": { "page": 1, "limit": 2, "total": 8, "total_pages": 4 }, "metadata": { "total_count": 8, "tcg": 7, "cardmarket": 7, "tcg_only": 1, "cardmarket_only": 1, "both_sources": 6, "truncated": false } } ``` > `metadata.truncated: true` means more cards match than the search returns: add words to narrow it down. Words match anywhere in the name; a query shorter than 3 characters matches names and card numbers that **start** with it (`27` finds `27`, `027/264`, `0027`). Quotes are ignored; `*`, `%` and `_` are plain text, not wildcards. ### GET /dgm/images/:id The card image, one resolution (`X-Image-Size: unsized`): the `size` parameter of the Pokémon image endpoint does not apply. Cached for 24 hours. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/dgm/images/dgm_8a6ca66bf034f86b91d102c4d6e31169a41181937a3435202730dcf3fdd1d0ce9b73e9d3418074ec64d2741defa7eedaca" \ --output card ``` ## Ultra endpoints Available on Ultra and Business plans, or during the 7-day trial. The Pro plan covers Pokémon and One Piece only: with Pro these endpoints answer 403 with an `upgrade_url`. Ultra includes everything in Pro. Same parameters and response format as the Pokémon endpoints of the same name. | Endpoint | What it returns | | --- | --- | | `GET /dgm/prices/:set` | TCGPlayer and CardMarket prices for every card of a set, one row per finish. `?source=tcg\|cm` | | `GET /dgm/sets/:set/statistics` | Price statistics and rarity breakdown. Sealed products excluded. `?variant=normal\|foil` | | `GET /dgm/sets/:set/completion-value` | Cost of one copy of every card in the set. Sealed products excluded. | | `GET /dgm/sets/trending` | Sets whose CardMarket prices moved most: 7-day average against 30-day average, cards from 1 € up. `?period=7d` `?limit=` | | `GET /dgm/analytics/top-cards` | Most expensive cards, or fastest-growing on CardMarket (7-day average against 30-day average, cards from 1 € up; `current_price` is the 7-day average). `?metric=price\|growth` `?source=tcg\|cm` `?limit=` | > Price history is a Pokémon feature: for this game there is no `/cards/:id/price-history`. Current prices are in the card detail and in `/dgm/prices/:set`; `metric=growth` works with `source=cm` only, and trending supports `period=7d` only. ### GET /dgm/prices/:set (first rows) *200 OK* ```json { "success": true, "source": "both", "set_code": "RPC", "set_id": "2987", "data": [ { "id": "dgm_8a6ca66bf034f86b91d102c4d6e31169a41181937a3435202730dcf3fdd1d0ce9b73e9d3418074ec64d2741defa7eedaca", "card_number": "BT2-097 C", "name": "Lightning Paw", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.17, "mid_price": 0.49, "high_price": 2.47, "market_price": 0.24, "direct_low_price": null, "updated_at": "2026-09-30T20:41:10.523951+00:00" }, "cardmarket": { "avg": 1.49, "low": 0.9, "trend": 1.27, "avg1": 0.99, "avg7": 1.65, "avg30": 1.65, "updated_at": "2026-09-30T14:50:04.161777+00:00" } }, { "id": "dgm_0c0c1b23b5e2dffe86d45ff23a5b225aeed5607b65c81c5275ccb159bc0669524b585b6c0ca625ba4cf6144dc2134d9b0f", "card_number": "BT3-092 R", "name": "MaloMyotismon", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 2.2, "mid_price": 2.99, "high_price": 9.99, "market_price": 2.97, "direct_low_price": null, "updated_at": "2026-09-30T20:41:10.523951+00:00" }, "cardmarket": { "avg": 3, "low": 0.75, "trend": 2.23, "avg1": 3, "avg7": 2.38, "avg30": 0.98, "updated_at": "2026-09-30T14:50:04.161777+00:00" } }, { "id": "dgm_8dfe7e94b348739bce5965d88110d1e71aaac21b6d5055a4f7c4e7cc7008955aa231718c7216ed450e41caa07c6dae3174", "card_number": "BT3-097 U", "name": "A Delicate Plan", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.21, "mid_price": 0.69, "high_price": 8, "market_price": 0.35, "direct_low_price": null, "updated_at": "2026-09-20T12:37:08.504636+00:00" }, "cardmarket": { "avg": 0.43, "low": 0.4, "trend": 0.48, "avg1": 0.43, "avg7": 0.32, "avg30": 0.32, "updated_at": "2026-09-30T14:50:04.161777+00:00" } } ], "total": 54 } ``` ### GET /dgm/sets/:set/statistics *200 OK* ```json { "set_info": { "name": "Revision Pack Cards", "set_code": "RPC", "set_id": "2987", "total_cards": 54 }, "price_statistics": { "tcgplayer": { "avg_market_price": "0.83", "min_price": 0.11, "max_price": 5.1, "most_expensive": { "id": "dgm_2291e80f3e9aaef8ccd75d616357764d5a38807fa0776de60997284ca7208521062b8dd08f53088d5a468db419a860187462", "name": "Imperialdramon: Dragon Mode", "price": 5.1 } }, "cardmarket": { "avg_price": "0.64", "min_price": 0.02, "max_price": 4.35, "most_expensive": { "id": "dgm_2291e80f3e9aaef8ccd75d616357764d5a38807fa0776de60997284ca7208521062b8dd08f53088d5a468db419a860187462", "name": "Imperialdramon: Dragon Mode", "price": 4.35 }, "trend_direction": "up" } }, "rarity_breakdown": { "Common": 13, "Rare": 15, "Uncommon": 10, "Secret Rare": 2, "Super Rare": 9, "Promo": 5 } } ``` ### GET /dgm/sets/:set/completion-value *200 OK* ```json { "set_info": { "name": "Revision Pack Cards", "set_code": "RPC", "set_id": "2987", "total_cards": 54 }, "completion_cost": { "tcgplayer": { "currency": "USD", "low_estimate": 28.78, "market_estimate": 42.67, "high_estimate": 208.28 }, "cardmarket": { "currency": "EUR", "low_estimate": 14.81, "avg_estimate": 32.77, "trend_estimate": 29.87 }, "note": "One copy per card (base finish). TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available." }, "breakdown_by_rarity": { "Common": { "count": 13, "total_cost": 11.96 }, "Rare": { "count": 15, "total_cost": 9.98 }, "Uncommon": { "count": 10, "total_cost": 5.41 }, "Secret Rare": { "count": 2, "total_cost": 1.64 }, "Super Rare": { "count": 9, "total_cost": 9.66 }, "Promo": { "count": 5, "total_cost": 3.45 } } } ``` ### GET /dgm/analytics/top-cards *200 OK* ```json { "metric": "price", "source": "tcg", "top_cards": [ { "id": "dgm_86efe938247f8486d12fcee53828d02f1edf6e3829a10ca9c4bb0bc5ff02d386ed7b0d4429db4ae00daa1729d66f8a222eedefae7f", "card_info": { "name": "WarGreymon (Rare Pull)", "clean_name": "WarGreymon Rare Pull", "set_name": "Release Special Booster 2.5", "set_code": "BT19-20", "set_id": "24178", "card_number": "BT14-101 SEC", "rarity": "Secret Rare", "card_type": "Digimon", "product_type": "card", "variants": [ "Normal", "Foil" ], "card_text": "([Digivolve] Lv.5 w/[Greymon] in name: Cost 4)\r\n
While you have a Tamer with [Tai Kamiya] in its name and your opponent has a Digimon with 10000 DP or more, one of your [Agumon] may digivolve into this card in your hand for a digivolution cost of 4, ignoring digivolution requirements.\r\n
[When Digivolving] This Digimon gains [Raid] for the turn. Then, it may\r\nattack.\r\n
[When Attacking] If you have a Tamer, this Digimon gains [Security A. +1] and [Piercing] for the turn.", "color": "Red", "level_lv": "6", "play_cost": "12", "digimon_form": "Mega", "digimon_type": "Dragonkin", "digimon_power_dp": "12000", "digivolve1_cost": "4", "digivolve1_color": "Red", "digivolve1_level": "5", "digimon_attribute": "Vaccine" }, "current_price": 3000 }, { "id": "dgm_df0b0bb5d6671cbb3e1bbc744e61c45fe15e56435c3d383ecb49cb194ed1e689a606f8ca8849ba2447c63471a0b97592380ea2aebf", "card_info": { "name": "MetalGarurumon (Rare Pull)", "clean_name": "MetalGarurumon Rare Pull", "set_name": "Release Special Booster 2.5", "set_code": "BT19-20", "set_id": "24178", "card_number": "BT15-101 SEC", "rarity": "Secret Rare", "card_type": "Digimon", "product_type": "card", "variants": [ "Foil" ], "card_text": "[[Digivolve] Lv.5 w/[Garurumon] in name: Cost 4]\r\n
While you have a Tamer with [Matt Ishida] in its name and your opponent has a 10000 DP or higher Digimon, one of your [Gabumon] may digivolve into this card in your hand for a divolution cost of 4, ignoring its digivolution requirements.\r\n
[Evade]\r\n
[When Digivolving] 3 of your opponent's Digimon and Tamers can't suspend until the end of their turn.\r\n
[All Turns] [Once Per Turn] When this Digimon becomes suspended, you may unsuspend it.", "color": "Blue", "level_lv": "6", "play_cost": "12", "digimon_form": "Mega", "digimon_type": "Cyborg", "digimon_power_dp": "12000", "digivolve1_cost": "4", "digivolve1_color": "Blue", "digivolve1_level": "5", "digimon_attribute": "Data" }, "current_price": 1700 }, { "id": "dgm_5f86b3c5016828f2f20323209dd3264f0dc9bc53cdd651da44dfe41dc850fa58941a2691f25b526678dc07fad54d6cc56c932996", "card_info": { "name": "BeelStarmon (X Antibody) (Textured)", "clean_name": "BeelStarmon X Antibody Textured", "set_name": "Digimon LIBERATOR", "set_code": "EX-07", "set_id": "23587", "card_number": "EX7-073 SCR", "rarity": "Secret Rare", "card_type": "Digimon", "product_type": "card", "variants": [ "Foil" ], "card_text": "[When Digivolving] You may use 1 Option card with [Three Musketeers] in its text from your hand without paying the cost.
\r\n[When Digivolving] [When Attacking] By trashing 2 cards with the [Three Musketeers] trait in this Digimon's digivolution cards, delete 1 of your opponent's Digimon with the highest level and trash the top card of your opponent's security stack.", "color": "Purple", "level_lv": "6", "play_cost": "12", "digimon_form": "Mega", "digivolve1_cost": "3", "digivolve1_color": "Purple", "digivolve1_level": "5", "digimon_attribute": "Virus" }, "current_price": 1449.5 } ] } ``` ### GET /dgm/analytics/top-cards?metric=growth&source=cm *200 OK* ```json { "metric": "growth", "source": "cm", "top_cards": [ { "id": "dgm_af2c44b58cec3573aff24bdd650daeb0b0f9a8175779abca42cd8299ae59bc1bb7ae6e20387f1c6ec9cb1d455666065213ba", "card_info": { "name": "Gazimon (Limited Foil)", "clean_name": "Gazimon Limited Foil", "set_name": "Versus Monsters", "set_code": "EX-09", "set_id": "24077", "card_number": "EX9-058 U", "rarity": "Uncommon", "card_type": "Digimon", "product_type": "card", "variants": [ "Foil" ], "card_text": "[[Digivolve] Lv.2 w/[DM] trait: Cost 0]\r\n
[On Play] Reveal the top 3 cards of your deck. Among them, add 1 card with the [DM] trait to the hand and place 1 card with the [Ver.5] trait face down as the bottom digivolution card of any of your Digimon with the [DM] trait. Return the rest to the bottom of the deck.", "color": "Purple", "level_lv": "3", "play_cost": "3", "digimon_form": "Rookie", "digimon_type": "Mammal/DM/Ver.5", "digimon_power_dp": "1000", "digivolve1_cost": "0", "digivolve1_color": "Purple", "digivolve1_level": "2", "digimon_attribute": "Virus", "inherited_effect": "[Retaliation] (When only this Digimon is deleted in battle, delete the Digimon it battled.)" }, "current_price": 10.55, "change_7d": "+343.3%" }, { "id": "dgm_52ddf1834adba4251d6ba73f79b48a176c4511876291f93fde8499efa34b826c7661e3d1cafdbedc0a789097c1b410a7d763", "card_info": { "name": "Tsunomon (Limited Foil)", "clean_name": "Tsunomon Limited Foil", "set_name": "Versus Monsters", "set_code": "EX-09", "set_id": "24077", "card_number": "EX9-002 C", "rarity": "Common", "card_type": "Digi-Egg", "product_type": "card", "variants": [ "Foil" ], "card_text": null, "color": "Blue", "level_lv": "2", "digimon_form": "In-Training", "digimon_type": "Lesser/DM/Ver.2", "inherited_effect": "[Your Turn] [Once Per Turn] When face-down cards are placed in this Digimon's digivolution cards, this Digimon may digivolve into a [Ver.2] trait Digimon card in the hand with the digivolution cost reduced by 1." }, "current_price": 7.57, "change_7d": "+340.1%" }, { "id": "dgm_9c24eebb4cc59bf3cd8874373423f812b740900404caf33c358a5a97ebcb991625c737df32fe3b87cc905e19c9ab9e204ee9", "card_info": { "name": "Starmon (Foil)", "clean_name": "Starmon Foil", "set_name": "Digimon LIBERATOR", "set_code": "EX-07", "set_id": "23587", "card_number": "EX7-026 C", "rarity": "Common", "card_type": "Digimon", "product_type": "card", "variants": [ "Foil" ], "card_text": "[[Digivolve] Lv.3 w/[NSp] trait: Cost 2]
\r\n[On Play] [When Digivolving] 1 of your opponent's Digimon gets -3000 DP for the turn.", "color": "Yellow", "level_lv": "4", "play_cost": "4", "digimon_form": "Champion", "digimon_type": "Mutant/NSp", "digimon_power_dp": "4000", "digivolve1_cost": "2", "digivolve1_color": "Yellow", "digivolve1_level": "3", "digimon_attribute": "Data", "inherited_effect": "[Barrier] (When this Digimon would be deleted in battle, by trashing the top card of your security stack, prevent that deletion.)" }, "current_price": 8.87, "change_7d": "+197.7%" } ] } ``` ### GET /dgm/sets/trending *200 OK* ```json { "period": "7d", "trending_sets": [ { "set_name": "Starter Deck 21: Hero of Hope Release Event Cards", "set_code": "ST-21_PR", "set_id": "24271", "card_count": 5, "cardmarket": { "price_change": "-40.5%", "avg_price_current": 1.37, "avg_price_previous": 2.3, "top_movers": [ { "name": "Tsunomon", "change": "-64.1%" }, { "name": "Gomamon", "change": "-46.1%" }, { "name": "MetalGarurumon Ace", "change": "-27.1%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } }, { "set_name": "Starter Deck 20: Protector of Light Release Event Cards", "set_code": "ST-20_PR", "set_id": "24292", "card_count": 5, "cardmarket": { "price_change": "-33.4%", "avg_price_current": 1.45, "avg_price_previous": 2.18, "top_movers": [ { "name": "Birdramon", "change": "-51.1%" }, { "name": "MegaKabuterimon", "change": "-39.0%" }, { "name": "Biyomon", "change": "-38.8%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } } ] } ``` ## Data Notes > **Prices.** TCGPlayer and CardMarket prices are refreshed daily. CardMarket has one entry per finish (`normal`, `foil`); a finish CardMarket does not price is left out, so `cardmarket.prices` can be empty. `updated_at` is when that price last changed, not when it was last checked: a stable price keeps an older date. > **`product_type`.** Cards and sealed products are told apart using TCGPlayer data, then CardTrader. Tokens, emblems and oversized cards count as `"card"`. For the very few products whose type cannot be determined, `product_type` is `null`, not `"card"`. > **CardMarket-only sets.** Sets with a negative `set_id` exist only on CardMarket: their cards have 64-character IDs and `tcgplayer: null`. > **Missing links.** `cardmarket.product_url` is absent for some cards; the card data is still valid. Sets with no cards are not listed: they appear as soon as cards are added. ## Digimon API FAQ ### Is there a free Digimon price API? Yes. The free tier (100 requests/hour, 1,000/day) opens the Digimon sets, cards, search and images endpoints, with TCGPlayer and CardMarket prices refreshed daily. Prices by set, set statistics, completion value, trending sets and top cards need the Ultra plan (€29/month) or its 7-day trial. ### Does the Digimon API include CardMarket prices? Yes. Cards return TCGPlayer (USD) prices for every finish and CardMarket (EUR) prices for normal and foil, where that market lists the card. Cards sold only on CardMarket have a 64-character hex id and no TCGPlayer price. ### How do I find the id of a Digimon card? Search with /dgm/search?q=… or list a set with /dgm/sets/:set. Each card has an id (dgm_ + hex for cards on TCGPlayer) to pass to /dgm/cards/:id and /dgm/images/:id. ### Can I use the same API key for other games? Yes. One PokéWallet API key works for all 12 games, Pokémon and One Piece included, and the rate limits are shared across them. --- # Star Wars Unlimited API Documentation Source: https://pokewallet.io/api-docs/star-wars-unlimited REST reference for the Star Wars Unlimited API: sets, cards, search and images, with prices from TCGPlayer and CardMarket. Same API key as the Pokémon and One Piece APIs. In short The Star Wars Unlimited API returns 34 sets with their cards, search and images, and TCGPlayer (USD) and CardMarket (EUR) prices refreshed daily. These endpoints are free (100 requests/hour) with the same key as the other 11 games; prices by set and set analytics need the Ultra plan (€29/month) or its 7-day trial. At a glance - **Base path:** `https://api.pokewallet.io/swu` - **Sets:** 34 Star Wars Unlimited sets - **Card IDs:** `swu_` + hex for cards on TCGPlayer; 64 hex characters for CardMarket-only cards - **Prices:** TCGPlayer (USD) for every finish and CardMarket (EUR) for `normal` and `foil`, refreshed daily - **Free on every plan:** Sets, set cards, card details, search and images - **Ultra plan or 7-day trial:** Prices by set, set statistics, completion value, trending sets and top cards - **API key:** The same key as the Pokémon and One Piece APIs, with shared rate limits Updated Oct 19, 2026 ## Quick Start Get started with PokéWallet API in 4 simple steps: ### Create an Account Sign up for free to start using the API. Upgrade anytime from your dashboard. [Sign Up Now](https://pokewallet.io/auth/login?source=pokemon) ### Generate an API Key Create your first API key from the dashboard. ### Make Your First Request Start querying the API with your key. *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/swu/sets" ``` ### Join the Discord Community Stay up to date with new features, ask for help, and connect with other developers. [Join Discord](https://discord.gg/znDxEjmDVP) > **Star Wars Unlimited PRO endpoints: Ultra plan required** > > The **Pro plan does not include them**: Pro covers Pokémon and One Piece only. Ultra (€29/month) includes everything in Pro plus the paid endpoints of **all 12 games**. Free endpoints (sets, cards, search, images) work on every plan. > > [Compare plans →](https://pokewallet.io/pricing) ## Star Wars Unlimited All Star Wars Unlimited endpoints live under `/swu`. Same API key, same rate limits and the same response format as the Pokémon endpoints. ### Card IDs | Format | Example | Used for | | --- | --- | --- | | `swu_` + hex | `swu_c81e56aec90439ccd07c…` | Every card with a TCGPlayer product, even if it also has CardMarket data | | 64 hex characters, no prefix | `e26f12b8b1fabf19…` | Cards that exist only on CardMarket | > A `swu_…` ID only works under `/swu/`. Finishes of the same product (Normal, Foil, …) are one card with one ID; each finish has its own TCGPlayer price. If you request a card by its CardMarket ID and it is linked to a TCGPlayer product, the response uses the canonical `swu_…` ID. ### Response Format Same shape as the Pokémon API: `card_info`, `images`, `tcgplayer.prices` and `cardmarket.prices` as arrays, `pagination`, errors as `{ "error", "message" }`. Differences: | Field | Star Wars Unlimited | | --- | --- | | Game fields in `card_info` | Instead of Pokémon's `hp`, `stage`, `attacks`…, the game's own fields in snake_case (present when the card has them): `traits`, `cost`, `aspect`, `hp`, `power`, `arena_type`, `epic_action` | | `card_type`, `card_text` | Filled from the game's card type and rules text. `card_text` may contain HTML (``, ``…) as provided by TCGPlayer. | | `card_info.variants`, `card_info.set_id` | Always present, on every endpoint | | `product_type` | `"card"`, `"sealed"` or `null` when unknown — see [Data Notes](https://pokewallet.io/api-docs/star-wars-unlimited#swu-data-notes) | | `release_date` | ISO format, e.g. `"2025-03-07T00:00:00"` (Pokémon uses `"16th June, 2023"`) | | `images.languages` | `["en"]`, or `[]` when there is no image | ## Star Wars Unlimited Endpoints ### GET /swu/sets All Star Wars Unlimited sets. ### Response Fields: | Field | Type | Description | | --- | --- | --- | | `name` | string | Set name | | `set_code` | string \| null | Short code. **Not unique**: several sets can share it. | | `set_id` | string | Unique set identifier. Negative for sets that exist only on CardMarket. | | `card_count` | integer | Cards in the set (sealed products excluded). Omitted, not 0, if temporarily unavailable. | | `sealed_count` | integer | Sealed products in the set (booster boxes, displays, decks). Omitted, not 0, if temporarily unavailable. | | `language` | string \| null | Set language | | `release_date` | string \| null | ISO date | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/swu/sets" ``` ### Response Example (first two sets): *200 OK* ```json { "success": true, "data": [ { "name": "2024 Convention Exclusive", "set_code": "CE2024", "set_id": "23572", "card_count": 6, "sealed_count": 1, "language": "eng", "release_date": "2024-07-25T00:00:00" }, { "name": "2025 Convention Exclusive", "set_code": "CE2025", "set_id": "24385", "card_count": 6, "sealed_count": 1, "language": "eng", "release_date": "2025-07-24T00:00:00" } ], "total": 34 } ``` ### GET /swu/sets/:set Cards of one set, paginated. Prices are empty in set listings, as on the Pokémon API: use `/swu/cards/:id` for prices. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `set` | string | Required | `set_id` (recommended, always unique) or `set_code` (exact match, case-insensitive) | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 50, max: 200) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/swu/sets/24854?limit=1" ``` ### Response Example: *200 OK* ```json { "success": true, "set": { "name": "Sector and Regional Promos: Season 2", "set_code": "P26", "set_id": "24854", "total_cards": 54, "language": "eng", "release_date": "2026-08-01T00:00:00" }, "cards": [ { "id": "swu_f8568585a4c9946c765b3b4a6abd51bc6038294324fcbcd28647fcbc319dd52583d7361f1a10b74d360d", "card_info": { "name": "Boba Fett's Rancor - Emotionally Complex Creature", "clean_name": "Boba Fetts Rancor Emotionally Complex Creature", "set_name": "Sector and Regional Promos: Season 2", "set_code": "P26", "set_id": "24854", "card_number": "00", "rarity": "Legendary", "card_type": "Unit", "product_type": "card", "variants": [ "Normal" ], "card_text": "When Played: Deal 5 damage to your base. Then, deal 5 damage to an enemy ground unit. Then, deal 5 damage to the same unit.
On Attack:
You may deal 1 damage to a base for every 5 damage on your base.", "hp": "9", "cost": "8", "power": "8", "aspect": "Aggression", "traits": "Creature;Underworld", "arena_type": "Ground" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/714471/star-wars-unlimited-sector-and-regional-promos-season-2-boba-fetts-rancor-emotionally-complex-creature" }, "cardmarket": null } ], "pagination": { "page": 1, "limit": 1, "total": 54, "total_pages": 54 } } ``` ### Disambiguation Response: When a `set_code` is shared by several sets, the API returns the candidates instead of a set (status 200, as on the Pokémon API). Call again with the `set_id` you need. *200 OK — /swu/sets/P26* ```json { "disambiguation": true, "message": "Multiple sets found for set_code 'P26'. Use set_id to specify which one.", "matches": [ { "set_id": "24784", "set_code": "P26", "name": "Galactic Championship 2026", "language": "eng", "release_date": "2026-07-01T00:00:00" }, { "set_id": "24854", "set_code": "P26", "name": "Sector and Regional Promos: Season 2", "language": "eng", "release_date": "2026-08-01T00:00:00" } ], "total": 2 } ``` ### GET /swu/cards/:id Full card with prices. `id` is a `swu_…` ID or a 64-character CardMarket ID. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/swu/cards/swu_c81e56aec90439ccd07c1baac956a4039c72a47482a2f74b0b5040bbc5857d9e38fa1e862b2930bd49eac01a" ``` ### Response Example: *200 OK* ```json { "id": "swu_c81e56aec90439ccd07c1baac956a4039c72a47482a2f74b0b5040bbc5857d9e38fa1e862b2930bd49eac01a", "card_info": { "name": "Pre Vizsla - Strong-Willed Ruler", "clean_name": "Pre Vizsla Strong Willed Ruler", "set_name": "Sector and Regional Promos: Season 2", "set_code": "P26", "set_id": "24854", "card_number": "235", "rarity": "Legendary", "card_type": "Unit", "product_type": "card", "variants": [ "Foil" ], "card_text": "When Played: Defeat any number of nonleader units with a total of 6 or less remaining HP. Create a Mandalorian token for each unit defeated this way.", "hp": "6", "cost": "8", "power": "6", "aspect": "Vigilance;Villainy", "traits": "Mandalorian;Official", "arena_type": "Ground" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 215, "mid_price": 216.09, "high_price": 221.73, "market_price": null, "direct_low_price": null, "updated_at": "2026-09-30T20:41:16.825869+00:00", "sub_type_name": "Foil" } ], "url": "https://www.tcgplayer.com/product/714466/star-wars-unlimited-sector-and-regional-promos-season-2-pre-vizsla-strong-willed-ruler" }, "cardmarket": { "product_name": "Paz Vizsla - For a Brighter Future", "prices": [ { "variant_type": "normal", "avg": null, "low": 100, "trend": null, "avg1": null, "avg7": null, "avg30": null, "updated_at": "2026-09-30T14:50:05.474823+00:00" }, { "variant_type": "foil", "avg": 105, "low": 100, "trend": 105, "avg1": null, "avg7": null, "avg30": null, "updated_at": "2026-09-30T14:50:05.474823+00:00" } ] } } ``` > One entry in `tcgplayer.prices` per finish, identified by `sub_type_name`, and one entry in `cardmarket.prices` per finish, identified by `variant_type` (`normal`, `foil`). `updated_at` is when that price last changed, not when it was last checked. A CardMarket-only card has `tcgplayer: null` and empty `variants`. ### GET /swu/search Search cards by name or card number. Results have the same shape as `/swu/cards/:id`, prices included. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | Required | 2–100 characters. Card name (all words, any order) or card number | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 20, max: 100) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/swu/search?q=Vizsla&limit=2" ``` ### Response Example (`results` omitted): *200 OK* ```json { "query": "Vizsla", "results": [ { "id": "swu_2d744f2605266f77a4ef06a2fbcd948b163dc5ce5011f7826238fc36f66be2cbedede3675dd6d1a070cb80fe0c2536", "card_info": { "name": "Pre Vizsla - Pursuing the Throne", "clean_name": "Pre Vizsla Pursuing the Throne", "set_name": "Twilight of the Republic", "set_code": "TWI", "set_id": "23597", "card_number": "010/257", "rarity": "Rare", "card_type": "Leader", "product_type": "card", "variants": [ "Normal" ], "card_text": "Action [1, Exhaust]: Deal damage to a unit equal to the number of cards you've drawn this phase. (This doesn't include cards drawn in the regroup phase.)", "hp": "6", "cost": "5", "power": "4", "aspect": "Aggression;Villainy", "traits": "Mandalorian;Trooper", "arena_type": "Ground", "epic_action": "Epic Action: If you control 5 or more resources, deploy this leader." }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 0.03, "mid_price": 0.2, "high_price": 3, "market_price": 0.1, "direct_low_price": null, "updated_at": "2026-09-30T20:41:16.522017+00:00", "sub_type_name": "Normal" } ], "url": "https://www.tcgplayer.com/product/588395/star-wars-unlimited-twilight-of-the-republic-pre-vizsla-pursuing-the-throne" }, "cardmarket": { "product_name": "Pre Vizsla, Pursuing the Throne", "prices": [ { "variant_type": "normal", "avg": 0.19, "low": 0.02, "trend": 0.22, "avg1": 0.05, "avg7": 0.15, "avg30": 0.1, "updated_at": "2026-09-30T14:50:05.177578+00:00" } ], "product_url": "https://www.cardmarket.com/en/StarWarsUnlimited/Products/Singles/Twilight-of-the-Republic/Pre-Vizsla-Pursuing-the-Throne" } } ], "pagination": { "page": 1, "limit": 2, "total": 26, "total_pages": 13 }, "metadata": { "total_count": 26, "tcg": 26, "cardmarket": 26, "tcg_only": 0, "cardmarket_only": 0, "both_sources": 26, "truncated": false } } ``` > `metadata.truncated: true` means more cards match than the search returns: add words to narrow it down. Words match anywhere in the name; a query shorter than 3 characters matches names and card numbers that **start** with it (`27` finds `27`, `027/264`, `0027`). Quotes are ignored; `*`, `%` and `_` are plain text, not wildcards. ### GET /swu/images/:id The card image, one resolution (`X-Image-Size: unsized`): the `size` parameter of the Pokémon image endpoint does not apply. Cached for 24 hours. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/swu/images/swu_c81e56aec90439ccd07c1baac956a4039c72a47482a2f74b0b5040bbc5857d9e38fa1e862b2930bd49eac01a" \ --output card ``` ## Ultra endpoints Available on Ultra and Business plans, or during the 7-day trial. The Pro plan covers Pokémon and One Piece only: with Pro these endpoints answer 403 with an `upgrade_url`. Ultra includes everything in Pro. Same parameters and response format as the Pokémon endpoints of the same name. | Endpoint | What it returns | | --- | --- | | `GET /swu/prices/:set` | TCGPlayer and CardMarket prices for every card of a set, one row per finish. `?source=tcg\|cm` | | `GET /swu/sets/:set/statistics` | Price statistics and rarity breakdown. Sealed products excluded. `?variant=normal\|foil` | | `GET /swu/sets/:set/completion-value` | Cost of one copy of every card in the set. Sealed products excluded. | | `GET /swu/sets/trending` | Sets whose CardMarket prices moved most: 7-day average against 30-day average, cards from 1 € up. `?period=7d` `?limit=` | | `GET /swu/analytics/top-cards` | Most expensive cards, or fastest-growing on CardMarket (7-day average against 30-day average, cards from 1 € up; `current_price` is the 7-day average). `?metric=price\|growth` `?source=tcg\|cm` `?limit=` | > Price history is a Pokémon feature: for this game there is no `/cards/:id/price-history`. Current prices are in the card detail and in `/swu/prices/:set`; `metric=growth` works with `source=cm` only, and trending supports `period=7d` only. ### GET /swu/prices/:set (first rows) *200 OK* ```json { "success": true, "source": "both", "set_code": "P26", "set_id": "24854", "data": [ { "id": "swu_f8568585a4c9946c765b3b4a6abd51bc6038294324fcbcd28647fcbc319dd52583d7361f1a10b74d360d", "card_number": "00", "name": "Boba Fett's Rancor - Emotionally Complex Creature", "product_type": "card", "variant": "Normal", "tcgplayer": null, "cardmarket": null }, { "id": "swu_2758375fc678827d4d1e6924950189fb62d82c8b4053cd91e45f5b618a3ac8a12680c80637d210251412", "card_number": "00", "name": "Maul - Master of the Shadow Collective", "product_type": "card", "variant": "Normal", "tcgplayer": null, "cardmarket": null }, { "id": "swu_f9e9deacfd086ae424f6e52d019c673d08ae24b89b853ec25f7dc2ef3c642313114bd1b892e08c0e3b4278", "card_number": "14", "name": "Hera Syndulla - Renegade General", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.24, "mid_price": 0.99, "high_price": 2.99, "market_price": 1.08, "direct_low_price": null, "updated_at": "2026-09-30T20:41:16.825869+00:00" }, "cardmarket": null } ], "total": 57 } ``` ### GET /swu/sets/:set/statistics *200 OK* ```json { "set_info": { "name": "Sector and Regional Promos: Season 2", "set_code": "P26", "set_id": "24854", "total_cards": 54 }, "price_statistics": { "tcgplayer": { "avg_market_price": "34.48", "min_price": 1.08, "max_price": 101.49, "most_expensive": { "id": "swu_0cf5fbec97b75d39255cafcbf4ffbc7206bdbdfb550d02c0e84671bb4196ee03c6076600c94399004d4514", "name": "Luke Skywalker - Answering the Call (Champion)", "price": 101.49 } }, "cardmarket": { "avg_price": "105.00", "min_price": 105, "max_price": 105, "most_expensive": { "id": "swu_c81e56aec90439ccd07c1baac956a4039c72a47482a2f74b0b5040bbc5857d9e38fa1e862b2930bd49eac01a", "name": "Pre Vizsla - Strong-Willed Ruler", "price": 105 }, "trend_direction": null } }, "rarity_breakdown": { "Legendary": 18, "Rare": 25, "Common": 4, "Uncommon": 3, "Special": 4 } } ``` ### GET /swu/sets/:set/completion-value *200 OK* ```json { "set_info": { "name": "Sector and Regional Promos: Season 2", "set_code": "P26", "set_id": "24854", "total_cards": 54 }, "completion_cost": { "tcgplayer": { "currency": "USD", "low_estimate": 1996.17, "market_estimate": 2175.92, "high_estimate": 2720.05 }, "cardmarket": { "currency": "EUR", "low_estimate": 100, "avg_estimate": 100, "trend_estimate": 0 }, "note": "One copy per card (base finish). TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available." }, "breakdown_by_rarity": { "Legendary": { "count": 18, "total_cost": 434.55 }, "Rare": { "count": 25, "total_cost": 602.7 }, "Common": { "count": 4, "total_cost": 141.14 }, "Uncommon": { "count": 3, "total_cost": 62.81 }, "Special": { "count": 4, "total_cost": 0 } } } ``` ### GET /swu/analytics/top-cards *200 OK* ```json { "metric": "price", "source": "tcg", "top_cards": [ { "id": "swu_58b46c53de3f24f5775bef3c334c02bdd526181ba232bad28b0a41ae48366247a4b013868f39cb9b1c0c04fef5", "card_info": { "name": "Yoda - My Ally is the Force (Serialized)", "clean_name": "Yoda My Ally is the Force Serialized", "set_name": "Legends of the Force", "set_code": "LOF", "set_id": "24279", "card_number": "1149", "rarity": "Legendary", "card_type": "Unit", "product_type": "card", "variants": [ "Foil" ], "card_text": "When Played: You may use the Force. If you do, heal 5 damage from a base.
When you use the Force: You may deal damage to a unit equal to twice the number of units you control.", "hp": "9", "cost": "8", "power": "5", "aspect": "Command;Heroism", "traits": "Force;Jedi;Republic", "arena_type": "Ground" }, "current_price": 787.47 }, { "id": "swu_a52e2e9869c3b71a7fe8d34f6c82cca8d6491352a4178215d91e85ae1d1b4152f0e9fd85a3abbdd0fb81c7fc", "card_info": { "name": "The Mandalorian - Devoted Rescuer (Serialized)", "clean_name": "The Mandalorian Devoted Rescuer Serialized", "set_name": "Ashes of the Empire", "set_code": "ASH", "set_id": "24660", "card_number": "889", "rarity": "Legendary", "card_type": "Unit", "product_type": "card", "variants": [ "Normal", "Foil" ], "card_text": "This product comes in Three (3) serializations: /250, /100, and /50.\n
Shielded
If damage would be dealt to another friendly unit, you may defeat a Shield token on this unit. If you do, prevent that damage.", "hp": "4", "cost": "4", "power": "5", "aspect": "Heroism;Vigilance", "traits": "Mandalorian", "arena_type": "Ground" }, "current_price": 600 }, { "id": "swu_b8cc8f6089bd5404163d9e4411d05a536836f1de727854f2f151e5aceff257bf9ac794a17ae971142ff63b45", "card_info": { "name": "Darth Vader - Commanding the First Legion", "clean_name": "Darth Vader Commanding the First Legion", "set_name": "Organized Play Promos", "set_code": "OPP", "set_id": "23455", "card_number": "103", "rarity": "Legendary", "card_type": "Unit", "product_type": "card", "variants": [ "Foil" ], "card_text": "Ambush
When Played: Search the top 10 cards of your deck for any number of [Villainy] units with combined cost 3 or less and play each of them for free.", "hp": "7", "cost": "7", "power": "5", "aspect": "Command;Villainy", "traits": "Force;Imperial;Sith", "arena_type": "Ground" }, "current_price": 425 } ] } ``` ### GET /swu/analytics/top-cards?metric=growth&source=cm *200 OK* ```json { "metric": "growth", "source": "cm", "top_cards": [ { "id": "swu_763a8cb515d2b19da33140fa281e9c76ca752aa68721c6bef2b80e6e2a015d2a41c40675cbded33bd3b586b4", "card_info": { "name": "It's a Trap (Hyperspace Foil)", "clean_name": "Its a Trap Hyperspace Foil", "set_name": "Jump to Lightspeed", "set_code": "JTL", "set_id": "23956", "card_number": "943", "rarity": "Rare", "card_type": "Event", "product_type": "card", "variants": [ "Foil" ], "card_text": "If an opponent controls more space units than you, ready each space unit you control.", "cost": "3", "aspect": "Cunning;Heroism", "traits": "Gambit" }, "current_price": 2.81, "change_7d": "+175.5%" }, { "id": "swu_9dbe40892929e5a85605285395fc5cdc21fd096b3bccccbe60e871ea021d7cf0457b14cd7d8d19a834641cb2", "card_info": { "name": "IG-88 - Programmed to Kill (Hyperspace)", "clean_name": "IG 88 Programmed to Kill Hyperspace", "set_name": "A Lawless Time", "set_code": "LAW", "set_id": "24572", "card_number": "306", "rarity": "Rare", "card_type": "Unit", "product_type": "card", "variants": [ "Normal" ], "card_text": "Shielded", "hp": "3", "cost": "4", "power": "6", "aspect": "Aggression;Vigilance;Villainy", "traits": "Bounty Hunter;Droid;Underworld", "arena_type": "Ground" }, "current_price": 5.98, "change_7d": "+160.0%" }, { "id": "swu_3ec38b8428bd2b8b10afc8ff66e0b3c4df8baab60659dceb9bb8b198a15f10d92b38171f641c51ff12857338", "card_info": { "name": "Sudden Ferocity (Hyperspace Foil)", "clean_name": "Sudden Ferocity Hyperspace Foil", "set_name": "Secrets of Power", "set_code": "SEC", "set_id": "24387", "card_number": "932", "rarity": "Common", "card_type": "Upgrade", "product_type": "card", "variants": [ "Foil" ], "card_text": "Plot (When you deploy a leader, you may play this card from your resources, paying its cost. Replace it with the top card of your deck.)", "hp": "0", "cost": "3", "power": "0", "aspect": "Aggression", "traits": "Innate" }, "current_price": 5.26, "change_7d": "+128.7%" } ] } ``` ### GET /swu/sets/trending *200 OK* ```json { "period": "7d", "trending_sets": [ { "set_name": "Twilight of the Republic", "set_code": "TWI", "set_id": "23597", "card_count": 65, "cardmarket": { "price_change": "-18.0%", "avg_price_current": 2.33, "avg_price_previous": 2.84, "top_movers": [ { "name": "Sanctioner's Shuttle", "change": "+118.5%" }, { "name": "Tactical Advantage", "change": "+61.5%" }, { "name": "Cad Bane, Hostage Taker", "change": "-50.6%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } }, { "set_name": "Shadows of the Galaxy", "set_code": "SHD", "set_id": "23488", "card_count": 80, "cardmarket": { "price_change": "-16.8%", "avg_price_current": 2.79, "avg_price_previous": 3.35, "top_movers": [ { "name": "Poe Dameron, Quick to Improvise", "change": "-46.2%" }, { "name": "Kylo's TIE Silencer, Ruthlessly Efficient", "change": "-44.2%" }, { "name": "Heroic Resolve", "change": "-42.9%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } } ] } ``` ## Data Notes > **Prices.** TCGPlayer and CardMarket prices are refreshed daily. CardMarket has one entry per finish (`normal`, `foil`); a finish CardMarket does not price is left out, so `cardmarket.prices` can be empty. `updated_at` is when that price last changed, not when it was last checked: a stable price keeps an older date. > **`product_type`.** Cards and sealed products are told apart using TCGPlayer data, then CardTrader. Tokens, emblems and oversized cards count as `"card"`. For the very few products whose type cannot be determined, `product_type` is `null`, not `"card"`. > **CardMarket-only sets.** Sets with a negative `set_id` exist only on CardMarket: their cards have 64-character IDs and `tcgplayer: null`. > **Missing links.** `cardmarket.product_url` is absent for some cards; the card data is still valid. Sets with no cards are not listed: they appear as soon as cards are added. ## Star Wars Unlimited API FAQ ### Is there a free Star Wars Unlimited price API? Yes. The free tier (100 requests/hour, 1,000/day) opens the Star Wars Unlimited sets, cards, search and images endpoints, with TCGPlayer and CardMarket prices refreshed daily. Prices by set, set statistics, completion value, trending sets and top cards need the Ultra plan (€29/month) or its 7-day trial. ### Does the Star Wars Unlimited API include CardMarket prices? Yes. Cards return TCGPlayer (USD) prices for every finish and CardMarket (EUR) prices for normal and foil, where that market lists the card. Cards sold only on CardMarket have a 64-character hex id and no TCGPlayer price. ### How do I find the id of a Star Wars Unlimited card? Search with /swu/search?q=… or list a set with /swu/sets/:set. Each card has an id (swu_ + hex for cards on TCGPlayer) to pass to /swu/cards/:id and /swu/images/:id. ### Can I use the same API key for other games? Yes. One PokéWallet API key works for all 12 games, Pokémon and One Piece included, and the rate limits are shared across them. --- # Cardfight!! Vanguard API Documentation Source: https://pokewallet.io/api-docs/cardfight-vanguard REST reference for the Cardfight!! Vanguard API: sets, cards, search and images, with prices from TCGPlayer and CardMarket. Same API key as the Pokémon and One Piece APIs. In short The Cardfight!! Vanguard API returns 420 sets with their cards, search and images, and TCGPlayer (USD) and CardMarket (EUR) prices refreshed daily. These endpoints are free (100 requests/hour) with the same key as the other 11 games; prices by set and set analytics need the Ultra plan (€29/month) or its 7-day trial. At a glance - **Base path:** `https://api.pokewallet.io/cfv` - **Sets:** 420 Cardfight!! Vanguard sets - **Card IDs:** `cfv_` + hex for cards on TCGPlayer; 64 hex characters for CardMarket-only cards - **Prices:** TCGPlayer (USD) for every finish and CardMarket (EUR) for `normal` and `foil`, refreshed daily - **Free on every plan:** Sets, set cards, card details, search and images - **Ultra plan or 7-day trial:** Prices by set, set statistics, completion value, trending sets and top cards - **API key:** The same key as the Pokémon and One Piece APIs, with shared rate limits Updated Oct 19, 2026 ## Quick Start Get started with PokéWallet API in 4 simple steps: ### Create an Account Sign up for free to start using the API. Upgrade anytime from your dashboard. [Sign Up Now](https://pokewallet.io/auth/login?source=pokemon) ### Generate an API Key Create your first API key from the dashboard. ### Make Your First Request Start querying the API with your key. *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cfv/sets" ``` ### Join the Discord Community Stay up to date with new features, ask for help, and connect with other developers. [Join Discord](https://discord.gg/znDxEjmDVP) > **Cardfight!! Vanguard PRO endpoints: Ultra plan required** > > The **Pro plan does not include them**: Pro covers Pokémon and One Piece only. Ultra (€29/month) includes everything in Pro plus the paid endpoints of **all 12 games**. Free endpoints (sets, cards, search, images) work on every plan. > > [Compare plans →](https://pokewallet.io/pricing) ## Cardfight!! Vanguard All Cardfight!! Vanguard endpoints live under `/cfv`. Same API key, same rate limits and the same response format as the Pokémon endpoints. ### Card IDs | Format | Example | Used for | | --- | --- | --- | | `cfv_` + hex | `cfv_5277c3b17c4cf57bd911…` | Every card with a TCGPlayer product, even if it also has CardMarket data | | 64 hex characters, no prefix | `e26f12b8b1fabf19…` | Cards that exist only on CardMarket | > A `cfv_…` ID only works under `/cfv/`. Finishes of the same product (Normal, Foil, …) are one card with one ID; each finish has its own TCGPlayer price. If you request a card by its CardMarket ID and it is linked to a TCGPlayer product, the response uses the canonical `cfv_…` ID. ### Response Format Same shape as the Pokémon API: `card_info`, `images`, `tcgplayer.prices` and `cardmarket.prices` as arrays, `pagination`, errors as `{ "error", "message" }`. Differences: | Field | Cardfight!! Vanguard | | --- | --- | | Game fields in `card_info` | Instead of Pokémon's `hp`, `stage`, `attacks`…, the game's own fields in snake_case (present when the card has them): `grade`, `power`, `shield`, `critical`, `unit`, `skill_icon`, `nation`, `race`, `flavor_text`, `clan`, `trigger`, `imaginary_gift`, `upc` | | `card_type`, `card_text` | Filled from the game's card type and rules text. `card_text` may contain HTML (``, ``…) as provided by TCGPlayer. | | `card_info.variants`, `card_info.set_id` | Always present, on every endpoint | | `product_type` | `"card"`, `"sealed"` or `null` when unknown — see [Data Notes](https://pokewallet.io/api-docs/cardfight-vanguard#cfv-data-notes) | | `release_date` | ISO format, e.g. `"2025-03-07T00:00:00"` (Pokémon uses `"16th June, 2023"`) | | `images.languages` | `["en"]`, or `[]` when there is no image | ## Cardfight!! Vanguard Endpoints ### GET /cfv/sets All Cardfight!! Vanguard sets. ### Response Fields: | Field | Type | Description | | --- | --- | --- | | `name` | string | Set name | | `set_code` | string \| null | Short code. **Not unique**: several sets can share it. | | `set_id` | string | Unique set identifier. Negative for sets that exist only on CardMarket. | | `card_count` | integer | Cards in the set (sealed products excluded). Omitted, not 0, if temporarily unavailable. | | `sealed_count` | integer | Sealed products in the set (booster boxes, displays, decks). Omitted, not 0, if temporarily unavailable. | | `language` | string \| null | Set language | | `release_date` | string \| null | ISO date | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cfv/sets" ``` ### Response Example (first two sets): *200 OK* ```json { "success": true, "data": [ { "name": "A Brush with the Legends", "set_code": "d-bt02", "set_id": "-92", "card_count": 212, "sealed_count": 0, "language": "eng", "release_date": null }, { "name": "Absolute Judgment", "set_code": "g-bt08", "set_id": "-72", "card_count": 143, "sealed_count": 0, "language": "eng", "release_date": null } ], "total": 420 } ``` ### GET /cfv/sets/:set Cards of one set, paginated. Prices are empty in set listings, as on the Pokémon API: use `/cfv/cards/:id` for prices. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `set` | string | Required | `set_id` (recommended, always unique) or `set_code` (exact match, case-insensitive) | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 50, max: 200) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cfv/sets/24738?limit=1" ``` ### Response Example: *200 OK* ```json { "success": true, "set": { "name": "DZ-BT15: Strike of Illusionary Shadows", "set_code": "DZ-BT15", "set_id": "24738", "total_cards": 222, "language": "eng", "release_date": "2026-08-28T00:00:00" }, "cards": [ { "id": "cfv_5277c3b17c4cf57bd911b31886d90bb88bce908dfc85294cfb5077d3963160c955b5c1fd5b7e0706a0da0eedfdbc32c08e3970df0c45", "card_info": { "name": "Hellfire Dragon Emperor, Wirbel Kenig", "clean_name": "Hellfire Dragon Emperor Wirbel Kenig", "set_name": "DZ-BT15: Strike of Illusionary Shadows", "set_code": "DZ-BT15", "set_id": "24738", "card_number": "DZ-BT15/001EN", "rarity": "RRR", "card_type": null, "product_type": "card", "variants": [ "Normal" ], "card_text": "[CONT]:During this fight, this card is also regarded as \"Hellfire Dragon, Wirbel Dragon\", and can only be ridden from a grade 3 with \"Wirbel\" in its card name.
[CONT](VC):The maximum energy you may have in the [CONT] ability of the \"Energy Generator\" in your crest zone gets +5.
[AUTO]:When this unit is placed on (VC), [Energy-Charge 3]. Choose a card with original card name \"Hellfire Dragon, Wirbel Dragon\" from your soul or drop, and until end of this fight, this unit gets all of the original abilities of that card.
[ACT](VC)[1/Turn]:[COST][Energy-Blast 10], retire all of your opponent's rear-guards, and perform one of the following according to the number of cards in your opponent's damage zone.
Four or less - Choose one of your opponent's vanguard, and deal one damage.
Five or more - This unit gets [Power]+10000 until end of turn.", "race": "Flame Dragon", "unit": "Normal Unit", "grade": "3", "power": "13000", "nation": "Dragon Empire", "shield": "0", "critical": "1", "flavor_text": "Swirl and break, hellfire of decimation! Burning Perdition!", "skill_icon": "Twin Drive!!", "imaginary_gift": "Persona Ride" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/713541/cardfight-vanguard-dz-bt15-strike-of-illusionary-shadows-hellfire-dragon-emperor-wirbel-kenig" }, "cardmarket": { "product_name": "Hellfire Dragon Emperor, Wirbel Kenig [D-Format] (V.1 - Triple Rare)", "prices": [], "product_url": "https://www.cardmarket.com/en/Vanguard/Products/Singles/Strike-of-Illusionary-Shadows/Hellfire-Dragon-Emperor-Wirbel-Kenig-D-Format-V1-Triple-Rare" } } ], "pagination": { "page": 1, "limit": 1, "total": 222, "total_pages": 222 } } ``` ### Disambiguation Response: When a `set_code` is shared by several sets, the API returns the candidates instead of a set (status 200, as on the Pokémon API). Call again with the `set_id` you need. *200 OK — /cfv/sets/BT01* ```json { "disambiguation": true, "message": "Multiple sets found for set_code 'BT01'. Use set_id to specify which one.", "matches": [ { "set_id": "-3", "set_code": "bt01", "name": "Descent of the King of Knights", "language": "eng", "release_date": null }, { "set_id": "1115", "set_code": "BT01", "name": "BT01: Descent of the King of Knights", "language": "eng", "release_date": "2011-12-10T00:00:00" } ], "total": 2 } ``` ### GET /cfv/cards/:id Full card with prices. `id` is a `cfv_…` ID or a 64-character CardMarket ID. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cfv/cards/cfv_5277c3b17c4cf57bd911b31886d90bb88bce908dfc85294cfb5077d3963160c955b5c1fd5b7e0706a0da0eedfdbc32c08e3970df0c45" ``` ### Response Example: *200 OK* ```json { "id": "cfv_5277c3b17c4cf57bd911b31886d90bb88bce908dfc85294cfb5077d3963160c955b5c1fd5b7e0706a0da0eedfdbc32c08e3970df0c45", "card_info": { "name": "Hellfire Dragon Emperor, Wirbel Kenig", "clean_name": "Hellfire Dragon Emperor Wirbel Kenig", "set_name": "DZ-BT15: Strike of Illusionary Shadows", "set_code": "DZ-BT15", "set_id": "24738", "card_number": "DZ-BT15/001EN", "rarity": "RRR", "card_type": null, "product_type": "card", "variants": [ "Normal" ], "card_text": "[CONT]:During this fight, this card is also regarded as \"Hellfire Dragon, Wirbel Dragon\", and can only be ridden from a grade 3 with \"Wirbel\" in its card name.
[CONT](VC):The maximum energy you may have in the [CONT] ability of the \"Energy Generator\" in your crest zone gets +5.
[AUTO]:When this unit is placed on (VC), [Energy-Charge 3]. Choose a card with original card name \"Hellfire Dragon, Wirbel Dragon\" from your soul or drop, and until end of this fight, this unit gets all of the original abilities of that card.
[ACT](VC)[1/Turn]:[COST][Energy-Blast 10], retire all of your opponent's rear-guards, and perform one of the following according to the number of cards in your opponent's damage zone.
Four or less - Choose one of your opponent's vanguard, and deal one damage.
Five or more - This unit gets [Power]+10000 until end of turn.", "race": "Flame Dragon", "unit": "Normal Unit", "grade": "3", "power": "13000", "nation": "Dragon Empire", "shield": "0", "critical": "1", "flavor_text": "Swirl and break, hellfire of decimation! Burning Perdition!", "skill_icon": "Twin Drive!!", "imaginary_gift": "Persona Ride" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 0.25, "mid_price": 0.5, "high_price": 3, "market_price": 0.3, "direct_low_price": null, "updated_at": "2026-09-30T20:40:04.764268+00:00", "sub_type_name": "Normal" } ], "url": "https://www.tcgplayer.com/product/713541/cardfight-vanguard-dz-bt15-strike-of-illusionary-shadows-hellfire-dragon-emperor-wirbel-kenig" }, "cardmarket": { "product_name": "Hellfire Dragon Emperor, Wirbel Kenig [D-Format] (V.1 - Triple Rare)", "prices": [ { "variant_type": "normal", "avg": 0.64, "low": 0.44, "trend": 0.96, "avg1": 0.5, "avg7": 0.59, "avg30": 0.59, "updated_at": "2026-09-30T14:49:56.324042+00:00" } ], "product_url": "https://www.cardmarket.com/en/Vanguard/Products/Singles/Strike-of-Illusionary-Shadows/Hellfire-Dragon-Emperor-Wirbel-Kenig-D-Format-V1-Triple-Rare" } } ``` > One entry in `tcgplayer.prices` per finish, identified by `sub_type_name`, and one entry in `cardmarket.prices` per finish, identified by `variant_type` (`normal`, `foil`). `updated_at` is when that price last changed, not when it was last checked. A CardMarket-only card has `tcgplayer: null` and empty `variants`. ### GET /cfv/search Search cards by name or card number. Results have the same shape as `/cfv/cards/:id`, prices included. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | Required | 2–100 characters. Card name (all words, any order) or card number | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 20, max: 100) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cfv/search?q=Hellfire&limit=2" ``` ### Response Example (`results` omitted): *200 OK* ```json { "query": "Hellfire", "results": [ { "id": "f7b35556326fa8eb395a89c477ddb9d66841b65e7aa4b5ddd693e48c9e52a6e5", "card_info": { "name": "Hellfire Seal Dragon, Blockade Inferno", "clean_name": "Hellfire Seal Dragon, Blockade Inferno", "set_name": "Seal Dragons Unleashed", "set_code": "bt11", "set_id": "-61", "card_number": "004", "rarity": null, "card_type": null, "product_type": "card", "variants": [], "card_text": null }, "images": { "languages": [ "en" ] }, "tcgplayer": null, "cardmarket": { "product_name": "Hellfire Seal Dragon, Blockade Inferno", "prices": [ { "variant_type": "normal", "avg": 2, "low": 2.61, "trend": 1.74, "avg1": 2, "avg7": 2, "avg30": 2.4, "updated_at": "2026-09-30T14:49:55.41944+00:00" } ] } } ], "pagination": { "page": 1, "limit": 2, "total": 20, "total_pages": 10 }, "metadata": { "total_count": 20, "tcg": 15, "cardmarket": 16, "tcg_only": 4, "cardmarket_only": 5, "both_sources": 11, "truncated": false } } ``` > `metadata.truncated: true` means more cards match than the search returns: add words to narrow it down. Words match anywhere in the name; a query shorter than 3 characters matches names and card numbers that **start** with it (`27` finds `27`, `027/264`, `0027`). Quotes are ignored; `*`, `%` and `_` are plain text, not wildcards. ### GET /cfv/images/:id The card image, one resolution (`X-Image-Size: unsized`): the `size` parameter of the Pokémon image endpoint does not apply. Cached for 24 hours. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cfv/images/cfv_5277c3b17c4cf57bd911b31886d90bb88bce908dfc85294cfb5077d3963160c955b5c1fd5b7e0706a0da0eedfdbc32c08e3970df0c45" \ --output card ``` ## Ultra endpoints Available on Ultra and Business plans, or during the 7-day trial. The Pro plan covers Pokémon and One Piece only: with Pro these endpoints answer 403 with an `upgrade_url`. Ultra includes everything in Pro. Same parameters and response format as the Pokémon endpoints of the same name. | Endpoint | What it returns | | --- | --- | | `GET /cfv/prices/:set` | TCGPlayer and CardMarket prices for every card of a set, one row per finish. `?source=tcg\|cm` | | `GET /cfv/sets/:set/statistics` | Price statistics and rarity breakdown. Sealed products excluded. `?variant=normal\|foil` | | `GET /cfv/sets/:set/completion-value` | Cost of one copy of every card in the set. Sealed products excluded. | | `GET /cfv/sets/trending` | Sets whose CardMarket prices moved most: 7-day average against 30-day average, cards from 1 € up. `?period=7d` `?limit=` | | `GET /cfv/analytics/top-cards` | Most expensive cards, or fastest-growing on CardMarket (7-day average against 30-day average, cards from 1 € up; `current_price` is the 7-day average). `?metric=price\|growth` `?source=tcg\|cm` `?limit=` | > Price history is a Pokémon feature: for this game there is no `/cards/:id/price-history`. Current prices are in the card detail and in `/cfv/prices/:set`; `metric=growth` works with `source=cm` only, and trending supports `period=7d` only. ### GET /cfv/prices/:set (first rows) *200 OK* ```json { "success": true, "source": "both", "set_code": "DZ-BT15", "set_id": "24738", "data": [ { "id": "cfv_5277c3b17c4cf57bd911b31886d90bb88bce908dfc85294cfb5077d3963160c955b5c1fd5b7e0706a0da0eedfdbc32c08e3970df0c45", "card_number": "DZ-BT15/001EN", "name": "Hellfire Dragon Emperor, Wirbel Kenig", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.25, "mid_price": 0.5, "high_price": 3, "market_price": 0.3, "direct_low_price": null, "updated_at": "2026-09-30T20:40:04.764268+00:00" }, "cardmarket": { "avg": 0.64, "low": 0.44, "trend": 0.96, "avg1": 0.5, "avg7": 0.59, "avg30": 0.59, "updated_at": "2026-09-30T14:49:56.324042+00:00" } }, { "id": "cfv_a7616e7cda480cd8ac92174e2e8c0a613af43ff7d620c414734a285a9db1e679894fa3a78f92cd199805f967f245bf42a5c17772d970", "card_number": "DZ-BT15/002EN", "name": "Brawler, Compete Dragon", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.7, "mid_price": 1.97, "high_price": 4.99, "market_price": 0.93, "direct_low_price": null, "updated_at": "2026-09-30T20:40:04.764268+00:00" }, "cardmarket": { "avg": 2.29, "low": 0.5, "trend": 0.96, "avg1": 2, "avg7": 2.45, "avg30": 2.45, "updated_at": "2026-09-30T14:49:56.324042+00:00" } }, { "id": "cfv_aca4bf9a636c4332a38d5b416baaccb3bf606ef96244f3b8b8a5d1c9a4c6b643fe0203b2bbdaab3bb593cc9c08f8e95768dcf7512046", "card_number": "DZ-BT15/003EN", "name": "Dragritter, Najuura", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.49, "mid_price": 0.77, "high_price": 4.79, "market_price": 0.68, "direct_low_price": null, "updated_at": "2026-09-30T20:40:04.764268+00:00" }, "cardmarket": { "avg": 1.25, "low": 0.75, "trend": 1.11, "avg1": 0.96, "avg7": 1.23, "avg30": 1.23, "updated_at": "2026-09-30T14:49:56.324042+00:00" } } ], "total": 222 } ``` ### GET /cfv/sets/:set/statistics *200 OK* ```json { "set_info": { "name": "DZ-BT15: Strike of Illusionary Shadows", "set_code": "DZ-BT15", "set_id": "24738", "total_cards": 219 }, "price_statistics": { "tcgplayer": { "avg_market_price": "15.53", "min_price": 0.06, "max_price": 850.08, "most_expensive": { "id": "cfv_0814de74c6a01a77565e4a622473ac2d67927e6d1115c62e8085b7b59b4096bedda04d638a68ec3ad35e422fa0bbc80982c2aa26bad9c5bc", "name": "Star-vader, Chaos Breaker Dragon (SEC)", "price": 850.08 } }, "cardmarket": { "avg_price": "6.97", "min_price": 0.05, "max_price": 167.39, "most_expensive": { "id": "cfv_7da2f67d7e4353ea2fde7e1907e3c5891fb3604093f8df28329e33665f3c5a683459801dcc13cadb93694de11b15341b49571dd852f442c8d06709", "name": "Blaster Dark (15thSP)", "price": 167.39 }, "trend_direction": "stable" } }, "rarity_breakdown": { "RRR": 19, "15thSP": 4, "RR": 21, "R": 21, "C": 43, "Double Frame Rare": 19, "Frame Rare": 42, "PGS": 1, "SEC": 6, "SR": 40, "T": 2 } } ``` ### GET /cfv/sets/:set/completion-value *200 OK* ```json { "set_info": { "name": "DZ-BT15: Strike of Illusionary Shadows", "set_code": "DZ-BT15", "set_id": "24738", "total_cards": 219 }, "completion_cost": { "tcgplayer": { "currency": "USD", "low_estimate": 3560.52, "market_estimate": 4334.74, "high_estimate": 6282.97 }, "cardmarket": { "currency": "EUR", "low_estimate": 3511.59, "avg_estimate": 3795.65, "trend_estimate": 1265.7 }, "note": "One copy per card (base finish). TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available." }, "breakdown_by_rarity": { "RRR": { "count": 19, "total_cost": 75.46 }, "15thSP": { "count": 4, "total_cost": 446.73 }, "RR": { "count": 21, "total_cost": 16.6 }, "R": { "count": 21, "total_cost": 4.59 }, "C": { "count": 43, "total_cost": 4.98 }, "Double Frame Rare": { "count": 19, "total_cost": 738.11 }, "Frame Rare": { "count": 42, "total_cost": 135.17 }, "PGS": { "count": 1, "total_cost": 0 }, "SEC": { "count": 6, "total_cost": 1628.18 }, "SR": { "count": 40, "total_cost": 289.26 }, "T": { "count": 2, "total_cost": 0.73 } } } ``` ### GET /cfv/analytics/top-cards *200 OK* ```json { "metric": "price", "source": "tcg", "top_cards": [ { "id": "cfv_13dafb189e5051ab2f3da8ddd310a890f1ff87b0e9be03bacdb4541dc751bd20918302ce864ec3a94d38bfa14bac8551fcaf0916ecc7e2b7", "card_info": { "name": "Blaster Blade", "clean_name": "Blaster Blade", "set_name": "DZ-SS15: The Legendary Vanguards", "set_code": "DZ-SS15", "set_id": "24592", "card_number": "DZ-SS15/PGS01EN", "rarity": "PGS", "card_type": null, "product_type": "card", "variants": [ "Normal" ], "card_text": "[AUTO]:[Counter-Blast 2] When this unit is placed on (VC), you may pay the cost. If you do, choose an opponent's rear-guard, and retire it.
\n[AUTO]:[Counter-Blast 2] When this unit is placed on (RC), if you have a <> vanguard, you may pay the cost. If you do, choose an opponent's grade 2 or greater rear-guard, and retire it.", "clan": "Royal Paladin", "race": "Human", "grade": "2", "power": "9000", "nation": "United Sanctuary", "shield": "0", "critical": "1", "flavor_text": "Shine forth, brave sword and defender of the weak! Blaster Blade!" }, "current_price": 1088.99 }, { "id": "cfv_c752237f2cc982beaf4e125558c64604de8afdef0bfd5efd05fe3921bf6a5cf673de789ad26e0236c4d8727f47b488cb7126fe95453b", "card_info": { "name": "Elementaria Sanctitude", "clean_name": "Elementaria Sanctitude", "set_name": "Bushiroad Event Cards", "set_code": "EVENT", "set_id": "2601", "card_number": "BCS2526/VGS03a", "rarity": "PR", "card_type": null, "product_type": "card", "variants": [ "Normal" ], "card_text": "[CONT]:Sentinel (You may only have up to four cards with \"[CONT]:Sentinel\" in a deck)
[CONT]:You may only have one \"Elementaria Sanctitude\" in a deck.
If your opponent's vanguard has \"Triple Drive\", this ability can be played without paying the cost. (Your vanguard must be grade 3 or less)
Play this with [COST][discard a card from hand] if your vanguard is grade 3 or less!
Choose one of your units, and it cannot be hit until end of that battle. Remove this card.", "race": "Abyss Dragon", "unit": "Blitz Order", "grade": "1", "power": "0", "shield": "0", "critical": "0", "flavor_text": "The spirits answered the voices yearning for tomorrow with a brilliant shield.", "skill_icon": "0" }, "current_price": 1000 }, { "id": "cfv_cb63b98d9b255790a2718b3f0ce13f4d0c3dbe4a01c743b71ac06f1a784f85e7fe822b6fa65d2b3c90fdfa49fc29649f60a02791abec06d4", "card_info": { "name": "One Who Bears Resolve and Sin, Liael=Animus (SEC)", "clean_name": "One Who Bears Resolve and Sin Liael=Animus SEC", "set_name": "DZ-BT13: Parallactic Clash", "set_code": "DZ-BT13", "set_id": "24615", "card_number": "DZ-BT13/SEC03EN", "rarity": "SEC", "card_type": null, "product_type": "card", "variants": [ "Normal" ], "card_text": "[CONT]:This card can only be ridden from a grade 3 card with \"Odium\" or \"Amorta\" in its card name, and the normal ride from those cards also becomes a persona ride.
[AUTO]:When this unit is placed on (VC), choose a grade 3 card with \"Odium\" or \"Amorta\" in its card name from your soul or drop, and this unit gets the card name and all of the abilities of the chosen card until end of this fight. Look at the top five cards of your deck, choose up to one card from among them, and bind it or put it face up as a regress gauge. If you bound a card, choose a card from your bind zone, and put it into drop. If you put a card as regress gauge, choose a card from your regress gauge, and discard it. Shuffle the deck.
[ACT](VC)[1/Turn]:If you used a [Divine Skill] this fight, [COST][Energy-Blast 3], and this unit gets \"[AUTO](VC)[1/Turn]:At the end of the battle this unit attacked, choose one of your rear-guards, and [Stand] it.\" until end of turn.", "race": "Angel", "unit": "Normal Unit", "grade": "3", "power": "13000", "nation": "Dark States", "shield": "0", "critical": "1", "skill_icon": "Twin Drive!!", "imaginary_gift": "Persona Ride" }, "current_price": 997.97 } ] } ``` ### GET /cfv/analytics/top-cards?metric=growth&source=cm *200 OK* ```json { "metric": "growth", "source": "cm", "top_cards": [ { "id": "5e989b44483fdcff9c46d197b14b4dda3842fc39cf9b6b0227f84323a0272803", "card_info": { "name": "Tragic Claw", "clean_name": "Tragic Claw", "set_name": "Glorious Bravery of Radiant Sword", "set_code": "g-bt07", "set_id": "-109", "card_number": "087", "rarity": null, "card_type": null, "product_type": "card", "variants": [], "card_text": null }, "current_price": 5.06, "change_7d": "+360.0%" }, { "id": "eaa46b6bb83bad4ee89cad12c2687b5785b310db582cca148ba7e4d0d289c198", "card_info": { "name": "Imaginary Gift Accel II", "clean_name": "Imaginary Gift Accel II", "set_name": null, "set_code": null, "set_id": null, "card_number": "011", "rarity": null, "card_type": null, "product_type": "card", "variants": [], "card_text": null }, "current_price": 5.1, "change_7d": "+328.6%" }, { "id": "cfv_cb2c8d93a9ae9441075023aed55f8f9235c49e611c59241a19e9b89de0220096f375001fde8e459d4e74f9ab5ac910686b67ba7b763edc", "card_info": { "name": "Zypsophila Fairy, Asher", "clean_name": "Zypsophila Fairy Asher", "set_name": "DZ-SS01: Festival Booster 2024", "set_code": "DZ-SS01", "set_id": "23438", "card_number": "DZ-SS01/Re28EN", "rarity": "RE", "card_type": null, "product_type": "card", "variants": [ "Normal" ], "card_text": "[AUTO]:When this unit is placed on (GC), if your opponent's attacking unit has attacked two or more times this turn, this unit gets [Shield] +15000 until end of that battle. (Active if this battle is its second attack this turn or more)", "race": "Sylph", "unit": "Trigger", "grade": "0", "power": "4000", "nation": "Stoicheia", "shield": "10000", "trigger": "Heal", "critical": "1", "flavor_text": "A phantasmal garden where happiness blooms, that evildoers cannot reach.", "skill_icon": "Boost" }, "current_price": 4.29, "change_7d": "+316.5%" } ] } ``` ### GET /cfv/sets/trending *200 OK* ```json { "period": "7d", "trending_sets": [ { "set_name": "Premium Collection 2020", "set_code": "v-ss05", "set_id": "-97", "card_count": 65, "cardmarket": { "price_change": "+53.4%", "avg_price_current": 12.29, "avg_price_previous": 8.01, "top_movers": [ { "name": "Heat Wave Beast, Geomaglass", "change": "+210.8%" }, { "name": "Heat Wave Beast, Geomaglass", "change": "+195.4%" }, { "name": "Conquering Supreme Dragon, Stunverse Dragon", "change": "+193.2%" } ] }, "tcgplayer": null }, { "set_name": "Trial Deck: Blue Cavalry of the Divine Marine Spirits", "set_code": "g-td04", "set_id": "-37", "card_count": 5, "cardmarket": { "price_change": "+48.6%", "avg_price_current": 5.89, "avg_price_previous": 3.97, "top_movers": [ { "name": "Officer Cadet, Andrey", "change": "+67.2%" }, { "name": "Marine General of the Heavenly Scales, Tidal Bore Dragon", "change": "+62.6%" }, { "name": "One Who Surpasses the Storm, Thavas", "change": "+47.9%" } ] }, "tcgplayer": null } ] } ``` ## Data Notes > **Prices.** TCGPlayer and CardMarket prices are refreshed daily. CardMarket has one entry per finish (`normal`, `foil`); a finish CardMarket does not price is left out, so `cardmarket.prices` can be empty. `updated_at` is when that price last changed, not when it was last checked: a stable price keeps an older date. > **`product_type`.** Cards and sealed products are told apart using TCGPlayer data, then CardTrader. Tokens, emblems and oversized cards count as `"card"`. For the very few products whose type cannot be determined, `product_type` is `null`, not `"card"`. > **CardMarket-only sets.** Sets with a negative `set_id` exist only on CardMarket: their cards have 64-character IDs and `tcgplayer: null`. > **Missing links.** `cardmarket.product_url` is absent for some cards; the card data is still valid. Sets with no cards are not listed: they appear as soon as cards are added. ## Cardfight!! Vanguard API FAQ ### Is there a free Cardfight!! Vanguard price API? Yes. The free tier (100 requests/hour, 1,000/day) opens the Cardfight!! Vanguard sets, cards, search and images endpoints, with TCGPlayer and CardMarket prices refreshed daily. Prices by set, set statistics, completion value, trending sets and top cards need the Ultra plan (€29/month) or its 7-day trial. ### Does the Cardfight!! Vanguard API include CardMarket prices? Yes. Cards return TCGPlayer (USD) prices for every finish and CardMarket (EUR) prices for normal and foil, where that market lists the card. Cards sold only on CardMarket have a 64-character hex id and no TCGPlayer price. ### How do I find the id of a Cardfight!! Vanguard card? Search with /cfv/search?q=… or list a set with /cfv/sets/:set. Each card has an id (cfv_ + hex for cards on TCGPlayer) to pass to /cfv/cards/:id and /cfv/images/:id. ### Can I use the same API key for other games? Yes. One PokéWallet API key works for all 12 games, Pokémon and One Piece included, and the rate limits are shared across them. --- # Riftbound API Documentation Source: https://pokewallet.io/api-docs/riftbound REST reference for the Riftbound API: sets, cards, search and images, with prices from TCGPlayer and CardMarket. Same API key as the Pokémon and One Piece APIs. In short The Riftbound API returns 15 sets with their cards, search and images, and TCGPlayer (USD) and CardMarket (EUR) prices refreshed daily. These endpoints are free (100 requests/hour) with the same key as the other 11 games; prices by set and set analytics need the Ultra plan (€29/month) or its 7-day trial. At a glance - **Base path:** `https://api.pokewallet.io/rft` - **Sets:** 15 Riftbound sets - **Card IDs:** `rft_` + hex for cards on TCGPlayer; 64 hex characters for CardMarket-only cards - **Prices:** TCGPlayer (USD) for every finish and CardMarket (EUR) for `normal` and `foil`, refreshed daily - **Free on every plan:** Sets, set cards, card details, search and images - **Ultra plan or 7-day trial:** Prices by set, set statistics, completion value, trending sets and top cards - **API key:** The same key as the Pokémon and One Piece APIs, with shared rate limits Updated Oct 19, 2026 ## Quick Start Get started with PokéWallet API in 4 simple steps: ### Create an Account Sign up for free to start using the API. Upgrade anytime from your dashboard. [Sign Up Now](https://pokewallet.io/auth/login?source=pokemon) ### Generate an API Key Create your first API key from the dashboard. ### Make Your First Request Start querying the API with your key. *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/rft/sets" ``` ### Join the Discord Community Stay up to date with new features, ask for help, and connect with other developers. [Join Discord](https://discord.gg/znDxEjmDVP) > **Riftbound PRO endpoints: Ultra plan required** > > The **Pro plan does not include them**: Pro covers Pokémon and One Piece only. Ultra (€29/month) includes everything in Pro plus the paid endpoints of **all 12 games**. Free endpoints (sets, cards, search, images) work on every plan. > > [Compare plans →](https://pokewallet.io/pricing) ## Riftbound All Riftbound endpoints live under `/rft`. Same API key, same rate limits and the same response format as the Pokémon endpoints. ### Card IDs | Format | Example | Used for | | --- | --- | --- | | `rft_` + hex | `rft_bf4eaca8debd7fa56f0c…` | Every card with a TCGPlayer product, even if it also has CardMarket data | | 64 hex characters, no prefix | `e26f12b8b1fabf19…` | Cards that exist only on CardMarket | > A `rft_…` ID only works under `/rft/`. Finishes of the same product (Normal, Foil, …) are one card with one ID; each finish has its own TCGPlayer price. If you request a card by its CardMarket ID and it is linked to a TCGPlayer product, the response uses the canonical `rft_…` ID. ### Response Format Same shape as the Pokémon API: `card_info`, `images`, `tcgplayer.prices` and `cardmarket.prices` as arrays, `pagination`, errors as `{ "error", "message" }`. Differences: | Field | Riftbound | | --- | --- | | Game fields in `card_info` | Instead of Pokémon's `hp`, `stage`, `attacks`…, the game's own fields in snake_case (present when the card has them): `domain`, `energy_cost`, `might`, `power_cost`, `tag`, `flavor_text` | | `card_type`, `card_text` | Filled from the game's card type and rules text. `card_text` may contain HTML (``, ``…) as provided by TCGPlayer. | | `card_info.variants`, `card_info.set_id` | Always present, on every endpoint | | `product_type` | `"card"`, `"sealed"` or `null` when unknown — see [Data Notes](https://pokewallet.io/api-docs/riftbound#rft-data-notes) | | `release_date` | ISO format, e.g. `"2025-03-07T00:00:00"` (Pokémon uses `"16th June, 2023"`) | | `images.languages` | `["en"]`, or `[]` when there is no image | ## Riftbound Endpoints ### GET /rft/sets All Riftbound sets. ### Response Fields: | Field | Type | Description | | --- | --- | --- | | `name` | string | Set name | | `set_code` | string \| null | Short code. **Not unique**: several sets can share it. | | `set_id` | string | Unique set identifier. Negative for sets that exist only on CardMarket. | | `card_count` | integer | Cards in the set (sealed products excluded). Omitted, not 0, if temporarily unavailable. | | `sealed_count` | integer | Sealed products in the set (booster boxes, displays, decks). Omitted, not 0, if temporarily unavailable. | | `language` | string \| null | Set language | | `release_date` | string \| null | ISO date | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/rft/sets" ``` ### Response Example (first two sets): *200 OK* ```json { "success": true, "data": [ { "name": "Legacy", "set_code": "LGC", "set_id": "24832", "card_count": 0, "sealed_count": 7, "language": "eng", "release_date": "2027-01-29T00:00:00" }, { "name": "Nexus Night Promos", "set_code": "nnp", "set_id": "-2", "card_count": 1, "sealed_count": 0, "language": "eng", "release_date": null } ], "total": 15 } ``` ### GET /rft/sets/:set Cards of one set, paginated. Prices are empty in set listings, as on the Pokémon API: use `/rft/cards/:id` for prices. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `set` | string | Required | `set_id` (recommended, always unique) or `set_code` (exact match, case-insensitive) | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 50, max: 200) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/rft/sets/24698?limit=1" ``` ### Response Example: *200 OK* ```json { "success": true, "set": { "name": "Vendetta", "set_code": "VEN", "set_id": "24698", "total_cards": 260, "language": "eng", "release_date": "2026-07-31T00:00:00" }, "cards": [ { "id": "rft_bf4eaca8debd7fa56f0cf4cf7ee347989cdeaf71595032dfa475d03388a39904bd977d9707ddc662c47db3b6c36f", "card_info": { "name": "Baccai Sandspinner", "clean_name": "Baccai Sandspinner", "set_name": "Vendetta", "set_code": "VEN", "set_id": "24698", "card_number": "001/166", "rarity": "Common", "card_type": "Unit", "product_type": "card", "variants": [ "Normal", "Foil" ], "card_text": "[EMPOWER 5]. This ability costs 3 less if you control 4 or fewer runes. (Pay the cost: Empower me. Use only if not Empowered.)
\r\n[EMPOWERED] I have [DEFLECT] and [ASSAULT 2]. (Opponents must pay Rune to choose me with a spell or ability. +2 Might while I'm an attacker.)", "tag": "Shurima", "might": "6", "domain": "Fury", "energy_cost": "6" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/707613/riftbound-league-of-legends-trading-card-game-vendetta-baccai-sandspinner" }, "cardmarket": { "product_name": "Baccai Sandspinner", "prices": [], "product_url": "https://www.cardmarket.com/en/Riftbound/Products/Singles/Vendetta/Baccai-Sandspinner" } } ], "pagination": { "page": 1, "limit": 1, "total": 260, "total_pages": 260 } } ``` ### GET /rft/cards/:id Full card with prices. `id` is a `rft_…` ID or a 64-character CardMarket ID. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/rft/cards/rft_bf4eaca8debd7fa56f0cf4cf7ee347989cdeaf71595032dfa475d03388a39904bd977d9707ddc662c47db3b6c36f" ``` ### Response Example: *200 OK* ```json { "id": "rft_bf4eaca8debd7fa56f0cf4cf7ee347989cdeaf71595032dfa475d03388a39904bd977d9707ddc662c47db3b6c36f", "card_info": { "name": "Baccai Sandspinner", "clean_name": "Baccai Sandspinner", "set_name": "Vendetta", "set_code": "VEN", "set_id": "24698", "card_number": "001/166", "rarity": "Common", "card_type": "Unit", "product_type": "card", "variants": [ "Normal", "Foil" ], "card_text": "[EMPOWER 5]. This ability costs 3 less if you control 4 or fewer runes. (Pay the cost: Empower me. Use only if not Empowered.)
\r\n[EMPOWERED] I have [DEFLECT] and [ASSAULT 2]. (Opponents must pay Rune to choose me with a spell or ability. +2 Might while I'm an attacker.)", "tag": "Shurima", "might": "6", "domain": "Fury", "energy_cost": "6" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 0.01, "mid_price": 0.15, "high_price": 2.47, "market_price": 0.05, "direct_low_price": null, "updated_at": "2026-09-20T12:34:15.413415+00:00", "sub_type_name": "Normal" }, { "low_price": 0.03, "mid_price": 0.24, "high_price": 4.99, "market_price": 0.13, "direct_low_price": null, "updated_at": "2026-09-30T20:41:23.09906+00:00", "sub_type_name": "Foil" } ], "url": "https://www.tcgplayer.com/product/707613/riftbound-league-of-legends-trading-card-game-vendetta-baccai-sandspinner" }, "cardmarket": { "product_name": "Baccai Sandspinner", "prices": [ { "variant_type": "normal", "avg": 0.08, "low": 0.02, "trend": 0.05, "avg1": 0.17, "avg7": 0.06, "avg30": 0.04, "updated_at": "2026-09-30T14:50:06.98989+00:00" }, { "variant_type": "foil", "avg": 0.08, "low": 0.02, "trend": 0.12, "avg1": 0.05, "avg7": 0.1, "avg30": 0.14, "updated_at": "2026-09-30T14:50:06.98989+00:00" } ], "product_url": "https://www.cardmarket.com/en/Riftbound/Products/Singles/Vendetta/Baccai-Sandspinner" } } ``` > One entry in `tcgplayer.prices` per finish, identified by `sub_type_name`, and one entry in `cardmarket.prices` per finish, identified by `variant_type` (`normal`, `foil`). `updated_at` is when that price last changed, not when it was last checked. A CardMarket-only card has `tcgplayer: null` and empty `variants`. ### GET /rft/search Search cards by name or card number. Results have the same shape as `/rft/cards/:id`, prices included. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | Required | 2–100 characters. Card name (all words, any order) or card number | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 20, max: 100) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/rft/search?q=Sandspinner&limit=2" ``` ### Response Example (`results` omitted): *200 OK* ```json { "query": "Sandspinner", "results": [ { "id": "rft_bf4eaca8debd7fa56f0cf4cf7ee347989cdeaf71595032dfa475d03388a39904bd977d9707ddc662c47db3b6c36f", "card_info": { "name": "Baccai Sandspinner", "clean_name": "Baccai Sandspinner", "set_name": "Vendetta", "set_code": "VEN", "set_id": "24698", "card_number": "001/166", "rarity": "Common", "card_type": "Unit", "product_type": "card", "variants": [ "Normal", "Foil" ], "card_text": "[EMPOWER 5]. This ability costs 3 less if you control 4 or fewer runes. (Pay the cost: Empower me. Use only if not Empowered.)
\r\n[EMPOWERED] I have [DEFLECT] and [ASSAULT 2]. (Opponents must pay Rune to choose me with a spell or ability. +2 Might while I'm an attacker.)", "tag": "Shurima", "might": "6", "domain": "Fury", "energy_cost": "6" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 0.01, "mid_price": 0.15, "high_price": 2.47, "market_price": 0.05, "direct_low_price": null, "updated_at": "2026-09-20T12:34:15.413415+00:00", "sub_type_name": "Normal" }, { "low_price": 0.03, "mid_price": 0.24, "high_price": 4.99, "market_price": 0.13, "direct_low_price": null, "updated_at": "2026-09-30T20:41:23.09906+00:00", "sub_type_name": "Foil" } ], "url": "https://www.tcgplayer.com/product/707613/riftbound-league-of-legends-trading-card-game-vendetta-baccai-sandspinner" }, "cardmarket": { "product_name": "Baccai Sandspinner", "prices": [ { "variant_type": "normal", "avg": 0.08, "low": 0.02, "trend": 0.05, "avg1": 0.17, "avg7": 0.06, "avg30": 0.04, "updated_at": "2026-09-30T14:50:06.98989+00:00" }, { "variant_type": "foil", "avg": 0.08, "low": 0.02, "trend": 0.12, "avg1": 0.05, "avg7": 0.1, "avg30": 0.14, "updated_at": "2026-09-30T14:50:06.98989+00:00" } ], "product_url": "https://www.cardmarket.com/en/Riftbound/Products/Singles/Vendetta/Baccai-Sandspinner" } } ], "pagination": { "page": 1, "limit": 2, "total": 1, "total_pages": 1 }, "metadata": { "total_count": 1, "tcg": 1, "cardmarket": 1, "tcg_only": 0, "cardmarket_only": 0, "both_sources": 1, "truncated": false } } ``` > `metadata.truncated: true` means more cards match than the search returns: add words to narrow it down. Words match anywhere in the name; a query shorter than 3 characters matches names and card numbers that **start** with it (`27` finds `27`, `027/264`, `0027`). Quotes are ignored; `*`, `%` and `_` are plain text, not wildcards. ### GET /rft/images/:id The card image, one resolution (`X-Image-Size: unsized`): the `size` parameter of the Pokémon image endpoint does not apply. Cached for 24 hours. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/rft/images/rft_bf4eaca8debd7fa56f0cf4cf7ee347989cdeaf71595032dfa475d03388a39904bd977d9707ddc662c47db3b6c36f" \ --output card ``` ## Ultra endpoints Available on Ultra and Business plans, or during the 7-day trial. The Pro plan covers Pokémon and One Piece only: with Pro these endpoints answer 403 with an `upgrade_url`. Ultra includes everything in Pro. Same parameters and response format as the Pokémon endpoints of the same name. | Endpoint | What it returns | | --- | --- | | `GET /rft/prices/:set` | TCGPlayer and CardMarket prices for every card of a set, one row per finish. `?source=tcg\|cm` | | `GET /rft/sets/:set/statistics` | Price statistics and rarity breakdown. Sealed products excluded. `?variant=normal\|foil` | | `GET /rft/sets/:set/completion-value` | Cost of one copy of every card in the set. Sealed products excluded. | | `GET /rft/sets/trending` | Sets whose CardMarket prices moved most: 7-day average against 30-day average, cards from 1 € up. `?period=7d` `?limit=` | | `GET /rft/analytics/top-cards` | Most expensive cards, or fastest-growing on CardMarket (7-day average against 30-day average, cards from 1 € up; `current_price` is the 7-day average). `?metric=price\|growth` `?source=tcg\|cm` `?limit=` | > Price history is a Pokémon feature: for this game there is no `/cards/:id/price-history`. Current prices are in the card detail and in `/rft/prices/:set`; `metric=growth` works with `source=cm` only, and trending supports `period=7d` only. ### GET /rft/prices/:set (first rows) *200 OK* ```json { "success": true, "source": "both", "set_code": "VEN", "set_id": "24698", "data": [ { "id": "rft_bf4eaca8debd7fa56f0cf4cf7ee347989cdeaf71595032dfa475d03388a39904bd977d9707ddc662c47db3b6c36f", "card_number": "001/166", "name": "Baccai Sandspinner", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.01, "mid_price": 0.15, "high_price": 2.47, "market_price": 0.05, "direct_low_price": null, "updated_at": "2026-09-20T12:34:15.413415+00:00" }, "cardmarket": { "avg": 0.08, "low": 0.02, "trend": 0.05, "avg1": 0.17, "avg7": 0.06, "avg30": 0.04, "updated_at": "2026-09-30T14:50:06.98989+00:00" } }, { "id": "rft_bf4eaca8debd7fa56f0cf4cf7ee347989cdeaf71595032dfa475d03388a39904bd977d9707ddc662c47db3b6c36f", "card_number": "001/166", "name": "Baccai Sandspinner", "product_type": "card", "variant": "Foil", "tcgplayer": { "low_price": 0.03, "mid_price": 0.24, "high_price": 4.99, "market_price": 0.13, "direct_low_price": null, "updated_at": "2026-09-30T20:41:23.09906+00:00" }, "cardmarket": { "avg": 0.08, "low": 0.02, "trend": 0.12, "avg1": 0.05, "avg7": 0.1, "avg30": 0.14, "updated_at": "2026-09-30T14:50:06.98989+00:00" } }, { "id": "rft_0f52a25f5a610c4c35e2b6d6d3166ce839f6384d1c3ebcf498c9c9591ba882353344ec6e159ffcc21a76cb7916a8", "card_number": "002/166", "name": "Blade Twirler", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.01, "mid_price": 0.15, "high_price": 2, "market_price": 0.06, "direct_low_price": null, "updated_at": "2026-09-30T20:41:23.09906+00:00" }, "cardmarket": { "avg": 0.08, "low": 0.02, "trend": 0.07, "avg1": 0.02, "avg7": 0.1, "avg30": 0.06, "updated_at": "2026-09-30T14:50:06.98989+00:00" } } ], "total": 360 } ``` ### GET /rft/sets/:set/statistics *200 OK* ```json { "set_info": { "name": "Vendetta", "set_code": "VEN", "set_id": "24698", "total_cards": 248 }, "price_statistics": { "tcgplayer": { "avg_market_price": "58.84", "min_price": 0.08, "max_price": 3229.71, "most_expensive": { "id": "rft_62597d684abc0973df2982423436f0e11b91805812c56e35f6bb872b21acfa3241bd50ab013a8a59061f9ad4f5a65a73ca", "name": "Akali, Rogue Assassin (Signature)", "price": 3229.71 } }, "cardmarket": { "avg_price": "34.59", "min_price": 0.04, "max_price": 2516.75, "most_expensive": { "id": "rft_62597d684abc0973df2982423436f0e11b91805812c56e35f6bb872b21acfa3241bd50ab013a8a59061f9ad4f5a65a73ca", "name": "Akali, Rogue Assassin (Signature)", "price": 2516.75 }, "trend_direction": "up" } }, "rarity_breakdown": { "Common": 58, "Uncommon": 46, "Rare": 46, "Epic": 28, "Showcase": 68 } } ``` ### GET /rft/sets/:set/completion-value *200 OK* ```json { "set_info": { "name": "Vendetta", "set_code": "VEN", "set_id": "24698", "total_cards": 248 }, "completion_cost": { "tcgplayer": { "currency": "USD", "low_estimate": 13385.72, "market_estimate": 14436.01, "high_estimate": 41697.43 }, "cardmarket": { "currency": "EUR", "low_estimate": 8570.56, "avg_estimate": 9669.26, "trend_estimate": 5496.27 }, "note": "One copy per card (base finish). TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available." }, "breakdown_by_rarity": { "Common": { "count": 58, "total_cost": 5.31 }, "Uncommon": { "count": 46, "total_cost": 4.71 }, "Rare": { "count": 46, "total_cost": 9.93 }, "Epic": { "count": 28, "total_cost": 80.13 }, "Showcase": { "count": 68, "total_cost": 14335.93 } } } ``` ### GET /rft/analytics/top-cards *200 OK* ```json { "metric": "price", "source": "tcg", "top_cards": [ { "id": "rft_6c251bb0c09bf7c85f3c729aa5dd3d3a5c475b70de723747a3f6cbc2c80b5d83607f56f864960a56dca9da85ea95484e", "card_info": { "name": "Teemo, Swift Scout (Metal) (Prize Wall)", "clean_name": "Teemo Swift Scout Metal Prize Wall", "set_name": "Riftbound Organized Play Promotional Cards", "set_code": "OPP", "set_id": "24528", "card_number": "263/298", "rarity": "Promo", "card_type": "Legend", "product_type": "card", "variants": [ "Normal" ], "card_text": "You may pay 1 to hide a card with HIDDEN instead of rune.

\r\n
1, Exhaust: Put a Teemo unit you own into your hand from your Champion Zone or the board.\r\n

Disclaimer: This product page is for the Prize Wall printing of this Metal card. This card is only available as non-foil.", "tag": "Teemo", "might": "0", "domain": "Mind;Chaos", "power_cost": "0", "energy_cost": "0" }, "current_price": 4400 }, { "id": "rft_78672ce4f5e5f5fb019ffec841c76cf66654ae9b714a44ef249585f0e107ccca1d85567f760fb0d9d7373b89a50ac5e012", "card_info": { "name": "Ahri, Nine-Tailed Fox (Signature)", "clean_name": "Ahri Nine Tailed Fox Signature", "set_name": "Origins", "set_code": "OGN", "set_id": "24344", "card_number": "303*/298", "rarity": "Showcase", "card_type": "Legend", "product_type": "card", "variants": [ "Foil" ], "card_text": "When an enemy unit attacks a battlefield you control, give it -1 Might this turn, to a minimum of 1 Might.", "tag": "Ahri", "might": "0", "domain": "Calm;Mind", "power_cost": "0", "energy_cost": "0" }, "current_price": 3624.82 }, { "id": "rft_f5e0fde13a9cebcdcfcf0f229525916216efb8e6277db59321e9897f6eaa2a42b4dcb3d69ae8ca2769cc8291aff11a7136", "card_info": { "name": "Ahri, Inquisitive (Signature)", "clean_name": "Ahri Inquisitive Signature", "set_name": "Spiritforged", "set_code": "SFD", "set_id": "24519", "card_number": "227*/221", "rarity": "Showcase", "card_type": "Champion Unit", "product_type": "card", "variants": [ "Foil" ], "card_text": "When I attack or defend, give an enemy unit here -2 Might this turn, to a minimum of 1 Might.", "tag": "Ahri;Ionia", "might": "3", "domain": "Mind", "power_cost": "1", "energy_cost": "3", "flavor_text": "\"Just remember...to follow the fox.\"" }, "current_price": 3334.49 } ] } ``` ### GET /rft/analytics/top-cards?metric=growth&source=cm *200 OK* ```json { "metric": "growth", "source": "cm", "top_cards": [ { "id": "cfa22a9e9afd0e3e578972853ad2043d1af208f49d4c65f69d6c18c246f8a1e0", "card_info": { "name": "Altar to Unity", "clean_name": "Altar to Unity", "set_name": "Promos", "set_code": "promo-rift", "set_id": "-1", "card_number": "275a", "rarity": null, "card_type": null, "product_type": "card", "variants": [], "card_text": null }, "current_price": 759.29, "change_7d": "+104.7%" }, { "id": "8a00c2448e1fca3efd1778f19bb0da970386204487bfe06e37294e0b0d8d7e1c", "card_info": { "name": "Teemo - Scout", "clean_name": "Teemo - Scout", "set_name": "Promos", "set_code": "promo-rift", "set_id": "-1", "card_number": "196", "rarity": null, "card_type": null, "product_type": "card", "variants": [], "card_text": null }, "current_price": 1922.11, "change_7d": "+102.9%" }, { "id": "rft_a65bfe00c289984c2887ece2d8799d5a350d338b5be8f068974ff0034a333efa5badc60a26bb95fca78b27c29a18cd78bc", "card_info": { "name": "Aphelios, Exalted (Signature)", "clean_name": "Aphelios Exalted Signature", "set_name": "Spiritforged", "set_code": "SFD", "set_id": "24519", "card_number": "224*/221", "rarity": "Showcase", "card_type": "Champion Unit", "product_type": "card", "variants": [ "Foil" ], "card_text": "When you attach an Equipment to me, choose one that hasn't been chosen this turn —\r\n
•Ready 2 runes.\r\n
•Channel 1 rune exhausted.\r\n
‚Ä¢Buff a friendly unit.", "tag": "Mount Targon;Aphelios", "might": "4", "domain": "Calm", "power_cost": "1", "energy_cost": "4" }, "current_price": 723.09, "change_7d": "+98.6%" } ] } ``` ### GET /rft/sets/trending *200 OK* ```json { "period": "7d", "trending_sets": [ { "set_name": "Riftbound Promotional Cards", "set_code": "PR", "set_id": "24343", "card_count": 7, "cardmarket": { "price_change": "-7.8%", "avg_price_current": 41.28, "avg_price_previous": 44.78, "top_movers": [ { "name": "Ahri - Alluring", "change": "-25.9%" }, { "name": "Teemo - Scout", "change": "-21.4%" }, { "name": "Bird // Brush", "change": "+19.0%" } ] }, "tcgplayer": { "status": "work_in_progress", "message": "TCGPlayer price history not yet available" } }, { "set_name": "Promos", "set_code": "promo-rift", "set_id": "-1", "card_count": 18, "cardmarket": { "price_change": "+2.3%", "avg_price_current": 22.35, "avg_price_previous": 21.85, "top_movers": [ { "name": "Bird // Sprite", "change": "+29.1%" }, { "name": "Sprite // Bird", "change": "+24.4%" }, { "name": "Order Rune", "change": "+12.8%" } ] }, "tcgplayer": null } ] } ``` ## Data Notes > **Prices.** TCGPlayer and CardMarket prices are refreshed daily. CardMarket has one entry per finish (`normal`, `foil`); a finish CardMarket does not price is left out, so `cardmarket.prices` can be empty. `updated_at` is when that price last changed, not when it was last checked: a stable price keeps an older date. > **`product_type`.** Cards and sealed products are told apart using TCGPlayer data, then CardTrader. Tokens, emblems and oversized cards count as `"card"`. For the very few products whose type cannot be determined, `product_type` is `null`, not `"card"`. > **CardMarket-only sets.** Sets with a negative `set_id` exist only on CardMarket: their cards have 64-character IDs and `tcgplayer: null`. > **Missing links.** `cardmarket.product_url` is absent for some cards; the card data is still valid. Sets with no cards are not listed: they appear as soon as cards are added. ## Riftbound API FAQ ### Is there a free Riftbound price API? Yes. The free tier (100 requests/hour, 1,000/day) opens the Riftbound sets, cards, search and images endpoints, with TCGPlayer and CardMarket prices refreshed daily. Prices by set, set statistics, completion value, trending sets and top cards need the Ultra plan (€29/month) or its 7-day trial. ### Does the Riftbound API include CardMarket prices? Yes. Cards return TCGPlayer (USD) prices for every finish and CardMarket (EUR) prices for normal and foil, where that market lists the card. Cards sold only on CardMarket have a 64-character hex id and no TCGPlayer price. ### How do I find the id of a Riftbound card? Search with /rft/search?q=… or list a set with /rft/sets/:set. Each card has an id (rft_ + hex for cards on TCGPlayer) to pass to /rft/cards/:id and /rft/images/:id. ### Can I use the same API key for other games? Yes. One PokéWallet API key works for all 12 games, Pokémon and One Piece included, and the rate limits are shared across them. --- # Cyberpunk API Documentation Source: https://pokewallet.io/api-docs/cyberpunk REST reference for the Cyberpunk API: sets, cards, search and images, with prices from TCGPlayer and CardMarket. Same API key as the Pokémon and One Piece APIs. In short The Cyberpunk API returns 15 sets with their cards, search and images, and TCGPlayer (USD) and CardMarket (EUR) prices refreshed daily. These endpoints are free (100 requests/hour) with the same key as the other 11 games; prices by set and set analytics need the Ultra plan (€29/month) or its 7-day trial. At a glance - **Base path:** `https://api.pokewallet.io/cpk` - **Sets:** 15 Cyberpunk sets - **Card IDs:** `cpk_` + hex for cards on TCGPlayer; 64 hex characters for CardMarket-only cards - **Prices:** TCGPlayer (USD) for every finish and CardMarket (EUR) for `normal` and `foil`, refreshed daily - **Free on every plan:** Sets, set cards, card details, search and images - **Ultra plan or 7-day trial:** Prices by set, set statistics, completion value, trending sets and top cards - **API key:** The same key as the Pokémon and One Piece APIs, with shared rate limits Updated Oct 19, 2026 ## Quick Start Get started with PokéWallet API in 4 simple steps: ### Create an Account Sign up for free to start using the API. Upgrade anytime from your dashboard. [Sign Up Now](https://pokewallet.io/auth/login?source=pokemon) ### Generate an API Key Create your first API key from the dashboard. ### Make Your First Request Start querying the API with your key. *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cpk/sets" ``` ### Join the Discord Community Stay up to date with new features, ask for help, and connect with other developers. [Join Discord](https://discord.gg/znDxEjmDVP) > **Cyberpunk PRO endpoints: Ultra plan required** > > The **Pro plan does not include them**: Pro covers Pokémon and One Piece only. Ultra (€29/month) includes everything in Pro plus the paid endpoints of **all 12 games**. Free endpoints (sets, cards, search, images) work on every plan. > > [Compare plans →](https://pokewallet.io/pricing) ## Cyberpunk All Cyberpunk endpoints live under `/cpk`. Same API key, same rate limits and the same response format as the Pokémon endpoints. ### Card IDs | Format | Example | Used for | | --- | --- | --- | | `cpk_` + hex | `cpk_972fd08a1e74f249bb01…` | Every card with a TCGPlayer product, even if it also has CardMarket data | | 64 hex characters, no prefix | `e26f12b8b1fabf19…` | Cards that exist only on CardMarket | > A `cpk_…` ID only works under `/cpk/`. Finishes of the same product (Normal, Foil, …) are one card with one ID; each finish has its own TCGPlayer price. If you request a card by its CardMarket ID and it is linked to a TCGPlayer product, the response uses the canonical `cpk_…` ID. ### Response Format Same shape as the Pokémon API: `card_info`, `images`, `tcgplayer.prices` and `cardmarket.prices` as arrays, `pagination`, errors as `{ "error", "message" }`. Differences: | Field | Cyberpunk | | --- | --- | | Game fields in `card_info` | Instead of Pokémon's `hp`, `stage`, `attacks`…, the game's own fields in snake_case (present when the card has them): `color`, `eddies`, `tags`, `ram`, `cost`, `power` | | `card_type`, `card_text` | Filled from the game's card type and rules text. `card_text` may contain HTML (``, ``…) as provided by TCGPlayer. | | `card_info.variants`, `card_info.set_id` | Always present, on every endpoint | | `product_type` | `"card"`, `"sealed"` or `null` when unknown — see [Data Notes](https://pokewallet.io/api-docs/cyberpunk#cpk-data-notes) | | `release_date` | ISO format, e.g. `"2025-03-07T00:00:00"` (Pokémon uses `"16th June, 2023"`) | | `images.languages` | `["en"]`, or `[]` when there is no image | ## Cyberpunk Endpoints ### GET /cpk/sets All Cyberpunk sets. ### Response Fields: | Field | Type | Description | | --- | --- | --- | | `name` | string | Set name | | `set_code` | string \| null | Short code. **Not unique**: several sets can share it. | | `set_id` | string | Unique set identifier. Negative for sets that exist only on CardMarket. | | `card_count` | integer | Cards in the set (sealed products excluded). Omitted, not 0, if temporarily unavailable. | | `sealed_count` | integer | Sealed products in the set (booster boxes, displays, decks). Omitted, not 0, if temporarily unavailable. | | `language` | string \| null | Set language | | `release_date` | string \| null | ISO date | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cpk/sets" ``` ### Response Example (first two sets): *200 OK* ```json { "success": true, "data": [ { "name": "Alpha Edition", "set_code": "alpha", "set_id": "-2", "card_count": 34, "sealed_count": 0, "language": "eng", "release_date": null }, { "name": "Alpha Kit", "set_code": "AK", "set_id": "24881", "card_count": 0, "sealed_count": 1, "language": "eng", "release_date": "2026-09-04T00:00:00" } ], "total": 15 } ``` ### GET /cpk/sets/:set Cards of one set, paginated. Prices are empty in set listings, as on the Pokémon API: use `/cpk/cards/:id` for prices. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `set` | string | Required | `set_id` (recommended, always unique) or `set_code` (exact match, case-insensitive) | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 50, max: 200) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cpk/sets/24846?limit=1" ``` ### Response Example: *200 OK* ```json { "success": true, "set": { "name": "Embracing Power - Beta Starter Deck", "set_code": null, "set_id": "24846", "total_cards": 22, "language": "eng", "release_date": "2026-09-10T00:00:00" }, "cards": [ { "id": "cpk_972fd08a1e74f249bb019ef3707ff747377e4edf51df50f4d5c13956e33f050d7fe4525a3af2a94984b4b80223", "card_info": { "name": "Yorinobu Arasaka - Embracing Destruction", "clean_name": "Yorinobu Arasaka Embracing Destruction", "set_name": "Embracing Power - Beta Starter Deck", "set_code": null, "set_id": "24846", "card_number": "B001", "rarity": "Epic", "card_type": "Legend", "product_type": "card", "variants": [ "Foil" ], "card_text": "The first time a friendly ARASAKA Unit attacks each turn, draw 1. Then, if you have less than 20 Street Cred (Street Cred), discard 1.", "ram": "x2", "cost": "0", "tags": "Arasaka;Corpo", "color": "Red", "power": "0", "eddies": "true" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/714119/cyberpunk-tcg-embracing-power-beta-starter-deck-yorinobu-arasaka-embracing-destruction" }, "cardmarket": { "product_name": "Yorinobu Arasaka - Embracing Destruction", "prices": [], "product_url": "https://www.cardmarket.com/en/Cyberpunk/Products/Singles/Embracing-Power-Beta-Starter-Deck/Yorinobu-Arasaka-Embracing-Destruction" } } ], "pagination": { "page": 1, "limit": 1, "total": 22, "total_pages": 22 } } ``` ### GET /cpk/cards/:id Full card with prices. `id` is a `cpk_…` ID or a 64-character CardMarket ID. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cpk/cards/cpk_972fd08a1e74f249bb019ef3707ff747377e4edf51df50f4d5c13956e33f050d7fe4525a3af2a94984b4b80223" ``` ### Response Example: *200 OK* ```json { "id": "cpk_972fd08a1e74f249bb019ef3707ff747377e4edf51df50f4d5c13956e33f050d7fe4525a3af2a94984b4b80223", "card_info": { "name": "Yorinobu Arasaka - Embracing Destruction", "clean_name": "Yorinobu Arasaka Embracing Destruction", "set_name": "Embracing Power - Beta Starter Deck", "set_code": null, "set_id": "24846", "card_number": "B001", "rarity": "Epic", "card_type": "Legend", "product_type": "card", "variants": [ "Foil" ], "card_text": "The first time a friendly ARASAKA Unit attacks each turn, draw 1. Then, if you have less than 20 Street Cred (Street Cred), discard 1.", "ram": "x2", "cost": "0", "tags": "Arasaka;Corpo", "color": "Red", "power": "0", "eddies": "true" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [ { "low_price": 5.27, "mid_price": 7, "high_price": 9.99, "market_price": 6.74, "direct_low_price": null, "updated_at": "2026-09-30T20:41:25.14679+00:00", "sub_type_name": "Foil" } ], "url": "https://www.tcgplayer.com/product/714119/cyberpunk-tcg-embracing-power-beta-starter-deck-yorinobu-arasaka-embracing-destruction" }, "cardmarket": { "product_name": "Yorinobu Arasaka - Embracing Destruction", "prices": [ { "variant_type": "normal", "avg": null, "low": 4.45, "trend": null, "avg1": null, "avg7": null, "avg30": null, "updated_at": "2026-09-30T14:48:05.607944+00:00" }, { "variant_type": "foil", "avg": 8, "low": 4.45, "trend": 5.12, "avg1": null, "avg7": null, "avg30": null, "updated_at": "2026-09-30T14:48:05.607944+00:00" } ], "product_url": "https://www.cardmarket.com/en/Cyberpunk/Products/Singles/Embracing-Power-Beta-Starter-Deck/Yorinobu-Arasaka-Embracing-Destruction" } } ``` > One entry in `tcgplayer.prices` per finish, identified by `sub_type_name`, and one entry in `cardmarket.prices` per finish, identified by `variant_type` (`normal`, `foil`). `updated_at` is when that price last changed, not when it was last checked. A CardMarket-only card has `tcgplayer: null` and empty `variants`. ### GET /cpk/search Search cards by name or card number. Results have the same shape as `/cpk/cards/:id`, prices included. ### Parameters: | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `q` | string | Required | 2–100 characters. Card name (all words, any order) or card number | | `page` | number | Optional | Page number (default: 1) | | `limit` | number | Optional | Results per page (default: 20, max: 100) | ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cpk/search?q=Destruction&limit=2" ``` ### Response Example (`results` omitted): *200 OK* ```json { "query": "Destruction", "results": [ { "id": "cpk_0442b2bfc746fe1da0285a61e7c438ec3fdcad45d262ca0d5fc174033a522b0c10d8941233b12f2cb3da", "card_info": { "name": "Yorinobu Arasaka - Embracing Destruction", "clean_name": "Yorinobu Arasaka Embracing Destruction", "set_name": "Embracing Power - Retail Starter Deck", "set_code": null, "set_id": "24858", "card_number": "001", "rarity": "Epic", "card_type": "Legend", "product_type": "card", "variants": [ "Normal" ], "card_text": "The first time a friendly ARASAKA Unit attacks each turn, draw 1. Then, if you have less than 20 Street Cred (Street Cred), discard 1.", "ram": "x2", "cost": "0", "tags": "Arasaka;Corpo", "color": "Red", "power": "0", "eddies": "TRUE" }, "images": { "languages": [ "en" ] }, "tcgplayer": { "prices": [], "url": "https://www.tcgplayer.com/product/715219/cyberpunk-tcg-embracing-power-retail-starter-deck-yorinobu-arasaka-embracing-destruction" }, "cardmarket": null } ], "pagination": { "page": 1, "limit": 2, "total": 9, "total_pages": 5 }, "metadata": { "total_count": 9, "tcg": 7, "cardmarket": 5, "tcg_only": 4, "cardmarket_only": 2, "both_sources": 3, "truncated": false } } ``` > `metadata.truncated: true` means more cards match than the search returns: add words to narrow it down. Words match anywhere in the name; a query shorter than 3 characters matches names and card numbers that **start** with it (`27` finds `27`, `027/264`, `0027`). Quotes are ignored; `*`, `%` and `_` are plain text, not wildcards. ### GET /cpk/images/:id The card image, one resolution (`X-Image-Size: unsized`): the `size` parameter of the Pokémon image endpoint does not apply. Cached for 24 hours. ### Example Request: *cURL* ```bash curl -H "X-API-Key: pk_live_your_key_here" \ "https://api.pokewallet.io/cpk/images/cpk_972fd08a1e74f249bb019ef3707ff747377e4edf51df50f4d5c13956e33f050d7fe4525a3af2a94984b4b80223" \ --output card ``` ## Ultra endpoints Available on Ultra and Business plans, or during the 7-day trial. The Pro plan covers Pokémon and One Piece only: with Pro these endpoints answer 403 with an `upgrade_url`. Ultra includes everything in Pro. Same parameters and response format as the Pokémon endpoints of the same name. | Endpoint | What it returns | | --- | --- | | `GET /cpk/prices/:set` | TCGPlayer and CardMarket prices for every card of a set, one row per finish. `?source=tcg\|cm` | | `GET /cpk/sets/:set/statistics` | Price statistics and rarity breakdown. Sealed products excluded. `?variant=normal\|foil` | | `GET /cpk/sets/:set/completion-value` | Cost of one copy of every card in the set. Sealed products excluded. | | `GET /cpk/sets/trending` | Sets whose CardMarket prices moved most: 7-day average against 30-day average, cards from 1 € up. `?period=7d` `?limit=` | | `GET /cpk/analytics/top-cards` | Most expensive cards, or fastest-growing on CardMarket (7-day average against 30-day average, cards from 1 € up; `current_price` is the 7-day average). `?metric=price\|growth` `?source=tcg\|cm` `?limit=` | > Price history is a Pokémon feature: for this game there is no `/cards/:id/price-history`. Current prices are in the card detail and in `/cpk/prices/:set`; `metric=growth` works with `source=cm` only, and trending supports `period=7d` only. ### GET /cpk/prices/:set (first rows) *200 OK* ```json { "success": true, "source": "both", "set_code": null, "set_id": "24846", "data": [ { "id": "cpk_972fd08a1e74f249bb019ef3707ff747377e4edf51df50f4d5c13956e33f050d7fe4525a3af2a94984b4b80223", "card_number": "B001", "name": "Yorinobu Arasaka - Embracing Destruction", "product_type": "card", "variant": "Foil", "tcgplayer": { "low_price": 5.27, "mid_price": 7, "high_price": 9.99, "market_price": 6.74, "direct_low_price": null, "updated_at": "2026-09-30T20:41:25.14679+00:00" }, "cardmarket": { "avg": 8, "low": 4.45, "trend": 5.12, "avg1": null, "avg7": null, "avg30": null, "updated_at": "2026-09-30T14:48:05.607944+00:00" } }, { "id": "cpk_654472bb1112e08f84f34c9bdccf835f740866abeceecd44d496c97ffedc4ce2a935bf2655fe6d48ae94c4c6ac", "card_number": "B002", "name": "Chrome Fang", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 0.1, "mid_price": 0.25, "high_price": 0.97, "market_price": 0.2, "direct_low_price": null, "updated_at": "2026-09-30T20:41:25.14679+00:00" }, "cardmarket": { "avg": null, "low": 0.02, "trend": 0.08, "avg1": null, "avg7": null, "avg30": null, "updated_at": "2026-09-30T14:48:05.607944+00:00" } }, { "id": "cpk_d32fca4c8bd4a1218c159f9f56242bab95d31937c62ea9627cb5d585b8e07683e8ef7a30cca81a94f69f4f6ad4", "card_number": "B003", "name": "Minotaur", "product_type": "card", "variant": "Normal", "tcgplayer": { "low_price": 6.03, "mid_price": 8.38, "high_price": 15.99, "market_price": 7.1, "direct_low_price": null, "updated_at": "2026-09-30T20:41:25.14679+00:00" }, "cardmarket": { "avg": 3, "low": 5.85, "trend": 7.84, "avg1": null, "avg7": null, "avg30": null, "updated_at": "2026-09-30T14:48:05.607944+00:00" } } ], "total": 22 } ``` ### GET /cpk/sets/:set/statistics *200 OK* ```json { "set_info": { "name": "Embracing Power - Beta Starter Deck", "set_code": null, "set_id": "24846", "total_cards": 20 }, "price_statistics": { "tcgplayer": { "avg_market_price": "2.33", "min_price": 0.17, "max_price": 9.44, "most_expensive": { "id": "cpk_cb657d798d1530230aa273a8dcb52a2d8a82fbfbd329a92ab9c0e6cc0afb8bdc2d0e07b2bc04d13cbc9d8e29b5", "name": "Goro Takemura - Losing His Way", "price": 9.44 } }, "cardmarket": { "avg_price": "2.11", "min_price": 0.07, "max_price": 8, "most_expensive": { "id": "cpk_972fd08a1e74f249bb019ef3707ff747377e4edf51df50f4d5c13956e33f050d7fe4525a3af2a94984b4b80223", "name": "Yorinobu Arasaka - Embracing Destruction", "price": 8 }, "trend_direction": null } }, "rarity_breakdown": { "Epic": 3, "Common": 9, "Uncommon": 7, "Rare": 1 } } ``` ### GET /cpk/sets/:set/completion-value *200 OK* ```json { "set_info": { "name": "Embracing Power - Beta Starter Deck", "set_code": null, "set_id": "24846", "total_cards": 20 }, "completion_cost": { "tcgplayer": { "currency": "USD", "low_estimate": 33.94, "market_estimate": 46.51, "high_estimate": 88.77 }, "cardmarket": { "currency": "EUR", "low_estimate": 25.46, "avg_estimate": 18.3, "trend_estimate": 18.25 }, "note": "One copy per card (base finish). TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available." }, "breakdown_by_rarity": { "Epic": { "count": 3, "total_cost": 22.67 }, "Common": { "count": 9, "total_cost": 2.41 }, "Uncommon": { "count": 7, "total_cost": 19.86 }, "Rare": { "count": 1, "total_cost": 1.57 } } } ``` ### GET /cpk/analytics/top-cards *200 OK* ```json { "metric": "price", "source": "tcg", "top_cards": [ { "id": "cpk_8cf2b65cee51b0ae38c2e8cc450312a2858fde6d0542e4896096ce8e09bd778bab990acbae3bf90a0b376d82e6", "card_info": { "name": "Johnny Silverhand - Rocking Renegade (ISecret)", "clean_name": "Johnny Silverhand Rocking Renegade ISecret", "set_name": "Welcome to Night City - Beta", "set_code": null, "set_id": "24845", "card_number": "B168", "rarity": "Iconic Secret", "card_type": "Legend", "product_type": "card", "variants": [ "Foil" ], "card_text": "2 Eddies [Spend Icon:] A friendly Unit can attack spent rival Units the turn it's played. If it's a ROCKER Unit, also give it +2 power this turn. This effect costs -1 Eddies for each friendly Gig with 8+ value.", "ram": "x2", "cost": "0", "tags": "Merc;Rocker;Samurai", "color": "Red", "power": "0", "eddies": "TRUE" }, "current_price": 885.87 }, { "id": "cpk_0fb3213e45a23b40f3d7a3299ca38d9ad80167b184ab3eb8b1ec258f6e576f84f2e35919f0fa22000563c3941a", "card_info": { "name": "Sasha Yakovleva - Won't Let You Down (ISecret)", "clean_name": "Sasha Yakovleva Wont Let You Down ISecret", "set_name": "Welcome to Night City - Beta", "set_code": null, "set_id": "24845", "card_number": "B169", "rarity": "Iconic Secret", "card_type": "Legend", "product_type": "card", "variants": [ "Foil" ], "card_text": "[GO SOLO]
[ATTACK] Reveal the top card of your deck and add it to your hand. This Unit gains power equal to that card's cost this turn.
[DEFEATED] A Rival discards 1.", "ram": "x2", "cost": "5", "tags": "Maine's Crew;Merc;Netrunner", "color": "Blue", "power": "0", "eddies": "TRUE" }, "current_price": 797.14 }, { "id": "cpk_49d358a9c71a9ac4e50371f944a248c8b59af9e21e88657b1077622c5f0b5a9842aae0fe65b0a981a92d7b93e4", "card_info": { "name": "Judy Alvarez - Nothing to Doubt (ISecret)", "clean_name": "Judy Alvarez Nothing to Doubt ISecret", "set_name": "Welcome to Night City - Beta", "set_code": null, "set_id": "24845", "card_number": "B171", "rarity": "Iconic Secret", "card_type": "Unit", "product_type": "card", "variants": [ "Foil" ], "card_text": "1 Eddies [Spend Icon:] Reveal the top card of your deck. You may play it for free. Otherwise, add it to your hand.", "ram": "x5", "cost": "6", "tags": "Ganger;Mox;Techie", "color": "Blue", "power": "6", "eddies": "FALSE" }, "current_price": 719.35 } ] } ``` ### GET /cpk/analytics/top-cards?metric=growth&source=cm *200 OK* ```json { "metric": "growth", "source": "cm", "top_cards": [] } ``` ### GET /cpk/sets/trending *200 OK* ```json { "period": "7d", "trending_sets": [] } ``` ## Data Notes > **Prices.** TCGPlayer and CardMarket prices are refreshed daily. CardMarket has one entry per finish (`normal`, `foil`); a finish CardMarket does not price is left out, so `cardmarket.prices` can be empty. `updated_at` is when that price last changed, not when it was last checked: a stable price keeps an older date. > **`product_type`.** Cards and sealed products are told apart using TCGPlayer data, then CardTrader. Tokens, emblems and oversized cards count as `"card"`. For the very few products whose type cannot be determined, `product_type` is `null`, not `"card"`. > **CardMarket-only sets.** Sets with a negative `set_id` exist only on CardMarket: their cards have 64-character IDs and `tcgplayer: null`. > **Missing links.** `cardmarket.product_url` is absent for some cards; the card data is still valid. Sets with no cards are not listed: they appear as soon as cards are added. ## Cyberpunk API FAQ ### Is there a free Cyberpunk price API? Yes. The free tier (100 requests/hour, 1,000/day) opens the Cyberpunk sets, cards, search and images endpoints, with TCGPlayer and CardMarket prices refreshed daily. Prices by set, set statistics, completion value, trending sets and top cards need the Ultra plan (€29/month) or its 7-day trial. ### Does the Cyberpunk API include CardMarket prices? Yes. Cards return TCGPlayer (USD) prices for every finish and CardMarket (EUR) prices for normal and foil, where that market lists the card. Cards sold only on CardMarket have a 64-character hex id and no TCGPlayer price. ### How do I find the id of a Cyberpunk card? Search with /cpk/search?q=… or list a set with /cpk/sets/:set. Each card has an id (cpk_ + hex for cards on TCGPlayer) to pass to /cpk/cards/:id and /cpk/images/:id. ### Can I use the same API key for other games? Yes. One PokéWallet API key works for all 12 games, Pokémon and One Piece included, and the rate limits are shared across them. --- Official SDKs · v0.1.3 · MIT # PokéWallet SDKs for TypeScript and Python Source: https://pokewallet.io/developers/sdk Official TypeScript and Python SDKs for the PokéWallet card price API. One interface for Pokémon, One Piece and ten more trading card games, with TCGPlayer (USD) and CardMarket (EUR) prices, typed results, automatic pagination and typed errors. [Get a free API key](https://pokewallet.io/dashboard) [View on GitHub](https://github.com/pokewallet-lab/pokewallet-sdk) ## TypeScript @pokewallet/sdk ``` npm install @pokewallet/sdk ``` - Node 18+ - zero dependencies - ESM + CJS - [npm](https://www.npmjs.com/package/@pokewallet/sdk) ## Python pokewallet ``` pip install pokewallet ``` - Python 3.9+ - httpx only - sync + async - [PyPI](https://pypi.org/project/pokewallet/) ## Quickstart 1. [Create a free key](https://pokewallet.io/dashboard) in the dashboard. Keys start with `pk_`. 2. Put it in `POKEWALLET_API_KEY`. The SDKs read it by themselves. 3. Run the first script below. Free keys can search and read cards and sets. *TypeScript* ```typescript import { PokeWallet } from '@pokewallet/sdk' const pw = new PokeWallet() // reads POKEWALLET_API_KEY const results = await pw.pokemon.search('charizard', { limit: 3 }) for (const card of results.items) { const usd = card.tcgplayer?.prices[0]?.market // TCGPlayer market price const eur = card.cardmarket?.prices[0]?.trend // CardMarket trend price console.log(`${card.name} | ${card.setName} #${card.number} | $${usd} / €${eur}`) } // Every page of a set, without handling page numbers let count = 0 for await (const c of pw.pokemon.setCards('PLF', { maxItems: 120 })) count++ // Other games use the same methods const lotus = await pw.games.mtg.search('black lotus', { limit: 2 }) const luffy = await pw.onepiece.search('luffy', { limit: 2 }) ``` *Python* ```python from pokewallet import PokeWallet pw = PokeWallet() # reads POKEWALLET_API_KEY results = pw.pokemon.search("charizard", limit=3) for card in results.items: usd = card.tcgplayer.prices[0].market if card.tcgplayer and card.tcgplayer.prices else None eur = card.cardmarket.prices[0].trend if card.cardmarket and card.cardmarket.prices else None print(f"{card.name} | {card.set_name} #{card.number} | ${usd} / €{eur}") # Every page of a set, without handling page numbers count = sum(1 for _ in pw.pokemon.set_cards("PLF", max_items=120)) # Other games use the same methods lotus = pw.games.mtg.search("black lotus", limit=2) luffy = pw.onepiece.search("luffy", limit=2) ``` *Python async* ```python import asyncio from pokewallet import AsyncPokeWallet async def main(): async with AsyncPokeWallet() as pw: pikachu, lotus = await asyncio.gather( pw.pokemon.search("pikachu", limit=2), pw.games.mtg.search("black lotus", limit=2), ) async for card in pw.pokemon.set_cards("PLF", max_items=60): pass asyncio.run(main()) ``` No key yet? `health()` and `listGames()` work without one. More runnable scripts (pagination, errors, Pro endpoints, other games, async) are in the [examples folder](https://github.com/pokewallet-lab/pokewallet-sdk/tree/main/examples). ## One interface, twelve games The API has three shapes: Pokémon, One Piece and the ten other games use different routes, set identifiers and pagination. The SDKs hide those differences, so every game answers to the same methods and returns the same fields. `pw.pokemon` Pokémon TCG, with price history `pw.onepiece` One Piece Card Game `pw.games.` - mtg - ygo - lor - fab - dbs - dgm - swu - cfv - rft - cpk ## Everything available | TypeScript | Python | Returns | Access | | --- | --- | --- | --- | | `search(q, {page, limit})` | `search(q, page=, limit=)` | One page of cards with prices | Free | | `searchAll(q, {limit, maxItems})` | `search_all(q, limit=, max_items=)` | Iterator over every result | Free | | `card(id)` | `card(id)` | One card | Free | | `sets({language})` | `sets(language=)` | All sets | Free | | `set(code, {page, limit})` | `set(code, page=, limit=)` | One page of a set’s cards | Free | | `setCards(code, {limit, maxItems})` | `set_cards(code, limit=, max_items=)` | Iterator over a whole set | Free | | `imageUrl(id)` | `image_url(id)` | Image URL; fetch it with your key in the X-API-Key header | Free | | `prices(code)` | `prices(code)` | Prices of every card in a set, one row per finish, sealed products included | Pro | | `statistics(code, {variant})` | `statistics(code, variant=)` | Average, min, max, most expensive card, trend and rarity breakdown | Pro | | `completionValue(code)` | `completion_value(code)` | Cost of one copy of every card in its base finish | Pro | | `trending({limit})` | `trending(limit=)` | Sets with the biggest CardMarket price moves over 7 days | Pro | | `topCards({metric, source, limit})` | `top_cards(metric=, source=, limit=)` | Ranking by price or by 7-day growth | Pro | | `pokemon.priceHistory(id)` | `pokemon.price_history(id)` | Price at 7, 14, 30, 60 and 120 days | Pro · Pokémon | | `health()` | `health()` | Service status and a check per service | No key | | `listGames()` | `list_games()` | The ten games and their routes | No key | **Pro** means the Pro plan for Pokémon and One Piece, or the Ultra plan for the ten other games. Every account can start a 7-day free trial from the dashboard. Without access the SDK raises `PlanRequiredError` with the link to start the trial. [See plans](https://pokewallet.io/pricing) ## Errors, retries and limits Every failure is a typed error, all subclasses of `PokeWalletError`. | Error | When | Useful fields | | --- | --- | --- | | `ValidationError` | Bad arguments, or no API key; raised before any request | — | | `AuthError` | 401: key missing, malformed or unknown | — | | `PlanRequiredError` | 403: the plan or trial does not cover this endpoint | `redeemUrl, upgradeUrl` | | `FeatureNotEnabledError` | 403: the account does not have access to this feature | `contactUrl` | | `NotFoundError` | 404: unknown card or set | `didYouMean, suggestions` | | `GameUnavailableError` | 404 on a game route that is switched off | — | | `AmbiguousSetError` | A set code matches several sets | `matches` | | `RateLimitError` | 429: quota used up | `limits, retryAfter` | | `UnavailableError` | 503: service busy | `retryAfter` | | `NetworkError, ServerError` | No answer, or another 5xx | — | ### Retries Only a 429 with a `Retry-After` within 30 seconds, and a 503 up to 2 times. Nothing else is retried, and the SDK never guesses a wait. ### Quota After any call, `pw.lastRateLimit` (Python: `pw.last_rate_limit`) holds the hourly and daily limits and what is left. Error responses count against your quota too. ## Key safety - **Read it from the environment.** Never in code, git, issues or screenshots. Call the SDK from your server, so the key never reaches a browser. - **Masked everywhere.** The key shows as `pk_***` in logs, errors and serialization, and is removed from any server text that echoes it. - **Leaked a key?** Revoke it in the [dashboard](https://pokewallet.io/dashboard) and create a new one. It takes a few seconds. ## Frequently asked questions ### Is there an official SDK for the Pokémon TCG API? Yes. @pokewallet/sdk for TypeScript and pokewallet for Python are the official PokéWallet SDKs. They cover Pokémon, One Piece and ten more trading card games with one API key. ### Do I need a paid plan to use the SDKs? No. A free key can search cards and read cards and sets (100 requests per hour, 1,000 per day). Set prices, statistics, trending sets, top cards and price history need Pro, Ultra or the 7-day free trial. ### Can I use the TypeScript SDK in the browser? Use it on your server. The SDK needs your API key, and a key sent to a browser can be copied by anyone who opens the page. ### My language is not TypeScript or Python. What can I use? Call the REST API directly, or generate a client from the OpenAPI 3.1 specification at https://pokewallet.io/openapi.json. ### Are the SDKs open source? Yes, under the MIT license, on GitHub at pokewallet-lab/pokewallet-sdk. The data they return is covered by the PokéWallet Terms of Use. ## Prefer to ask your AI assistant? The PokéWallet MCP server gives Claude Code, Cursor and other clients the same data, with the same key. [Set up the MCP server](https://pokewallet.io/developers/mcp) --- Model Context Protocol · Hosted · Read-only # PokéWallet MCP server card prices in your AI assistant Source: https://pokewallet.io/developers/mcp Connect Claude Code, Cursor, VS Code, Gemini CLI and other MCP clients to PokéWallet. Your assistant searches cards and reads TCGPlayer and CardMarket prices for Pokémon, One Piece and ten more card games, with your own API key. Server URL `https://mcp.pokewallet.io/mcp` - Streamable HTTP - Authorization: Bearer pk_… - 10 read-only tools ## How it works 1. Your client **Claude Code, Cursor, VS Code…** Holds your key in its own config. 2. mcp.pokewallet.io **Keeps nothing** Forwards your key, stores and logs nothing. 3. api.pokewallet.io **Your plan, your quota** Each tool call uses one request. ## Connect your client Pick your client and paste the configuration. The key goes in the `Authorization` header; keep it in an environment variable where the client supports it. *Claude Code (bash)* ```bash claude mcp add --transport http pokewallet https://mcp.pokewallet.io/mcp \ --header "Authorization: Bearer $POKEWALLET_API_KEY" ``` *Cursor (json)* ```json { "mcpServers": { "pokewallet": { "url": "https://mcp.pokewallet.io/mcp", "headers": { "Authorization": "Bearer ${env:POKEWALLET_API_KEY}" } } } } ``` *VS Code (json)* ```json { "servers": { "pokewallet": { "type": "http", "url": "https://mcp.pokewallet.io/mcp", "headers": { "Authorization": "Bearer ${input:pokewallet-key}" } } }, "inputs": [ { "type": "promptString", "id": "pokewallet-key", "description": "PokeWallet API key", "password": true } ] } ``` *Gemini CLI (json)* ```json { "mcpServers": { "pokewallet": { "httpUrl": "https://mcp.pokewallet.io/mcp", "headers": { "Authorization": "Bearer $POKEWALLET_API_KEY" } } } } ``` *Claude Desktop (json)* ```json { "mcpServers": { "pokewallet": { "command": "npx", "args": ["-y", "mcp-remote", "https://mcp.pokewallet.io/mcp", "--header", "Authorization:${AUTH_HEADER}"], "env": { "AUTH_HEADER": "Bearer pk_live_xxx" } } } } ``` *Other clients* ``` URL https://mcp.pokewallet.io/mcp (Streamable HTTP) Header Authorization: Bearer ``` Claude CodeTerminal. Add --scope user to have the server in every project; /mcp inside Claude Code shows whether it is connected.Cursor~/.cursor/mcp.json, or .cursor/mcp.json in a project.VS Code.vscode/mcp.json in a project, or MCP: Open User Configuration. VS Code asks for the key on first start and stores it securely.Gemini CLI~/.gemini/settings.json, or .gemini/settings.json in a project.Claude Desktopclaude_desktop_config.json (Settings → Developer → Edit Config), through mcp-remote. Replace pk_live_xxx with your key, keep the file private and restart the app.Other clientsWindsurf, Cline, Zed or your own code with an MCP SDK: give the client the URL and the header. A client that only runs local servers can use the mcp-remote setup. The custom connectors of the claude.ai and ChatGPT web apps can’t send an API key header yet (they support OAuth or no authentication), so they can’t connect to this server for now. ## Tools 10 read-only tools. A `game` parameter picks `pokemon` (default), `onepiece` or one of the ten game codes. - `list_games`FreeThe ten games and their codes. - `search_cards`FreeCards matching a name, with prices. At most 10 results. - `get_card`FreeOne card with every finish and price. - `list_sets`FreeAll sets, filtered by name or language. - `get_set`FreeThe cards of a set. An ambiguous code returns the alternatives. - `get_price_history`ProPrice at 7, 14, 30, 60 and 120 days. Pokémon only. - `top_cards`ProRanking by price or by 7-day growth. - `trending_sets`ProSets with the biggest CardMarket price moves over the last 7 days. - `set_statistics`ProAverage, min, max, most expensive card and rarity breakdown of a set. - `set_completion_value`ProCost of one copy of every card in a set. Pro tools need the Pro plan for Pokémon and One Piece, the Ultra plan for the ten other games, or the 7-day free trial. [See plans](https://pokewallet.io/pricing) ## Try asking - Find Charizard ex cards and their CardMarket trend price - Which One Piece sets moved most this week? - What does it cost to complete Phantasmal Flames? - Top 10 Magic cards by TCGPlayer price ## Your key stays yours - **Nothing stored.** The server is stateless: your key travels in the request header to the PokéWallet API and is never saved or logged. - **Read-only.** No tool changes your account, your keys or your plan. It only reads cards, sets and prices. - **Open source.** The code is on [GitHub](https://github.com/pokewallet-lab/pokewallet-sdk), and you can run it on your own machine. ``` gh repo clone pokewallet-lab/pokewallet-sdk && cd pokewallet-sdk (cd packages/ts && npm install && npm run build) cd packages/mcp && npm install && npx wrangler dev ``` ## Frequently asked questions ### What is the PokéWallet MCP server? A hosted server for the Model Context Protocol that lets AI assistants such as Claude Code and Cursor search trading cards and read their prices through the PokéWallet API, using your own key. ### Does it cost anything extra? No. It uses your PokéWallet plan: each tool call is one request of your quota. A free key covers search, cards and sets. ### Which clients can connect? Any client that speaks Streamable HTTP and can send a header: Claude Code, Cursor, VS Code, Gemini CLI, Windsurf, Cline, Zed and your own code. Claude Desktop connects through mcp-remote. ### Can I use it in claude.ai or ChatGPT? Not yet. Their web connectors support OAuth or no authentication, and this server needs your API key in a header. ### Is my API key safe? The server forwards your key to the PokéWallet API on each request and keeps nothing: no storage, no logs. If a key leaks, revoke it in the dashboard and create a new one. ## Building an app instead? The TypeScript and Python SDKs give your code the same data, with typed results and errors. [See the SDKs](https://pokewallet.io/developers/sdk)