Skip to content

Building a Price Tracker

Build a price tracker that monitors card prices across multiple TCGs. By the end, you’ll have a working application that tracks prices and alerts you to changes.

  • Fetch current prices for any card
  • Store historical price data
  • Detect significant price changes
  • Send alerts via Discord webhook
  • Node.js 18+
  • Pulls API key (Free tier works)
  • Discord webhook URL (optional, for alerts)
  1. Create project and install dependencies

    Terminal window
    mkdir price-tracker && cd price-tracker
    npm init -y
    npm install @pulls/sdk dotenv
  2. Configure environment

    .env
    PULLS_API_KEY=pk_live_your_key_here
    DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
  3. Initialize the SDK

    src/index.ts
    import { PullsAPI } from '@pulls/sdk'
    import 'dotenv/config'
    const pulls = new PullsAPI({
    apiKey: process.env.PULLS_API_KEY!
    })

Get current market prices for a card:

src/prices.ts
async function getCardPrice(cardId: string) {
const card = await pulls.cards.get(cardId, {
includePrices: true
})
return {
id: card.id,
name: card.name,
tcg: card.tcg,
prices: card.prices
}
}
// Usage
const charizard = await getCardPrice('base1-4')
console.log(`${charizard.name}: $${charizard.prices.market}`)
// Output: Charizard: $420.00

Create a watchlist and fetch prices in bulk:

src/watchlist.ts
const watchlist = [
'sv7-001', // Pokemon
'ltr-1', // Lorcana
'neo-1', // One Piece
]
async function checkWatchlist() {
const prices = await pulls.prices.list({
cardIds: watchlist
})
return prices.map(p => ({
cardId: p.cardId,
market: p.market,
change24h: p.change24h
}))
}

Compare current prices against stored values:

src/alerts.ts
interface PriceRecord {
cardId: string
price: number
timestamp: Date
}
const priceHistory: Map<string, PriceRecord[]> = new Map()
function detectSignificantChange(
cardId: string,
currentPrice: number,
thresholdPercent: number = 10
): boolean {
const history = priceHistory.get(cardId) ?? []
if (history.length === 0) return false
const previousPrice = history[history.length - 1].price
const changePercent = ((currentPrice - previousPrice) / previousPrice) * 100
return Math.abs(changePercent) >= thresholdPercent
}
function recordPrice(cardId: string, price: number) {
const history = priceHistory.get(cardId) ?? []
history.push({ cardId, price, timestamp: new Date() })
priceHistory.set(cardId, history)
}

Notify when prices change significantly:

src/discord.ts
async function sendDiscordAlert(
cardName: string,
oldPrice: number,
newPrice: number
) {
const change = ((newPrice - oldPrice) / oldPrice) * 100
const direction = change > 0 ? '📈' : '📉'
await fetch(process.env.DISCORD_WEBHOOK_URL!, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
embeds: [{
title: `${direction} Price Alert: ${cardName}`,
description: `Price changed ${change.toFixed(1)}%`,
fields: [
{ name: 'Old Price', value: `$${oldPrice.toFixed(2)}`, inline: true },
{ name: 'New Price', value: `$${newPrice.toFixed(2)}`, inline: true },
],
color: change > 0 ? 0x22c55e : 0xef4444
}]
})
})
}

Tie it all together with a scheduled check:

src/index.ts
import { PullsAPI } from '@pulls/sdk'
import 'dotenv/config'
const pulls = new PullsAPI({ apiKey: process.env.PULLS_API_KEY! })
const watchlist = ['sv7-001', 'base1-4', 'ltr-1']
const priceHistory: Map<string, number> = new Map()
async function checkPrices() {
console.log(`[${new Date().toISOString()}] Checking prices...`)
const prices = await pulls.prices.list({ cardIds: watchlist })
for (const price of prices) {
const previousPrice = priceHistory.get(price.cardId)
priceHistory.set(price.cardId, price.market)
if (previousPrice) {
const change = ((price.market - previousPrice) / previousPrice) * 100
if (Math.abs(change) >= 10) {
console.log(`ALERT: ${price.cardId} changed ${change.toFixed(1)}%`)
// await sendDiscordAlert(...)
}
}
}
}
// Check every 15 minutes
setInterval(checkPrices, 15 * 60 * 1000)
checkPrices() // Initial check
  • Add persistent storage (SQLite, Redis)
  • Track graded card prices with prices.graded
  • Use webhooks instead of polling (Pro+ plans)
  • Build a web dashboard with Next.js