Discover/Card Kingdom API
live

Card Kingdom APIcardkingdom.com

Access Magic: The Gathering card prices, buylist rates, edition catalogs, and deals from Card Kingdom via 6 structured API endpoints.

Endpoints
6
Updated
2mo ago

What is the Card Kingdom API?

The Card Kingdom API provides structured access to Magic: The Gathering card data across 6 endpoints, covering retail prices, buylist rates, edition listings, and current deals. The search_cards endpoint lets you query cards by name, format, or edition and returns per-condition pricing and availability. Additional endpoints expose full card details, sell-to-store buylist prices in both cash and store credit, and a complete catalog of MTG sets.

Try it
Page number for pagination
Search keyword for card name (e.g. 'Lightning Bolt')
Filter by tournament format: Commander, Legacy, Modern, Pauper, Vintage, Pioneer, Brawl, Standard, Premodern
Filter by card set/edition name
api.parse.bot/scraper/57fad8b8-9bec-4fbf-9dfd-c5d328040d29/<endpoint>
Ready to send
Fill in the parameters and hit sign in to send to see live response data here.
Call it over HTTPgrab a free API key at signup
curl -X GET 'https://api.parse.bot/scraper/57fad8b8-9bec-4fbf-9dfd-c5d328040d29/search_cards?query=Lightning+Bolt' \
  -H 'X-API-Key: $PARSE_API_KEY'
Python SDK · recommended

Typed, relational, agent-ready

A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.

  • Fully typed · autocompletes
  • Objects link to objects
  • Typed errors & pagination

Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:

uv add parse-sdk
uv run parse init
uv run parse add --marketplace cardkingdom-com-api

uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.

"""
Card Kingdom MTG API Client
Comprehensive API for extracting Magic: The Gathering card data, pricing, and availability.
Get your API key from: https://parse.bot/settings
"""

import os
import requests
from typing import Optional, Dict, Any, List


class ParseClient:
    """Client for the Card Kingdom MTG API via Parse.bot"""

    def __init__(self, api_key: Optional[str] = None):
        """Initialize the Parse API client.
        
        Args:
            api_key: API key for Parse.bot. Falls back to PARSE_API_KEY env var.
        """
        self.base_url = "https://api.parse.bot"
        self.scraper_id = "57fad8b8-9bec-4fbf-9dfd-c5d328040d29"
        self.api_key = api_key or os.getenv("PARSE_API_KEY")
        
        if not self.api_key:
            raise ValueError("API key not provided and PARSE_API_KEY not set")

    def _call(self, endpoint: str, method: str = "POST", **params) -> Dict[str, Any]:
        """Make an API call to the Parse endpoint.
        
        Args:
            endpoint: The endpoint name (e.g., "search_cards")
            method: HTTP method (GET or POST)
            **params: Query/body parameters for the request
            
        Returns:
            Response JSON as dictionary
            
        Raises:
            requests.exceptions.RequestException: If the request fails
        """
        url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
        headers = {
            "X-API-Key": self.api_key,
            "Content-Type": "application/json"
        }
        
        if method.upper() == "GET":
            response = requests.get(url, headers=headers, params=params)
        else:  # POST
            response = requests.post(url, headers=headers, json=params)
        
        response.raise_for_status()
        return response.json()

    def search_cards(
        self,
        query: Optional[str] = None,
        edition: Optional[str] = None,
        format: Optional[str] = None,
        page: int = 1
    ) -> Dict[str, Any]:
        """Search for Magic: The Gathering cards by name, edition, and format.
        
        Args:
            query: Card name search keyword
            edition: Filter by card set/edition name
            format: Filter by tournament format (e.g., Standard, Commander, Legacy)
            page: Page number for pagination (default: 1)
            
        Returns:
            Dictionary with page info and list of card items
        """
        params = {"page": page}
        if query:
            params["query"] = query
        if edition:
            params["edition"] = edition
        if format:
            params["format"] = format
        
        return self._call("search_cards", method="GET", **params)

    def get_card_detail(self, url: str) -> Dict[str, Any]:
        """Get full details for a specific card listing.
        
        Args:
            url: The URL or path of the card detail page (e.g., /mtg/stronghold/mox-diamond)
            
        Returns:
            Dictionary with card details including name, oracle text, and conditions
        """
        return self._call("get_card_detail", method="GET", url=url)

    def get_buylist_prices(
        self,
        query: Optional[str] = None,
        edition: Optional[str] = None,
        page: int = 1
    ) -> Dict[str, Any]:
        """Retrieve buylist (sell-to-CK) prices for cards.
        
        Args:
            query: Card name search keyword
            edition: Filter by set name
            page: Page number (default: 1)
            
        Returns:
            Dictionary with page info and list of cards with buylist prices
        """
        params = {"page": page}
        if query:
            params["query"] = query
        if edition:
            params["edition"] = edition
        
        return self._call("get_buylist_prices", method="GET", **params)

    def list_all_editions(self) -> Dict[str, List[Dict[str, str]]]:
        """List all available MTG editions/sets.
        
        Returns:
            Dictionary with list of editions containing name, slug, and url
        """
        return self._call("list_all_editions", method="GET")

    def get_deals(self, page: int = 1) -> Dict[str, Any]:
        """Get current discounted deals and on-sale products.
        
        Args:
            page: Page number (default: 1)
            
        Returns:
            Dictionary with page info and list of discounted items
        """
        return self._call("get_deals", method="GET", page=page)

    def get_formats(self) -> Dict[str, Dict[str, Any]]:
        """Get a list of all game formats and their IDs.
        
        Returns:
            Dictionary of format objects keyed by index with name, slug, and id
        """
        return self._call("get_formats", method="GET")


def find_best_deal_across_conditions(card_details: Dict[str, Any]) -> Dict[str, Any]:
    """Find the cheapest available condition for a card.
    
    Args:
        card_details: Card details from get_card_detail
        
    Returns:
        Dictionary with best condition, price, and availability
    """
    conditions = card_details.get("conditions", [])
    if not conditions:
        return {}
    
    # Find cheapest available condition
    best = None
    for cond in conditions:
        if int(cond.get("available", 0)) > 0:
            price_str = cond.get("price", "$0").replace("$", "")
            if best is None or float(price_str) < float(best["price"].replace("$", "")):
                best = cond
    
    return best or {}


def calculate_arbitrage_opportunity(retail_price: str, buylist_credit: str) -> float:
    """Calculate profit margin from buying at retail and selling to buylist.
    
    Args:
        retail_price: Card retail price as string (e.g., "$100.00")
        buylist_credit: Buylist credit price as string (e.g., "$120.00")
        
    Returns:
        Profit margin percentage
    """
    try:
        retail = float(retail_price.replace("$", ""))
        buylist = float(buylist_credit.replace("$", ""))
        if retail == 0:
            return 0
        return ((buylist - retail) / retail) * 100
    except (ValueError, AttributeError):
        return 0


if __name__ == "__main__":
    # Initialize client
    client = ParseClient()
    
    print("=" * 70)
    print("Card Kingdom MTG API - Practical Workflow Example")
    print("=" * 70)
    
    # Step 1: Get all available formats to understand the market
    print("\n[1] Fetching available game formats...")
    formats_data = client.get_formats()
    formats = formats_data.get("data", {})
    print(f"Found {len(formats)} formats:")
    for fmt_key, fmt in list(formats.items())[:5]:
        print(f"  - {fmt['name']} (slug: {fmt['slug']})")
    
    # Step 2: Search for a valuable card (high-value targets)
    print("\n[2] Searching for 'Mox' cards in inventory...")
    search_result = client.search_cards(query="Mox", page=1)
    cards = search_result.get("data", {}).get("items", [])
    print(f"Found {len(cards)} Mox cards available:")
    
    # Step 3: Analyze each card found - get details and check pricing
    print("\n[3] Analyzing card details and pricing...")
    analyzed_cards = []
    
    for i, card in enumerate(cards[:5], 1):  # Analyze first 5 results
        card_name = card.get("name", "Unknown")
        card_edition = card.get("edition", "Unknown")
        card_url = card.get("url", "")
        
        print(f"\n  Card {i}: {card_name} ({card_edition})")
        
        if card_url:
            try:
                # Get detailed pricing information
                details = client.get_card_detail(url=card_url)
                conditions = details.get("data", {}).get("conditions", [])
                
                # Find best deal
                best_deal = find_best_deal_across_conditions(details.get("data", {}))
                
                if best_deal:
                    condition = best_deal.get("condition", "N/A")
                    price = best_deal.get("price", "N/A")
                    available = best_deal.get("available", "0")
                    
                    print(f"    Best price: {price} ({condition}) - {available} available")
                    
                    analyzed_cards.append({
                        "name": card_name,
                        "edition": card_edition,
                        "url": card_url,
                        "best_price": price,
                        "condition": condition,
                        "available": available
                    })
                else:
                    print(f"    No stock available at any condition")
                    
            except Exception as e:
                print(f"    Error fetching details: {str(e)}")
    
    # Step 4: Check buylist prices for cards we analyzed
    print("\n[4] Checking buylist prices for 'Mox' cards...")
    buylist_result = client.get_buylist_prices(query="Mox", page=1)
    buylist_items = buylist_result.get("data", {}).get("items", [])
    print(f"Found {len(buylist_items)} cards in buylist (showing first 5):")
    
    for item in buylist_items[:5]:
        name = item.get("name", "Unknown")
        edition = item.get("edition", "Unknown")
        prices = item.get("buylist_prices", {})
        cash_price = prices.get("cash", "N/A")
        credit_price = prices.get("credit", "N/A")
        max_qty = prices.get("max_quantity", "0")
        
        print(f"\n  {name} ({edition})")
        print(f"    Cash: {cash_price} | Store Credit: {credit_price} (Max qty: {max_qty})")
        
        # Check for arbitrage opportunities from our analyzed cards
        for analyzed in analyzed_cards:
            if analyzed["name"].lower() == name.lower():
                margin = calculate_arbitrage_opportunity(analyzed["best_price"], credit_price)
                print(f"    → Arbitrage margin (retail to credit): {margin:.1f}%")
    
    # Step 5: Check current deals to find bargains
    print("\n[5] Checking current deals and discounts...")
    deals_result = client.get_deals(page=1)
    deals = deals_result.get("data", {}).get("items", [])
    print(f"Found {len(deals)} items on sale (showing first 5):")
    
    for deal in deals[:5]:
        name = deal.get("name", "Unknown")
        original = deal.get("original_price", "0")
        sale = deal.get("sale_price", "0")
        
        try:
            original_float = float(original.replace("$", ""))
            sale_float = float(sale.replace("$", ""))
            savings = original_float - sale_float
            discount_pct = (savings / original_float) * 100
            
            print(f"\n  {name}")
            print(f"    ${original} → ${sale} (Save ${savings:.2f}, {discount_pct:.1f}% off)")
        except (ValueError, AttributeError):
            print(f"\n  {name}: {original} → {sale}")
    
    # Step 6: List sample editions for reference
    print("\n[6] Sample of available editions for filtering...")
    editions_data = client.list_all_editions()
    editions = editions_data.get("data", {}).get("editions", [])
    print(f"Total editions in catalog: {len(editions)}")
    print("Sample editions (first 6):")
    
    for edition in editions[:6]:
        print(f"  - {edition['name']} ({edition['slug']})")
    
    # Step 7: Summary and insights
    print("\n" + "=" * 70)
    print("WORKFLOW SUMMARY")
    print("=" * 70)
    print(f"✓ Analyzed {len(analyzed_cards)} specific card listings")
    print(f"✓ Reviewed {len(buylist_items)} buylist opportunities")
    print(f"✓ Found {len(deals)} current deals")
    print(f"✓ Indexed {len(editions)} available editions")
    
    if analyzed_cards:
        print(f"\nTop opportunities to track:")
        for card in analyzed_cards[:3]:
            print(f"  • {card['name']} ({card['edition']}): {card['best_price']}")
    
    print("\nWorkflow complete! Ready to use for real-time MTG market analysis.")
    print("=" * 70)
All endpoints · 6 totalmissing one? ·

Search for Magic: The Gathering cards by name, edition, and format. Returns paginated results with pricing and condition availability.

Input
ParamTypeDescription
pageintegerPage number for pagination
querystringSearch keyword for card name (e.g. 'Lightning Bolt')
formatstringFilter by tournament format: Commander, Legacy, Modern, Pauper, Vintage, Pioneer, Brawl, Standard, Premodern
editionstringFilter by card set/edition name
Response
{
  "type": "object",
  "fields": {
    "page": "integer, current page number",
    "items": "array of card objects with name, url, edition, rarity, type, oracle_text, and conditions (price/availability per condition)",
    "per_page": "integer, results per page"
  },
  "sample": {
    "data": {
      "page": 1,
      "items": [
        {
          "url": "https://www.cardkingdom.com/mtg/beta/lightning-bolt",
          "name": "Lightning Bolt",
          "type": "Instant",
          "rarity": "C",
          "edition": "Beta",
          "conditions": [
            {
              "price": "$449.99",
              "available": "0",
              "condition": "NM"
            },
            {
              "price": "$359.99",
              "available": "3",
              "condition": "EX"
            }
          ],
          "oracle_text": "Lightning Bolt deals 3 damage to any target.",
          "collector_number": "162"
        }
      ],
      "per_page": 100
    },
    "status": "success"
  }
}

About the Card Kingdom API

Card Search and Detail

The search_cards endpoint accepts a query string for card name lookup, an edition filter for set-specific results, and a format filter supporting nine tournament formats including Commander, Modern, Legacy, Pioneer, and Standard. Results are paginated via the page parameter and each item includes the card's name, edition, rarity, type, oracle_text, and a conditions array containing price and availability per grading condition. For deeper data, get_card_detail takes a card url path and returns the full conditions list with quantities, the card's oracle text, and an other_versions array linking to alternate printings of the same card.

Buylist and Deals

The get_buylist_prices endpoint returns what Card Kingdom will pay for cards — each item in the response includes buylist_prices with distinct cash, credit, and max_quantity fields. You can filter by query or edition and paginate results. The get_deals endpoint surfaces currently discounted products with original_price, sale_price, and a direct url to the listing, making it straightforward to track markdown events across the catalog.

Editions and Formats Reference

list_all_editions returns the full MTG set catalog as an array of objects with name, slug, and url — useful for building edition pickers or validating set names before passing them to search_cards or get_buylist_prices. get_formats returns a keyed object of all supported game formats with each format's id, name, slug, and is_active status, giving you the canonical format identifiers Card Kingdom recognizes.

Reliability & maintenance

The Card Kingdom API is a managed, monitored endpoint for cardkingdom.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when cardkingdom.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.

This isn't an official cardkingdom.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.

Will this API break when the source site changes?+
It's built not to. Every endpoint is health-checked on a schedule with automated test probes. When the source site changes and a check fails, the API is automatically queued for repair and re-verified — that's the self-healing layer. Each API page shows when its endpoints were last verified. And because marketplace APIs are shared, any fix reaches everyone using it.
Is this an official API from the source site?+
No — Parse APIs are independent, managed REST wrappers over publicly available data. That is the point: where a site has no official API (or only a limited one), Parse gives you a maintained, monitored endpoint for that data and keeps it working as the site changes — so you get a stable contract over a source that never promised one.
Can I fix or extend this API myself if I need a new endpoint or field?+
Yes — and you don't have to wait on us. This API was generated by the Parse agent, which stays attached. Describe the change in plain English ("add an endpoint that returns reviews", "fix the price field") in the revise box on the API page or via the revise_api MCP tool, and the agent rebuilds it against the live site in minutes. Contributing the change back to the public API is free.
What happens if I call an endpoint that has an issue?+
Errors are machine-readable: a bad call returns a clean status with the list of available endpoints and a repair hint, so an agent (or you) can recover or trigger a fix instead of failing silently. Confirmed failures feed the automatic repair queue.
Common use cases
  • Compare retail prices across card conditions to find the lowest-cost copy of a specific printing
  • Track buylist cash vs. store credit rates to identify the best time to sell cards back
  • Monitor the deals feed for price drops on specific cards or products
  • Build a format-legality price checker using the format filter in search_cards
  • Generate a full set inventory by iterating search_cards with an edition parameter from list_all_editions
  • Alert on buylist max_quantity limits to detect when Card Kingdom stops buying a given card
  • Cross-reference other_versions from get_card_detail to find cheaper alternate printings of a card
Pricing & limitsSee full pricing →
TierPriceCredits/monthRate limit
Free$0/mo1005 req/min
Hobby$30/mo1,00020 req/min
Developer$100/mo5,000100 req/min

One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.

Frequently asked questions
Does Card Kingdom have an official developer API?+
Card Kingdom does not publish a public developer API. There is no documented REST or GraphQL interface available to third-party developers on their site.
What does the buylist endpoint actually return — and how does it differ from retail pricing?+
The get_buylist_prices endpoint returns what Card Kingdom will pay when you sell cards to them, not what they charge buyers. Each item includes a buylist_prices object with separate cash and credit values and a max_quantity field indicating how many copies they are currently buying. Retail sell prices come from search_cards or get_card_detail via the conditions array.
Does the API cover foil or special-treatment card variants separately?+
The conditions arrays in search_cards and get_card_detail reflect the condition grades and quantities Card Kingdom lists. Foil and non-foil versions of a card typically appear as separate listings, accessible via get_card_detail with the relevant url or through the other_versions field. Explicit foil flags are not a dedicated response field currently. You can fork the API on Parse and revise it to add a foil-specific filter or field if that distinction matters to your use case.
Is historical price data available through any of the endpoints?+
Not currently. All six endpoints return current pricing as it stands — there are no date-range parameters or historical price arrays in any response. You can fork the API on Parse and revise it to add a scheduled polling layer that records snapshots over time.
How does pagination work across endpoints that support it?+
search_cards, get_buylist_prices, and get_deals all accept an integer page parameter. Each response includes the current page number and a per_page count so you can calculate total pages from the result set size. list_all_editions and get_formats return their full datasets in a single response with no pagination.
Page content last updated . Spec covers 6 endpoints from cardkingdom.com.
Related APIs in EcommerceSee all →
cardmarket.com API
Search and browse trading cards across Europe's largest marketplace, accessing detailed card information, listings, seller profiles, and finding the best bargains all in one place. Explore games and expansions to discover available singles and compare prices from multiple sellers.
tcgplayer.com API
Search for trading cards across all games and sets on TCGPlayer, and instantly access detailed pricing information by condition plus current seller listings with prices, shipping costs, and seller ratings. Compare card values and find the best deals from multiple sellers all in one place.
moxfield.com API
Search and retrieve Magic: The Gathering card data from Moxfield, including high-resolution card images, pricing, legalities, edition details, and metadata. Supports card name lookups, Scryfall syntax queries, and browsing curated card lists for deck building and collection management.
mtggoldfish.com API
Access Magic: The Gathering metagame data from MTGGoldfish, including popular deck archetypes with popularity metrics, mana composition, and complete card lists. Retrieve metagame breakdowns by format and look up full deck lists by archetype or deck ID.
snkrdunk.com API
Access data from snkrdunk.com.
pkmncards.com API
Search and browse Pokémon trading card game cards with detailed metadata, high-quality images, and advanced filtering by set, Pokémon name, or card type. Filter across thousands of cards from different sets to find exactly what you're looking for.
bazaardb.gg API
Search and retrieve comprehensive data about The Bazaar game cards, including items, skills, merchants, trainers, monsters, and events with full details like tiers, attributes, enchantments, and tooltips. Quickly find the specific card information you need to optimize your gameplay strategy and deck building.
giftcards.com API
Search for gift cards across brands and categories, and retrieve discounted cards with their promotion rules and current discount rates. Compare gift card prices programmatically to find the best available savings.