API Documentation

Learn how to integrate the JustTCG API into your applications.

API Version:

Overview

The JustTCG API provides real-time pricing data for trading card games including Magic: The Gathering, Pokémon, Yu-Gi-Oh!, Disney Lorcana, One Piece TCG, Digimon, and Union Arena. Our API is designed to be simple, fast, and reliable.

Base URL

https://api.justtcg.com/v1

Authentication

All API requests require authentication using an API key. You can obtain an API key by signing up for an account and subscribing to a plan.

API Key Authentication

Include your API key in the request headers:

x-api-key:tcg_your_api_key_here
Keep your API key secure and never expose it in client-side code.
If you suspect your API key has been compromised, regenerate it immediately.

API Reference

Our API is focused on three main endpoints for a more intuitive and seamless experience:

  • Games and Sets: For discovering available games and sets.
  • Cards: For searching and direct lookups. If you pass an id, you get a direct lookup. If you do not pass an id, the endpoint serves as a flexible search.

Collection Resources

These endpoints provide information about the available trading card games and sets in our database. Start with these endpoints to understand what's available before diving into the cards endpoint.

Games

GET

Retrieve a list of all games.

https://api.justtcg.com/v1/games

Response Object

Name
Type
Description
id
string
Unique identifier for the game
name
string
Name of the game
game_id
string
ID of the game
cards_count
integer
Number of cards in the game
sets_count
integer
Number of sets in the game

Sets

GET

Retrieve a list of all sets.

https://api.justtcg.com/v1/sets

Query Parameters

Name
Type
Required
Default
Description
game
string
Required

Filter by game ID (e.g., mtg, pokemon).

Response Object

Name
Type
Description
id
string
Unique identifier for the set
name
string
Name of the set
game_id
string
ID of the game this set belongs to
game
string
Name of the game this set belongs to
cards_count
integer
Number of cards in the set

Cards

This high-performance endpoint provides rapid access to card data whether you already have identifier values or not. For the best performance when retrieving specific cards, use this endpoint with IDs obtained from the games or sets endpoints.

Quick tip: Use "Card ID" for retrieving all variants of a single card. Use "Variant ID" when you need specific variant information for ultra-fast performance.
Notice (07/2025): Some Card IDs and Variant IDs have recently changed for standardization. See the Card IDs section for details.

Card Lookup

GET

Retrieve a card and its variant prices by ID or search query. You can optionally filter the returned variants by condition and printing type.

https://api.justtcg.com/v1/cards

Note: The tcgplayerId, cardId or variantId will take precedence over any search query if any of those are provided.

Query Parameters

Name
Type
Required
Default
Description
tcgplayerId
string
Required

TCGplayer ID of the card.

printing
string
Optional

Filter by printing type (e.g., Normal, Foil).

condition
string
Optional

Filter by condition:

  • Sealed
  • Near Mint
  • Lightly Played
  • Moderately Played
  • Heavily Played
  • Damaged

Or abbreviations:

  • S
  • NM
  • LP
  • MP
  • HP
  • DMG

You can specify a single value (e.g., NM) or a comma-separated list (e.g., NM,LP,HP) to filter for multiple conditions.

Response Object

Name
Type
Description
data
Card[]
Array of card objects. Please see below for detailed information about the Card object.

Batch Card Lookup

POST

Retrieve multiple cards and their variants in a single request. For each card, you can optionally filter variants by specifying condition and printing parameters.

https://api.justtcg.com/v1/cards

Request Body Parameters

Send an array of objects, each containing the following properties:

Name
Type
Required
Default
Description
tcgplayerId
string
Required

TCGplayer ID of the card.

printing
string
Optional

Filter by printing type (e.g., Normal, Foil).

condition
string
Optional

Filter by condition:

  • Sealed
  • Near Mint
  • Lightly Played
  • Moderately Played
  • Heavily Played
  • Damaged

Or abbreviations:

  • S
  • NM
  • LP
  • MP
  • HP
  • DMG

You can specify a single value (e.g., NM) or a comma-separated list (e.g., NM,LP,HP) to filter for multiple conditions.

Note: The maximum number of items supported in a single request is 100 for paid plans and 20 for the free plan. For larger queries, please consider batching your requests.

Response Object

Name
Type
Description
data
Card[]
Array of card objects. Please see below for detailed information about the Card object.

Card Object

The Card object contains detailed information about a trading card, including its variants with pricing information.

Property
Type
Description
id
string
Unique identifier for the card. Frequently referred to as "cardId"
name
string
Name of the card
game
string
Name of the game the card belongs to (e.g., "Pokemon", "Magic: The Gathering")
set
string
Name of the set the card belongs to
number
string
Card number within the set
tcgplayerId
string
TCGplayer product ID
rarity
string
Rarity of the card (e.g., "Common", "Rare", "Promo")
details
string | null
Additional card-specific details (when applicable)
variants
Variant[]
Array of variant objects with pricing information
Cards don't directly contain pricing information. Instead, pricing is stored in variant objects within the "variants" array.

Variant Object

Each variant represents a specific combination of condition and printing for a card, with its associated price.

Property
Type
Description
id
string
Unique identifier for this specific variant. Frequently referred to as 'variantId'
condition
string
Condition of the card (e.g., "Near Mint", "Lightly Played")
printing
string
Printing type (e.g., "Normal", "Foil")
language
string
Language of the card (e.g., "English", "Japanese")
price
number
Current price in USD
lastUpdated
number
Unix timestamp (in seconds) of when the price was last updated
priceChange24hr
number
Percentage price change in the last 24 hours
priceChange7d
number
Percentage price change in the last 7 days
avgPrice
number
Average price over the default time period
priceHistory
array
Array of historical price points, each containing price (p) and timestamp (t) in seconds
minPrice7d
number
Minimum price in the last 7 days
maxPrice7d
number
Maximum price in the last 7 days
stddevPopPrice7d
number
Population standard deviation of prices over 7 days
covPrice7d
number
Coefficient of variation for prices over 7 days
iqrPrice7d
number
Interquartile range of prices over 7 days
trendSlope7d
number
Price trend slope over 7 days
priceChangesCount7d
number
Number of price changes in the last 7 days
priceChange30d
number
Percentage price change in the last 30 days
avgPrice30d
number
Average price over 30 days
minPrice30d
number
Minimum price in the last 30 days
maxPrice30d
number
Maximum price in the last 30 days
priceHistory30d
array
Array of historical price points over 30 days
stddevPopPrice30d
number
Population standard deviation of prices over 30 days
covPrice30d
number
Coefficient of variation for prices over 30 days
iqrPrice30d
number
Interquartile range of prices over 30 days
trendSlope30d
number
Price trend slope over 30 days
priceChangesCount30d
number
Number of price changes in the last 30 days
priceRelativeTo30dRange
number
Current price position relative to 30-day price range (0-1)
minPrice90d
number
Minimum price in the last 90 days
maxPrice90d
number
Maximum price in the last 90 days
minPrice1y
number
Minimum price in the last year
maxPrice1y
number
Maximum price in the last year
minPriceAllTime
number
All-time minimum price
minPriceAllTimeDate
string
ISO 8601 date when the all-time minimum price occurred
maxPriceAllTime
number
All-time maximum price

Example Card Object

{
  "id": "pokemon-battle-academy-fire-energy-22-charizard-stamped",
  "name": "Fire Energy (#22 Charizard Stamped)",
  "game": "Pokemon",
  "set": "Battle Academy",
  "number": "N/A",
  "tcgplayerId": "219042",
  "rarity": "Promo",
  "details": null,
  "variants": [
    {
      "id": "pokemon-battle-academy-fire-energy-22-charizard-stamped_near-mint",
      "printing": "Normal",
      "condition": "Near Mint",
      "price": 4.99,
      "lastUpdated": 1743100261
    },
    {
      "id": "pokemon-battle-academy-fire-energy-22-charizard-stamped_lightly-played",
      "printing": "Normal",
      "condition": "Lightly Played",
      "price": 3.50,
      "lastUpdated": 1743101175
    }
  ]
}

Card IDs

Each card object has a unique id, sometimes referred to as the cardId or "Card ID".

The card ID is structured as game-set-name-rarity. This ID can be used for direct lookups using the /cards endpoint.

Note: Multiple variants of the same card ID may exist, each with its own unique variant ID. The card ID is not guaranteed to be unique across all variants.

Important ID Changes Notice

As of July 11, 2025, card IDs have been standardized for better consistency and to accurately support cards with multiple rarities. This is a breaking change.

  • All cards now include the full game name and rarity in the card ID
    • Magic: The Gathering example:
      • "magic-secret-lair-drop-series-food-chain" → "magic-the-gathering-secret-lair-drop-series-food-chain-mythic"
    • Disney Lorcana example:
      • "disney-lorcana" instead of "lorcana-tcg"
  • A small number of card IDs across all games that previously contained invalid characters (such as triple dashes, periods, or commas). These IDs are now fully standardized and consistent.
    • For example, "yugioh-force-of-the-breaker-lich-lord,-king-of-the-underworld" → "yugioh-force-of-the-breaker-lich-lord-king-of-the-underworld-secret-rare"

Migration Path

The simplest and recommended method to update your records is to re-fetch the cards you need via the API. This guarantees you have the latest, correct IDs.

However, if re-fetching is too cumbersome for your implementation, you can programmatically update your existing IDs. The new format is typically the old ID with the 'slugified' rarity appended (e.g., `-super-rare`). Sealed products do not have a rarity suffix. While this manual approach is possible, re-fetching remains the most reliable path.

If you store card IDs locally, please update them to ensure seamless integration.

Variant IDs

Each variant has a unique id, sometimes referred to as variantId or "Variant ID".

The variant ID is structured as cardId_condition_printing and can be used for direct, high-performance lookups using the /cards endpoint.

If you already have the variant ID, using it directly is the fastest way to retrieve pricing information.

Important: Variant ID Changes

Due to the card ID standardization in July 2025, variant IDs have also changed, as variant IDs are based on card IDs. Please update your stored variant IDs accordingly.

Filtering Variants

When retrieving cards, you can filter the variants by adding optional printing and condition parameters to your requests. This helps reduce response size and narrow down results to specific variants you're interested in.

Consistency Note

All endpoints that return card data use this same structure. Every card will have at least one variant in its variants array.

Response Format

All API responses follow a consistent format with a data field containing the requested information, a meta field with pagination details (when applicable), and a _metadata field with API usage statistics.

Response Structure

Field
Type
Description
data
array | null
The requested data. An array of card objects.
meta
object | null
Metadata about the pagination details, if available.
meta.total
integer
Total number of cards available for this query.
meta.limit
integer
Total results to limit this query to.
meta.offset
integer
The current offset for these results.
meta.hasMore
boolean
Indicates if there are more pages available for this query.
_metadata
object
API usage metadata and rate limit information included with each response.
_metadata.apiPlan
string
The name of your current API subscription plan.
_metadata.apiRequestLimit
integer
Total number of API requests allowed for your plan.
_metadata.apiRequestsUsed
integer
Number of API requests you have used so far.
_metadata.apiRequestsRemaining
integer
Number of API requests remaining before you reach your total limit.
_metadata.apiDailyLimit
integer
Maximum number of API requests allowed per day.
_metadata.apiDailyRequestsUsed
integer
Number of API requests used today.
_metadata.apiDailyRequestsRemaining
integer
Number of API requests remaining for today.
_metadata.apiRateLimit
integer
Maximum number of requests allowed per minute.
error
string | null
Detailed error message if an error occurred, otherwise null.
code
string | null
Error code indicating the type of error, if applicable.

Error Handling

The JustTCG API uses standard HTTP status codes and returns consistent error response formats to help you quickly identify and resolve issues.

HTTP Status Codes

Status Code
Error Type
Description
400
Bad Request
The request was malformed or missing required parameters.
401
Unauthorized
Missing or invalid API key.
403
Forbidden
Valid API key, but insufficient permissions for the requested resource.
404
Not Found
The requested resource could not be found.
429
Too Many Requests
Rate limit exceeded. Slow down your requests.
500
Server Error
An unexpected error occurred on the server.

Error Response Format

All error responses follow a consistent format with an error object containing details about the error.

{
    "error": "Invalid game parameter. Must be one of: magic-the-gathering, mtg, pokemon, yugioh, age-of-sigmar, warhammer-40000, union-arena, flesh-and-blood-tcg, disney-lorcana, digimon-card-game, one-piece-card-game",
    "code": "INVALID_REQUEST"
}

Common Error Codes

Error Code
Description
MISSING_API_KEY
The API key is missing from the request.
INVALID_API_KEY
The API key provided is invalid or has been revoked.
INVALID_REQUEST
A required parameter is missing or invalid from the request. Check the error message for more details.
RATE_LIMIT_EXCEEDED
You have exceeded your minute-by-minute rate limit. Please slow down your requests or upgrade your plan.
DAILY_LIMIT_EXCEEDED
You have exceeded your daily API usage limit. Please wait until the limit resets or upgrade your plan. Daily resets are at midnight UTC.
REQUEST_LIMIT_EXCEEDED
You have exceeded your monthly API usage limit. Please wait until your billing cycle resets or upgrade your plan.
Pro tip: We recommend implementing error handling that gracefully retries requests in case of temporary server errors (500 status codes) or rate limiting (429 status codes), with exponential backoff for best results.

Code Examples

Practical examples showing how to integrate the JustTCG API in real-world scenarios.

Price Sync for Inventory
Automatically fetch and update prices for all cards in a specific set
// Set your API key
const API_KEY = 'your_api_key_here';
const BASE_URL = 'https://api.justtcg.com/v1';

// Fetch all cards from a set (automatically handles pagination)
async function updatePricesForSet(gameId, setId) {
    console.log(`Updating prices for ${gameId} set: ${setId}...`);

    let allCards = [];
    let hasMoreResults = true;
    let offset = 0;
    const LIMIT = 20;

    // Keep fetching until we've got all cards
    while (hasMoreResults) {
        try {
            // Create URL with query parameters
            const url = new URL(`${BASE_URL}/cards`);
            url.searchParams.append('game', gameId);
            url.searchParams.append('set', setId);
            url.searchParams.append('limit', LIMIT);
            url.searchParams.append('offset', offset);

            // Make the API request
            const response = await fetch(url, {
                headers: { 'X-API-Key': API_KEY }
            });

            const result = await response.json();

            if (!response.ok) {
                throw new Error(result.error?.message || 'API request failed');
            }

            const cards = result.data;
            console.log(`Fetched ${cards.length} cards (offset: ${offset})`);

            // Add cards to our collection
            allCards = [...allCards, ...cards];

            // Check if we've reached the end
            hasMoreResults = cards.length === LIMIT;
            offset += LIMIT;

            // For demo purposes, just log first card's variants
            if (offset === LIMIT && cards.length > 0) {
                console.log('Sample card variation prices:');
                cards[0].variants.forEach(v => {
                    console.log(`- ${v.condition} / ${v.printing}: $${v.price}`);
                });
            }
        } catch (error) {
            console.error('Error fetching cards:', error);
            break;
        }
    }
    console.log(`✅ Updated prices for ${allCards.length} cards`);
    return allCards;
}

// Example usage
updatePricesForSet('magic-the-gathering', 'Modern Horizons 2');
Product Page Display
Fetch card data for a product page using batch lookup for better performance
// Set your API key
const API_KEY = 'your_api_key_here';
const BASE_URL = 'https://api.justtcg.com/v1';

// Display a product page with multiple cards
async function fetchProductPageCards(cardIds) {
  console.log('Fetching data for product display...');
  
  try {
    // Batch card lookup for efficiency
    const response = await fetch(`${BASE_URL}/cards`, {
      method: 'POST',
      headers: {
        'X-API-Key': API_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(cardIds.map(id => ({ tcgplayerId: id })))
    });
    
    const result = await response.json();
    
    if (!response.ok) {
      throw new Error(result.error?.message || 'Failed to fetch cards');
    }
    
    // Display the cards (in a real app, you'd render these to the DOM)
    console.log(`Displaying ${result.data.length} cards:`);
    
    result.data.forEach(card => {
      console.log(`${card.name} - ${card.set}`);
      
      // Get the lowest price for display
      const lowestPrice = Math.min(
        ...card.variants.map(v => v.price)
      );
      
      console.log(`  Starting from: $${lowestPrice.toFixed(2)}`);
    });
    
    return result.data;
  } catch (error) {
    console.error('Error fetching product data:', error);
    return [];
  }
}

// Example usage
fetchProductPageCards(['219042', '25788', '1369']);
Shopping Cart Calculation
Calculate the total for a shopping cart with specific card variants
// Set your API key
const API_KEY = 'your_api_key_here';
const BASE_URL = 'https://api.justtcg.com/v1';

// Calculate shopping cart total with specific variants
async function calculateShoppingCart(cartItems) {
    console.log('Calculating shopping cart total...');

    try {
        // Get up-to-date prices for all variants in cart
        const response = await fetch(`${BASE_URL}/cards`, {
            method: 'POST',
            headers: {
                'X-API-Key': API_KEY,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(cartItems)
        });

        const result = await response.json();

        if (!response.ok) {
            throw new Error(result.error?.message || 'Failed to fetch prices');
        }

        // Calculate total (in a real app, you'd update the cart UI)
        let total = 0;

        result.data.forEach(item => {
            const subtotal = item.variants[0].price;
            total += subtotal;

            console.log(
                `${item.name} (${item.variants[0].condition}, ${item.variants[0].printing}): $${item.variants[0].price.toFixed(2)}`
            );
        });

        console.log(`Cart Total: $${total.toFixed(2)}`);
        return total;
    } catch (error) {
        console.error('Error calculating cart:', error);
        return 0;
    }
}

// Example usage
calculateShoppingCart([
    { tcgplayerId: '219042', condition: 'Near Mint', printing: 'Normal' },
    { tcgplayerId: '25788', condition: 'Lightly Played', printing: '1st Edition' }
]);

Rate Limits & Usage

The JustTCG API has rate limits based on your subscription plan. You can monitor your API usage in your dashboard.

Rate Limits by Plan

Plan
Monthly Limit
Daily Limit
Rate Limit
Free
1,000 requests
100 requests
10 requests/min
Starter
10,000 requests
1,000 requests
20 requests/min
Professional
50,000 requests
5,000 requests
50 requests/min
Enterprise
500,000 requests
50,000 requests
100 requests/min
If you exceed your rate limit, the API will return a 429 Too Many Requests response. If you exceed your monthly limit, you'll need to upgrade your plan to continue using the API.

Note: Rate limits are enforced per API key. If you have multiple keys, each key has its own rate limit.

Reset Times

Plan Type
Daily Limit
Monthly Limit
Free
Midnight (00:00) UTC
On day of month which the account was created at Midnight (00:00) UTC.
Paid
Midnight (00:00) UTC
On successful payment at the start of each billing cycle.

Support

If you have any questions or need help with the API, please contact our support team.

Change Log

  • AddedLanguage Field Added to Variant Object2025-08-12

    Added a new field language to the variant object to specify the language of the card.

  • AddedNew Games Added2025-08-10

    Added support for two new games: Grand Archive TCG and Pokemon Japan (grand-archive-tcg, pokemon-japan).

  • AddedMulti-Condition and Multi-Printing Support2025-08-01

    Added support for querying for multiple conditions (e.g., Near Mint, Lightly Played) and multiple printings (e.g., First Edition, Unlimited). The cards endpoint now accepts condition and printing query parameters that can take multiple values comma-separated. Example: /cards?condition=NM,LP&printing[]=First Edition,Unlimited. This allows for more granular searches and better filtering of card data.

  • Changed[BREAKING] Card ID Standardization Completed2025-07-11

    To more accurately represent card variations, the id format for cards and variants has been updated to include the card's rarity. This is a breaking change that primarily affects any application that stores card or variant IDs.

    • Old ID Format: game-set-name
    • New ID Format: game-set-name-rarity

    API consumers must update their code to generate and use the new ID format. All previously stored IDs are now invalid and must be re-fetched or programmatically updated.

    Message to our fellow developers:

    We recognize this is the second breaking change to Card IDs in a short period, and we sincerely apologize for the inconvenience this causes. JustTCG is experiencing steady adoption, and our developer community is growing every day. We made the difficult but necessary decision to implement this fix now, as delaying it would have exposed a much larger number of developers to this issue in the near future.

    This update was essential to correctly support cards that exist in multiple rarities, which a few of you had pointed out were missing. We have now stabilized the ID schema, and we are confident this will prevent future breaking changes to these specific identifiers.


    Should you have any questions, or if you find that re-fetching data has significantly impacted your monthly quota, please contact our support team for assistance.

  • AddedOrderBy Parameters Added2025-07-04

    Added support for sorting by price and price changes using the orderBy and order parameters. orderBy can accept the following values: 'price', '24h', '7d' and '30d'. order is the direction of the ordering: 'desc' or 'asc'.

  • Changed[BREAKING] Card ID Standardization2025-07-01

    Card IDs now include the full game name. Some IDs with invalid characters have been standardized. Backwards compatibility is maintained for the old game names.

  • ChangedRate Limit Policy Update2025-06-14

    API rate limits have been adjusted for free users. See the Rate Limits section for details.

  • DeprecatedDeprecated /variants and /cards-search endpoints2025-05-15

    Deprecated the /variants and /cards-search endpoints. The functionality of these endpoints are merged into the /cards endpoint.

  • Addedv1 API Launched2025-04-02

    Version 1 introduces initial endpoints and card structure.