SDK Examples

Practical examples and tutorials for using the JustTCG JavaScript/TypeScript SDK.

Quick Start Example

This example demonstrates how to find the most valuable cards in Disney Lorcana: The First Chapter:

import { JustTCG } from 'justtcg-js';

async function findTopCards() {
  try {
    // The client automatically looks for the JUSTTCG_API_KEY environment variable
    const client = new JustTCG();

    console.log('Searching for the most valuable cards in Disney Lorcana: The First Chapter...');

    const response = await client.v1.cards.get({
      game: 'Disney Lorcana',
      set: 'the-first-chapter-disney-lorcana',
      orderBy: 'price',
      order: 'desc',
      limit: 10,
      condition: ['NM', 'LP', 'MP', 'HP', 'D'], // Exclude sealed cards
    });

    console.log('--- Top 10 Most Valuable Cards ---');
    response.data.forEach((card, index) => {
      // Find the most expensive variant for display (e.g., the Foil version)
      const topVariant = card.variants.sort((a, b) => (b.price ?? 0) - (a.price ?? 0))[0];

      const price = topVariant?.price?.toFixed(2) ?? 'N/A';
      const printing = topVariant?.printing ? `(${topVariant.printing})` : '';

      console.log(`${index + 1}. ${card.name} ${printing} - $${price}`);
    });

    console.log(`API requests remaining today: ${response.usage.apiDailyRequestsRemaining}`);
  } catch (error) {
    console.error('An error occurred:', (error as Error).message);
    process.exit(1);
  }
}

findTopCards();
Environment Setup: Make sure you have set your JUSTTCG_API_KEY environment variable before running this example.

Batch Card Lookup

This example shows how to efficiently retrieve multiple specific cards using batch lookup:

import { JustTCG } from 'justtcg-js';

async function batchLookup() {
  const client = new JustTCG();

  // Look up multiple cards by different identifiers
  const response = await client.v1.cards.getByBatch([
    { cardId: 'pokemon-base-set-charizard-holo-rare' },
    { variantId: 'magic-the-gathering-collector-s-edition-black-lotus-ce-rare_near-mint' },
    { tcgplayerId: '25788' },
    { cardId: 'yugioh-the-legend-of-blue-eyes-white-dragon-blue-eyes-white-dragon-ultra-rare', printing: ['1st Edition'] }
  ]);

  console.log('Batch lookup results:');
  response.data.forEach(card => {
    console.log(`${card.name} (${card.game})`);
    card.variants.forEach(variant => {
      console.log(`${variant.condition} ${variant.printing}: $${variant.price?.toFixed(2)}`);
    });
  });

  console.log(`API requests used: ${response.usage.apiRequestsUsed}`);
  console.log(`API requests remaining: ${response.usage.apiRequestsRemaining}`);
}

batchLookup();

Price Tracking Application

This example demonstrates how to build a price tracking application that monitors specific cards:

import { JustTCG } from 'justtcg-js';

interface PriceAlert {
  cardId: string;
  threshold: number;
  direction: 'above' | 'below';
}

class PriceTracker {
  private client: JustTCG;
  private alerts: PriceAlert[] = [];

  constructor() {
    this.client = new JustTCG();
  }

  addAlert(cardId: string, threshold: number, direction: 'above' | 'below') {
    this.alerts.push({ cardId, threshold, direction });
  }

  async checkPrices() {
    console.log('Checking prices for tracked cards...');

    for (const alert of this.alerts) {
      try {
        const response = await this.client.v1.cards.get({
          cardId: alert.cardId,
          limit: 1
        });

        if (response.data.length > 0) {
          const card = response.data[0];
          const topVariant = card.variants.sort((a, b) => (b.price ?? 0) - (a.price ?? 0))[0];
          const currentPrice = topVariant?.price ?? 0;

          if (this.shouldAlert(alert, currentPrice)) {
            this.sendAlert(alert, card.name, currentPrice);
          }
        }
      } catch (error) {
        console.error(`Error checking ${alert.cardId}:`, error);
      }
    }
  }

  private shouldAlert(alert: PriceAlert, price: number): boolean {
    if (alert.direction === 'above') {
      return price >= alert.threshold;
    } else {
      return price <= alert.threshold;
    }
  }

  private sendAlert(alert: PriceAlert, cardName: string, price: number) {
    console.log(`🚨 ALERT: ${cardName} is now $${price.toFixed(2)} (${alert.direction} $${alert.threshold})`);
  }
}

// Usage
const tracker = new PriceTracker();
tracker.addAlert('pokemon-base-set-charizard-holo-rare', 500, 'above');
tracker.addAlert('magic-the-gathering-collector-s-edition-black-lotus-ce-rare', 2000, 'below');

// Check prices every 5 minutes
setInterval(() => {
  tracker.checkPrices();
}, 5 * 60 * 1000);

Inventory Management

This example shows how to build an inventory management system that tracks card values:

import { JustTCG } from 'justtcg-js';

interface InventoryItem {
  cardId: string;
  variantId: string;
  quantity: number;
  purchasePrice: number;
}

class InventoryManager {
  private client: JustTCG;
  private inventory: InventoryItem[] = [];

  constructor() {
    this.client = new JustTCG();
  }

  addItem(cardId: string, variantId: string, quantity: number, purchasePrice: number) {
    this.inventory.push({ cardId, variantId, quantity, purchasePrice });
  }

  async updatePrices() {
    console.log('Updating inventory prices...');

    const variantIds = this.inventory.map(item => item.variantId);
    
    try {
      const response = await this.client.v1.cards.getByBatch(
        variantIds.map(variantId => ({ variantId }))
      );

      let totalValue = 0;
      let totalGainLoss = 0;

      console.log('--- Inventory Report ---');
      console.log('Card Name | Condition | Current Price | Purchase Price | Gain/Loss | Total Value');
      console.log('----------|-----------|---------------|----------------|-----------|------------');

      for (const item of this.inventory) {
        const card = response.data.find(c => 
          c.variants.some(v => v.id === item.variantId)
        );

        if (card) {
          const variant = card.variants.find(v => v.id === item.variantId);
          const currentPrice = variant?.price ?? 0;
          const itemValue = currentPrice * item.quantity;
          const gainLoss = (currentPrice - item.purchasePrice) * item.quantity;

          totalValue += itemValue;
          totalGainLoss += gainLoss;

          console.log(
            `${card.name.padEnd(20)} | ${variant?.condition.padEnd(10)} | $${currentPrice.toFixed(2).padStart(12)} | $${item.purchasePrice.toFixed(2).padStart(13)} | ${gainLoss >= 0 ? '+' : ''}$${gainLoss.toFixed(2).padStart(7)} | $${itemValue.toFixed(2).padStart(10)}`
          );
        }
      }

      console.log('--- Summary ---');
      console.log(`Total Inventory Value: $${totalValue.toFixed(2)}`);
      console.log(`Total Gain/Loss: ${totalGainLoss >= 0 ? '+' : ''}$${totalGainLoss.toFixed(2)}`);
      console.log(`API requests remaining: ${response.usage.apiRequestsRemaining}`);

    } catch (error) {
      console.error('Error updating prices:', error);
    }
  }
}

// Usage
const inventory = new InventoryManager();
inventory.addItem('pokemon-base-set-charizard-holo-rare_near-mint_holofoil', 1, 150.00);
inventory.addItem('magic-the-gathering-collector-s-edition-black-lotus-ce-rare_lightly-played', 1, 2000.00);

// Update prices
inventory.updatePrices();

Comprehensive Error Handling

This example demonstrates robust error handling for production applications:

import { JustTCG } from 'justtcg-js';

class RobustAPIClient {
  private client: JustTCG;
  private maxRetries: number = 3;
  private retryDelay: number = 1000;

  constructor() {
    this.client = new JustTCG();
  }

  async safeApiCall<T>(apiCall: () => Promise<T>): Promise<T | null> {
    for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
      try {
        const result = await apiCall();
        return result;
      } catch (error) {
        console.error(`Attempt ${attempt} failed:`, error);

        if (attempt === this.maxRetries) {
          console.error('All retry attempts failed');
          return null;
        }

        // Wait before retrying
        await new Promise(resolve => setTimeout(resolve, this.retryDelay * attempt));
      }
    }
    return null;
  }

  async getCardWithErrorHandling(cardId: string) {
    const result = await this.safeApiCall(async () => {
      const response = await this.client.v1.cards.get({ cardId });

      // Check for API-level errors
      if (response.error) {
        throw new Error(`API Error: ${response.error} (Code: ${response.code})`);
      }

      return response;
    });

    if (result) {
      console.log('Success:', result.data);
      return result;
    } else {
      console.error('Failed to retrieve card after all retries');
      return null;
    }
  }

  async getGamesWithFallback() {
    try {
      const response = await this.client.v1.games.list();
      
      if (response.error) {
        console.warn('API returned error, using fallback data');
        return this.getFallbackGames();
      }

      return response.data;
    } catch (error) {
      console.error('SDK error occurred, using fallback data:', error);
      return this.getFallbackGames();
    }
  }

  private getFallbackGames() {
    // Return cached or default data
    return [
      { id: 'pokemon', name: 'Pokemon', cardsCount: 0, setsCount: 0 },
      { id: 'mtg', name: 'Magic: The Gathering', cardsCount: 0, setsCount: 0 }
    ];
  }
}

// Usage
const apiClient = new RobustAPIClient();

// Safe card lookup
apiClient.getCardWithErrorHandling('pokemon-base-set-charizard-holo-rare');

// Safe games list with fallback
apiClient.getGamesWithFallback();

More Examples

For more comprehensive examples and tutorials, check out our GitHub repository :

The SDK repository includes a comprehensive /examples directory with runnable examples for common use cases.

📁 find-most-valuable-lorcana-cards.ts
📁 card-search.ts
📁 get-prices-for-inventory.ts
📁 analyze-single-card.ts
📁 list-all-pokemon-sets.ts