Compare TCGPlayer, Reverb, and OfferUp Prices in One API Call

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MyrinNew
    Senior Member
    • Feb 2024
    • 5175

    #1

    Compare TCGPlayer, Reverb, and OfferUp Prices in One API Call

    Compare TCGPlayer, Reverb, and OfferUp Prices in One API Call

    If you flip trading cards, musical gear, or general merchandise, you're probably checking multiple marketplaces manually to find the best price. TCGPlayer for Magic/Pokemon cards, Reverb for guitars and pedals, OfferUp for local deals.


    I built a unified API that searches across 20+ marketplaces and returns normalized results. Here's how to build a price comparison tool in ~30 lines.


    Quick Start: Cross-Marketplace Search





    const API_URL = 'https://marketplace-price-api-production.up.railway.app';
    const API_KEY = 'your-key';

    // Search for a Fender Stratocaster across marketplaces
    const markets = ['reverb', 'offerup', 'craigslist'];
    const query = 'Fender Stratocaster American Professional';

    const results = await Promise.all(
    markets.map(async (market) => {
    const resp = await fetch(
    `${API_URL}/${market}/search?` +
    new URLSearchParams({ q: query, limit: '5' }),
    { headers: { 'X-Api-Key': API_KEY } }
    );
    const data = await resp.json();
    return { market, listings: data.results || [] };
    })
    );

    // Find the cheapest listing across all marketplaces
    const allListings = results.flatMap(r =>
    r.listings.map(l => ({ ...l, source: r.market }))
    );

    allListings
    .filter(l => l.price > 0)
    .sort((a, b) => a.price - b.price)
    .slice(0, 10)
    .forEach(l => {
    console.log(
    `$${l.price.toFixed(2)} — ${l.title.slice(0, 60)} [${l.source}]`
    );
    });







    Output:






    $850.00 — Fender American Professional II Stratocaster [offerup]
    $899.00 — Fender Am Pro II Strat Mystic Surf Green [reverb]
    $925.00 — Fender American Professional II Stratocaster HSS [craigslist]
    $949.99 — Fender American Pro II Strat Dark Night [reverb]
    $975.00 — Fender American Professional II Strat w/ Case [reverb]







    One search query, three marketplaces, sorted by price.


    Trading Card Price Comparison

    For TCGPlayer, the API returns market pricing data:






    const tcgResp = await fetch(
    `${API_URL}/tcg/search?` +
    new URLSearchParams({
    q: 'Charizard ex 223',
    game: 'pokemon'
    }),
    { headers: { 'X-Api-Key': API_KEY } }
    );

    const cards = await tcgResp.json();

    for (const card of cards.results.slice(0, 5)) {
    console.log(`${card.name} — Market: $${card.marketPrice}`);
    console.log(` Low: $${card.lowPrice} | Mid: $${card.midPrice}`);
    }







    Building an Arbitrage Finder

    The real power is finding price gaps between marketplaces. Here's a script that checks if something is cheaper on one platform vs. another:






    async function findArbitrage(query, buyFrom, sellOn) {
    const [buyResults, sellResults] = await Promise.all([
    fetch(
    `${API_URL}/${buyFrom}/search?q=${encodeURIComponent(query)}&limit=10`,
    { headers: { 'X-Api-Key': API_KEY } }
    ).then(r => r.json()),
    fetch(
    `${API_URL}/${sellOn}/search?q=${encodeURIComponent(query)}&limit=10`,
    { headers: { 'X-Api-Key': API_KEY } }
    ).then(r => r.json()),
    ]);

    const buyMin = Math.min(
    ...buyResults.results.filter(r => r.price > 0).map(r => r.price)
    );
    const sellMax = Math.max(
    ...sellResults.results.filter(r => r.price > 0).map(r => r.price)
    );

    const margin = ((sellMax - buyMin) / buyMin * 100).toFixed(1);

    if (sellMax > buyMin) {
    console.log(`💰 ${query}`);
    console.log(` Buy on ${buyFrom}: $${buyMin.toFixed(2)}`);
    console.log(` Sell on ${sellOn}: $${sellMax.toFixed(2)}`);
    console.log(` Margin: ${margin}%`);
    }

    return { query, buyMin, sellMax, margin: parseFloat(margin) };
    }

    // Check a list of items
    const items = [
    'Boss Katana 50',
    'Shure SM7B',
    'Roland TD-17',
    'Fender Jazz Bass',
    ];

    for (const item of items) {
    await findArbitrage(item, 'offerup', 'reverb');
    await new Promise(r => setTimeout(r, 300));
    }







    Supported Marketplaces

    The API covers 20+ marketplaces across categories:


    Musical Instruments: Reverb

    Trading Cards: TCGPlayer

    General: OfferUp, Craigslist, Facebook Marketplace, Poshmark

    Real Estate: Redfin, Realtor.com, Zillow

    Cars: AutoTrader, Cars.com, CarGurus

    Home Services: Thumbtack, Houzz, Angi


    Each marketplace endpoint follows the same pattern: /{marketplace}/search?q=your+query. The response schema is normalized — title, price, url, image, location — so you don't need separate parsing logic per marketplace.

    Price Tracking Over Time

    Set up a daily cron to track prices on specific items:






    import { appendFileSync } from 'fs';

    const TRACK = [
    { query: 'Pokemon Charizard ex 223', market: 'tcg' },
    { query: 'Gibson Les Paul Standard', market: 'reverb' },
    ];

    for (const item of TRACK) {
    const resp = await fetch(
    `${API_URL}/${item.market}/search?q=${encodeURIComponent(item.query)}&limit=5 `,
    { headers: { 'X-Api-Key': API_KEY } }
    );
    const data = await resp.json();

    const prices = data.results
    ?.filter(r => r.price > 0)
    .map(r => r.price) || [];

    if (prices.length > 0) {
    const avg = (prices.reduce((a, b) => a + b, 0) / prices.length).toFixed(2);
    const line = `${new Date().toISOString()},${item.market},${item.query} ,${avg},${Math.min(...prices)},${Math.max(...price s)}`;
    appendFileSync('price-history.csv', line + '\n');
    }
    }







    After a few weeks, you'll have enough data points to spot trends and time your buys.


    I built this because I got tired of writing scrapers every time I needed marketplace data for a project. It's on RapidAPI — free tier for evaluation, paid tiers when you're running it in production.




    More...
Working...