eBay Trading Card Comps avatar

eBay Trading Card Comps

Pricing

from $2.10 / 1,000 sold listing saveds

Go to Apify Store
eBay Trading Card Comps

eBay Trading Card Comps

Sold eBay comps for sports cards and Pokémon/TCG cards, split by grade. Reads PSA, BGS, SGC, CGC and other grades from every sold listing, separates raw from graded, and summarizes median, average and range per grade. No login.

Pricing

from $2.10 / 1,000 sold listing saveds

Rating

0.0

(0)

Developer

Epic Scrapers

Epic Scrapers

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

13 days ago

Last modified

Share

eBay Trading Card Comps: sold prices for sports cards and Pokémon, split by grade

eBay Trading Card Comps turns any card search into sold comps you can trust. Enter a card such as 2018 Prizm Luka Doncic #280 or Charizard Base Set 4/102, and the actor collects its sold eBay listings, reads the grade from every title (PSA 10, BGS 9.5, CGC 10 Pristine, raw…) and gives you a price summary per grade: median, average, range, 25th/75th percentile and the last sale.

  • Raw and graded, separated for you. Most raw listings never say "raw" or "ungraded", so keyword tricks throw away good comps. This actor reads the grading company and grade from the title, uses eBay's own Graded/Ungraded condition, and puts every sale in the right bucket.
  • Real grade parsing, not keyword matching. Half grades, BGS Black Label, Pristine 10s, PSA qualifiers (OC, MC…), autograph grades ("PSA 9 Auto 10"), the old SGC 100-point scale and cert numbers. "PSA 10 ready", "potential PSA 10" and "not PSA" are not counted as graded.
  • Comps summary per grade. One record per card with statistics for Raw, PSA 10, PSA 9, BGS 9.5 and every other grade found. Accepted Best Offers are counted but kept out of the price statistics, because eBay doesn't show the amount paid.
  • Card details on every sale. Year, brand, set, player or character, card number, parallel, serial number, print run, rookie, autograph, patch, 1st Edition, language and lot flags.
  • Pay per sale, no subscription. No eBay account, API key or proxy setup. Export to JSON, CSV, Excel or Google Sheets.

Scope: sold listings only, from eBay's sold search (about the last 90 days). For live listings use eBay Search Results Scraper; for sold data of any product, not just cards, use eBay Sold Listings Scraper.

What can you do with eBay Trading Card Comps?

GoalHow
Price a card before buying or sellingRead the median and 25th–75th percentile for your grade in the COMPS_SUMMARY record.
Decide whether grading pays offCompare the Raw bucket with PSA 9 and PSA 10 for the same card, minus the grading cost.
Compare grading companiesSee PSA 10, BGS 9.5, SGC 10 and CGC 10 prices for the same card side by side.
Raw-only compsSet Graded or raw to raw. No need to add "raw" to your query.
Track a player or a setSchedule a list of cards weekly and follow the median per grade over time.
Value a collectionAdd one query per card and export the summary to a spreadsheet.
Spot underpriced salesSort the dataset by soldPrice within a gradeBucket and look at auctions (listingType) with few bidCount.

How it compares

What you needeBay Trading Card CompsGeneric eBay sold scraperseBay's own sold search
Raw vs gradedRead from title and eBay's condition, for every saleOnly through keywords in your queryManual filters, one grade at a time
Grade, grader, Black Label, certParsed fieldsNoNo
Price summary per gradeMedian, mean, min, max, percentiles, last saleNo, raw rows onlyNo
Best Offer acceptedFlagged and kept out of price statisticsOften reported at the asking priceShown with the asking price struck out
Card details (set, #, parallel)Parsed fieldsNoNo
ExportJSON, CSV, Excel, APIYesNo

An alternative to card price guides

Price guide sites show their own estimates or a short list of sales. This actor gives you the sold listings themselves, with a link to each one, so you can check every comp and drop the ones that don't fit. The summary is plain statistics over those sales; nothing is modeled.

Quick start

  1. Click Try for free and sign in to Apify.
  2. Add one or more cards to Cards to search, for example 2018 Prizm Luka Doncic #280. Write them as you would search eBay: year, set, player or character, card number. Leave the grade out to get every grade.
  3. For a first run, set Max sales per card to 30.
  4. Click Start. When the run finishes, open the Output tab for the sales and the comps summary.
{
"queries": ["2018 Prizm Luka Doncic #280"],
"maxItems": 30
}

What data can you extract?

Every row in the dataset is one sold listing:

GroupFields
SalesoldPrice, currency, shippingPrice, totalPrice, listedPrice, originalPrice, buyerProtectionFee, listingType, isBestOfferAccepted, bidCount, soldDate, soldAt
GradeisGraded, grader, grade, gradeLabel, gradeQualifier, autoGrade, certNumber, gradeBucket, gradeSource
Cardyear, season, brand, set, player, cardNumber, parallel, serialNumber, printRun, isRookie, isAutograph, isPatch, isFirstEdition, language, isLot
Listingquery, site, listingId, title, url, imageUrl, condition, categoryId, inPsaVault, sellerUsername, sellerFeedbackScore, sellerFeedbackPercent, sellerType, itemLocation, shippingText, soldDateText, scrapedAt

The comps summary is saved separately, in the run's key-value store under COMPS_SUMMARY (see Comps summary).

Track card prices over time with scheduled runs

Card prices move with seasons, injuries, set releases and grading pop reports. Apify can run the actor on a schedule and send the results wherever you need them.

1. Save your input as a task

Open the actor, add your cards and filters, then click Save as a new task. A task is a saved input you can run again with one click or on a schedule.

2. Schedule the task

In Apify Console, go to Schedules, click Create new, choose how often to run, and add your task. See Schedules and How to create a schedule.

Watch how to schedule an Actor:

Or schedule a saved task:

Common schedules:

Use caseFrequencyCron expressionDays back
Collection valueWeekly (Monday)0 6 * * 17
Hot players and new releasesDaily0 6 * * *1
Long-term price historyMonthly0 6 1 * *31

Match Sold in the last (days) to the schedule so each run covers the time since the previous one.

3. Send the results to a spreadsheet

Connect Google in the task's Integrations tab to save every run to Google Sheets or Google Drive automatically:

4. Compare runs

Every row has listingId, soldDate and gradeBucket, so runs are easy to join:

  • Price trend per grade: median soldPrice per query and gradeBucket per week.
  • Grading premium: PSA 10 median divided by the Raw median, over time.
  • Volume: number of sales per gradeBucket per period.
  • Duplicates across runs: drop repeated listingIds when runs overlap.

Input reference

FieldTypeDefaultEffect
queriesArray of stringsRequiredOne card per entry, searched as you would on eBay.
siteString"ebay.com"ebay.com, ebay.co.uk, ebay.de, ebay.fr, ebay.it, ebay.es, ebay.ca or ebay.com.au. Prices are in the site's currency.
daysInteger90Only sales from the last N days. Ignored when soldFrom is set.
maxItemsInteger100Maximum sales saved per card.
gradeFilterString"all""all", "raw" or "graded".
gradersArray of stringsEmptyOnly these grading companies: PSA, BGS, SGC, CGC, TAG, CSG, HGA, ACE, BVG, BCCG, GMA, KSA, MNT, ISA, AGS, PCA, ARS. Implies graded only.
minGrade/maxGradeNumberEmptyNumeric grade range, 1 to 10 (half grades allowed). Implies graded only.
excludeLotsBooleantrueLeave out lots, bundles, multi-card and "you pick" listings.
excludeParallelsBooleanfalseBase cards only: leave out parallels and numbered cards, except parallels named in your query and card game rarities such as Alt Art.
matchCardNumberBooleantrueWhen your query has a card number (#US175, #280, 4/102), leave out sales whose title names a different number. Titles without a number are kept; 175, US-175 and US175 match.
excludeKeywordsArray of stringsEmptyLeave out titles containing any of these words (not case-sensitive).
minPrice/maxPriceNumberEmptyPrice range in the site's currency.
soldFrom/soldToDateEmptyExact sold date range (YYYY-MM-DD).
categoryString"auto""auto", "sports" (Sports Trading Card Singles), "tcg" (CCG Individual Cards), "nonSport" (Non-Sport Trading Card Singles) or "all".
categoryIdStringEmptyAny eBay category ID. Overrides category.

With category: "auto", card game queries (Pokémon, Magic, One Piece, Yu-Gi-Oh!, Lorcana…) search card game singles and everything else searches sports card singles. If that finds nothing, the actor searches all categories.

Ready-to-run examples

All grades of one card

{
"queries": ["2018 Prizm Luka Doncic #280"],
"excludeParallels": true,
"maxItems": 200
}

The summary shows Raw, PSA 10, PSA 9, BGS 9.5 and so on side by side. Base cards only keeps Silver, Green and other parallels out of the base card's comps.

Raw comps only

{
"queries": ["Charizard Base Set 4/102 holo"],
"gradeFilter": "raw",
"excludeKeywords": ["30th", "celebrations", "reprint", "proxy"]
}

Raw listings rarely say "raw". The actor uses eBay's Ungraded condition and drops titles that name a grader. Exclude reprints that share the card number with excludeKeywords.

PSA 10 and BGS 9.5+ for several cards

{
"queries": ["2023 Bowman Chrome Paul Skenes auto", "Umbreon VMAX 215/203 Evolving Skies"],
"graders": ["PSA", "BGS"],
"minGrade": 9.5,
"days": 30
}

A collection on eBay UK

{
"queries": ["Charizard Base Set 4/102", "Blastoise Base Set 2/102", "Venusaur Base Set 15/102"],
"site": "ebay.co.uk",
"maxItems": 100
}

On ebay.co.uk, ebay.fr and ebay.it, eBay adds a Buyer Protection fee to private sellers' prices. The actor runs a second search restricted to private sellers and removes the fee, so soldPrice is the price of the card (see buyerProtectionFee).

Analyze the results with ChatGPT or Claude

Export the dataset as CSV (the Overview or Grades view keeps it small), or download the COMPS_SUMMARY record, and attach it to a chat with ChatGPT, Claude or another AI assistant. Some prompts to start with:

Price my card. "These are eBay sold comps for one card. Using only sales with a soldPrice, give me a fair price range for a PSA 9, and list the 5 most recent PSA 9 sales with their links."

Should I grade it? "From this comps summary, compare the Raw median with the PSA 9 and PSA 10 medians. Assuming grading costs $25 and a 40% chance of a PSA 10, is grading worth it?"

Find outliers. "In this dataset, flag sales whose soldPrice is more than 40% away from the median of their gradeBucket, and say from the title whether they are a different parallel, a lot or a misread grade."

The data is also available through the Apify API and integrations such as Make, Zapier and n8n. With the API client for JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('epicscrapers/ebay-trading-card-comps').call({
queries: ['2018 Prizm Luka Doncic #280'],
maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const summary = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('COMPS_SUMMARY');

Or with curl:

curl -X POST "https://api.apify.com/v2/acts/epicscrapers~ebay-trading-card-comps/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"queries": ["Charizard Base Set 4/102"], "maxItems": 50}'

Output

Sales go to the run's default dataset. Use the views Overview, Grades or Card details, or export everything as JSON, CSV, Excel, XML or HTML.

This is a real row from a 2018 Prizm Luka Doncic #280 run on October 2, 2026, an accepted Best Offer:

{
"query": "2018 Prizm Luka Doncic #280",
"site": "ebay.com",
"listingId": "820174767584",
"title": "Panini Prizm 2018-19 Luka Dončić #280 Rookie Base PSA 9 Dallas Mavericks",
"url": "https://www.ebay.com/itm/820174767584",
"imageUrl": "https://i.ebayimg.com/images/g/SYAAAeSwoQRqt8Wm/s-l500.jpg",
"soldPrice": null,
"currency": "USD",
"shippingPrice": null,
"totalPrice": null,
"listedPrice": 79.99,
"buyerProtectionFee": null,
"sellerType": null,
"originalPrice": null,
"listingType": "best_offer_accepted",
"isBestOfferAccepted": true,
"bidCount": null,
"soldDate": "2026-10-02",
"soldAt": "2026-10-02T17:33:00.000Z",
"isGraded": true,
"grader": "PSA",
"grade": 9,
"gradeLabel": null,
"gradeQualifier": null,
"autoGrade": null,
"gradeSource": "title",
"certNumber": null,
"gradeBucket": "PSA 9",
"year": 2018,
"season": "2018-19",
"brand": "Panini",
"set": "Prizm",
"player": "Luka Doncic",
"cardNumber": "280",
"parallel": null,
"serialNumber": null,
"printRun": null,
"isRookie": true,
"isAutograph": false,
"isPatch": false,
"isFirstEdition": false,
"language": null,
"isLot": false,
"condition": "New (Other)",
"categoryId": "261328",
"inPsaVault": false,
"sellerUsername": "verifiedslabs",
"sellerFeedbackScore": 164,
"sellerFeedbackPercent": 100,
"itemLocation": "Located in United States",
"shippingText": null,
"soldDateText": "Sold Oct 2, 2026",
"scrapedAt": "2026-10-02T23:49:51.087Z"
}

Comps summary

The COMPS_SUMMARY record in the run's key-value store has one entry per card, built from the sales saved in the dataset. Open it from the Output tab (Comps summary) or with the API at https://api.apify.com/v2/key-value-stores/{storeId}/records/COMPS_SUMMARY. It is not part of the dataset and is not charged. Shortened example from the same card, 30 days, base cards only:

{
"generatedAt": "2026-10-03T…",
"site": "ebay.com",
"dateFrom": "2026-09-03",
"dateTo": null,
"gradeFilter": "all",
"queries": [
{
"query": "2018 Prizm Luka Doncic #280",
"category": "Sports Trading Card Singles (261328)",
"currency": "USD",
"status": "complete",
"salesCount": 60,
"bestOfferAcceptedCount": 13,
"overall": { "pricedCount": 47, "median": "…" },
"grades": [
{
"gradeBucket": "Raw",
"salesCount": 5,
"median": 62.25,
"p25": 57.88,
"p75": 201.24,
"lastSoldPrice": 59.5
},
{
"gradeBucket": "PSA 10",
"grader": "PSA",
"grade": 10,
"salesCount": 30,
"bestOfferAcceptedCount": "…",
"pricedCount": "…",
"median": 203.75,
"mean": "…",
"min": "…",
"max": "…",
"p25": 197.4,
"p75": 223.74,
"lastSoldPrice": 196.53,
"lastSoldAt": "2026-10-02T…",
"lastSoldUrl": "https://www.ebay.com/itm/…"
},
{ "gradeBucket": "PSA 9", "salesCount": 16, "median": 75, "p25": 71, "p75": 82, "lastSoldPrice": 84.95 }
]
}
]
}

Buckets are Raw first, then by number of sales. Lots (when excludeLots is off) get their own Lot bucket and are left out of overall. status is partial (charge limit reached) when the run stopped at its spending limit.

Notes on fields

  • soldPrice excludes shipping and, on ebay.co.uk/.fr/.it, eBay's Buyer Protection fee for private sellers. It is null for accepted Best Offers: eBay shows only the asking price (listedPrice), not the amount paid. Those sales are counted in the summary but not in its price statistics.
  • shippingPrice is 0 for free shipping and null when eBay doesn't show shipping; totalPrice is then null too.
  • soldDate is the sale date eBay shows. soldAt is the exact time in UTC when eBay's end time falls on that date, otherwise midnight UTC of soldDate (multi-quantity listings can sell long before they end).
  • Grades and card details are parsed from the title, so they are best effort. gradeSource: "condition" means the title names no grader but the seller chose eBay's Graded condition; those sales are in Graded (unknown grader).
  • player is the player or character from your query, set only when the title contains it. parallel names the first parallel or rarity found.
  • Missing values are null. Every row has scrapedAt in UTC.

FAQ

How accurate is the grade parsing?

In our tests on real sold listings the grader and grade matched the title for nearly every graded card, including half grades, Black Label and Pristine labels. Parsing works from the title and eBay's condition, so it can't see a grade the seller left out of the title (those land in Graded (unknown grader)), and it trusts the title when the seller picked the wrong condition. Check outliers with the url before relying on a single sale.

Why are some sales missing a price?

They sold through an accepted Best Offer. eBay doesn't publish the accepted amount, only the asking price, which the actor puts in listedPrice. Using the asking price would inflate comps, so it is kept out of the statistics.

Why did I get few or no results?

Write the card the way sellers title it, without the grade: 2018 Prizm Luka Doncic #280, not a full sentence. eBay only keeps about 90 days of sold listings. When eBay has no exact matches it shows "results matching fewer words"; the actor skips those, because they are other cards, and the log says so. Narrow filters (grade range, price range, base only) also reduce results.

Why do my comps include other cards?

eBay's search matches words, so a query for a base card can also return parallels, reprints or anniversary versions. Turn on Base cards only, add words such as reprint, 30th or celebrations to Exclude titles containing, or make the query more specific.

Does "Raw only" need "raw" or "ungraded" in my query?

No. Don't add them: most raw listings don't use those words. The actor uses eBay's Ungraded condition and drops any title that names a grading company.

How fast is it?

Each eBay page has 60 sales and takes a few seconds. A card with 100 sales needs about 2 pages; on ebay.co.uk, .fr and .it the private-seller check adds a few more.

Why did my run fail?

If eBay keeps refusing the requests, the run fails with a message instead of finishing with an empty or incomplete dataset. Sales saved before that stay in the dataset. Try again later. A search with genuinely no sold listings finishes successfully with a message saying so.

Do I need proxies, an eBay account or an API key?

No. The actor doesn't log in and handles connections and retries itself.

The actor collects publicly visible sold listing data. It stores the seller's public username and feedback, but no buyer data. You are responsible for how you use the data, including eBay's terms and laws such as GDPR. Use it responsibly and at a reasonable volume.

Cost

This actor uses pay-per-event pricing: you pay for each sold listing saved to the dataset (event sold-listing), with no subscription: $3 per 1,000 sales on the free plan, down to $2.10 on Gold and above. Platform usage and proxy are included. The comps summary is free. The Pricing tab always shows the current price. Set a maximum cost per run; the actor stops cleanly when it's reached and still writes the summary for the sales it saved.

Support

Report problems or request features in the Issues tab. Include the run ID, the input and what you expected. We read every issue.

This actor is not affiliated with, endorsed by or sponsored by eBay Inc. "eBay" is a trademark of eBay Inc. PSA, BGS/Beckett, SGC, CGC and other grading company names are trademarks of their respective owners; this actor is not affiliated with them.