# eBay Trading Card Comps (`epicscrapers/ebay-trading-card-comps`) Actor

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.

- **URL**: https://apify.com/epicscrapers/ebay-trading-card-comps.md
- **Developed by:** [Epic Scrapers](https://apify.com/epicscrapers) (community)
- **Categories:** E-commerce, Automation, AI
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 sold listing saveds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### 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](https://apify.com/epicscrapers/ebay-search-results-scraper); for sold data of any product, not just cards, use [eBay Sold Listings Scraper](https://apify.com/epicscrapers/ebay-sold-listings-api).

### What can you do with eBay Trading Card Comps?

| Goal                                  | How                                                                                                              |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Price a card before buying or selling | Read the median and 25th–75th percentile for your grade in the `COMPS_SUMMARY` record.                           |
| Decide whether grading pays off       | Compare the Raw bucket with PSA 9 and PSA 10 for the same card, minus the grading cost.                          |
| Compare grading companies             | See PSA 10, BGS 9.5, SGC 10 and CGC 10 prices for the same card side by side.                                    |
| Raw-only comps                        | Set **Graded or raw** to raw. No need to add "raw" to your query.                                                |
| Track a player or a set               | Schedule a list of cards weekly and follow the median per grade over time.                                       |
| Value a collection                    | Add one query per card and export the summary to a spreadsheet.                                                  |
| Spot underpriced sales                | Sort the dataset by `soldPrice` within a `gradeBucket` and look at auctions (`listingType`) with few `bidCount`. |

### How it compares

| What you need                    | eBay Trading Card Comps                              | Generic eBay sold scrapers          | eBay's own sold search                 |
| -------------------------------- | ---------------------------------------------------- | ----------------------------------- | -------------------------------------- |
| Raw vs graded                    | Read from title and eBay's condition, for every sale | Only through keywords in your query | Manual filters, one grade at a time    |
| Grade, grader, Black Label, cert | Parsed fields                                        | No                                  | No                                     |
| Price summary per grade          | Median, mean, min, max, percentiles, last sale       | No, raw rows only                   | No                                     |
| Best Offer accepted              | Flagged and kept out of price statistics             | Often reported at the asking price  | Shown with the asking price struck out |
| Card details (set, #, parallel)  | Parsed fields                                        | No                                  | No                                     |
| Export                           | JSON, CSV, Excel, API                                | Yes                                 | No                                     |

#### 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.

```json
{
    "queries": ["2018 Prizm Luka Doncic #280"],
    "maxItems": 30
}
```

### What data can you extract?

Every row in the dataset is one sold listing:

| Group   | Fields                                                                                                                                                                                                                                         |
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Sale    | `soldPrice`, `currency`, `shippingPrice`, `totalPrice`, `listedPrice`, `originalPrice`, `buyerProtectionFee`, `listingType`, `isBestOfferAccepted`, `bidCount`, `soldDate`, `soldAt`                                                           |
| Grade   | `isGraded`, `grader`, `grade`, `gradeLabel`, `gradeQualifier`, `autoGrade`, `certNumber`, `gradeBucket`, `gradeSource`                                                                                                                         |
| Card    | `year`, `season`, `brand`, `set`, `player`, `cardNumber`, `parallel`, `serialNumber`, `printRun`, `isRookie`, `isAutograph`, `isPatch`, `isFirstEdition`, `language`, `isLot`                                                                  |
| Listing | `query`, `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](#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](https://docs.apify.com/platform/schedules) and [How to create a schedule](https://help.apify.com/en/articles/7120817-how-to-create-a-schedule).

Watch how to schedule an Actor:

https://www.youtube.com/watch?v=1jI7WcVQmwM

Or schedule a saved task:

https://www.youtube.com/watch?v=GRFW_Loo2dk

Common schedules:

| Use case                     | Frequency       | Cron expression | Days back |
| ---------------------------- | --------------- | --------------- | --------- |
| Collection value             | Weekly (Monday) | `0 6 * * 1`     | `7`       |
| Hot players and new releases | Daily           | `0 6 * * *`     | `1`       |
| Long-term price history      | Monthly         | `0 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:

https://www.youtube.com/watch?v=IFTeKdj6ZGM

#### 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 `listingId`s when runs overlap.

### Input reference

| Field                 | Type             | Default      | Effect                                                                                                                                                                     |
| --------------------- | ---------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `queries`             | Array of strings | Required     | One card per entry, searched as you would on eBay.                                                                                                                         |
| `site`                | String           | `"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.                                       |
| `days`                | Integer          | `90`         | Only sales from the last N days. Ignored when `soldFrom` is set.                                                                                                           |
| `maxItems`            | Integer          | `100`        | Maximum sales saved per card.                                                                                                                                              |
| `gradeFilter`         | String           | `"all"`      | `"all"`, `"raw"` or `"graded"`.                                                                                                                                            |
| `graders`             | Array of strings | Empty        | Only these grading companies: `PSA`, `BGS`, `SGC`, `CGC`, `TAG`, `CSG`, `HGA`, `ACE`, `BVG`, `BCCG`, `GMA`, `KSA`, `MNT`, `ISA`, `AGS`, `PCA`, `ARS`. Implies graded only. |
| `minGrade`/`maxGrade` | Number           | Empty        | Numeric grade range, 1 to 10 (half grades allowed). Implies graded only.                                                                                                   |
| `excludeLots`         | Boolean          | `true`       | Leave out lots, bundles, multi-card and "you pick" listings.                                                                                                               |
| `excludeParallels`    | Boolean          | `false`      | Base cards only: leave out parallels and numbered cards, except parallels named in your query and card game rarities such as Alt Art.                                      |
| `matchCardNumber`     | Boolean          | `true`       | When 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. |
| `excludeKeywords`     | Array of strings | Empty        | Leave out titles containing any of these words (not case-sensitive).                                                                                                       |
| `minPrice`/`maxPrice` | Number           | Empty        | Price range in the site's currency.                                                                                                                                        |
| `soldFrom`/`soldTo`   | Date             | Empty        | Exact sold date range (`YYYY-MM-DD`).                                                                                                                                      |
| `category`            | String           | `"auto"`     | `"auto"`, `"sports"` (Sports Trading Card Singles), `"tcg"` (CCG Individual Cards), `"nonSport"` (Non-Sport Trading Card Singles) or `"all"`.                              |
| `categoryId`          | String           | Empty        | Any 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

```json
{
    "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

```json
{
    "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

```json
{
    "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

```json
{
    "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](https://docs.apify.com/api/v2) and integrations such as Make, Zapier and n8n. With the API client for JavaScript:

```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`:

```bash
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:

```json
{
    "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:

```json
{
    "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.

#### Is it legal to scrape eBay?

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.

# Actor input Schema

## `queries` (type: `array`):

One card per entry, written the way you would search eBay: year, set, player or character, card number, e.g. 2018 Prizm Luka Doncic #280 or Charizard Base Set 4/102. Leave the grade out to get every grade in one run, split into raw, PSA 10, PSA 9, BGS 9.5 and so on.

## `site` (type: `string`):

eBay marketplace to search. Prices are in its currency.

## `days` (type: `integer`):

Only sales from the last N days. eBay keeps about 90 days of sold listings. Ignored when you set a sold-from date.

## `maxItems` (type: `integer`):

Maximum sold listings saved for each card. Each saved sale is one result.

## `gradeFilter` (type: `string`):

Raw only keeps cards without a grading company in the title. You don't need words like raw or ungraded in your query.

## `graders` (type: `array`):

Only slabs from these companies. Selecting one also selects graded cards only.

## `minGrade` (type: `number`):

Only graded cards with at least this numeric grade (1 to 10, half grades allowed, e.g. 9.5).

## `maxGrade` (type: `number`):

Only graded cards with at most this numeric grade (1 to 10).

## `excludeLots` (type: `boolean`):

Leave out lots, bundles, multi-card listings and "you pick" listings, whose price is not the price of one card.

## `excludeParallels` (type: `boolean`):

Leave out parallels and numbered cards (Silver, Refractor, Gold /10…) so the comps compare the base card only. Uses the parallel and print run read from the title.

## `matchCardNumber` (type: `boolean`):

When your query has a card number (#US175, #280, 4/102), leave out sales whose title names a different card number, e.g. Jered Weaver #US26 for "2011 Topps Update Mike Trout #US175". Titles without a card number are kept. "175", "US-175" and "US175" count as the same number.

## `excludeKeywords` (type: `array`):

Leave out sales whose title contains any of these words or phrases (not case-sensitive), e.g. reprint, custom, proxy.

## `minPrice` (type: `number`):

Only sales at or above this price, in the site's currency.

## `maxPrice` (type: `number`):

Only sales at or below this price, in the site's currency.

## `soldFrom` (type: `string`):

Only sales on or after this date. Overrides "Sold in the last (days)".

## `soldTo` (type: `string`):

Only sales on or before this date.

## `category` (type: `string`):

Automatic searches card game singles (Pokémon, Magic, One Piece…) for card game queries and sports card singles for everything else, and falls back to all categories when that finds nothing.

## `categoryId` (type: `string`):

Search this eBay category instead, e.g. 261328. Overrides "Card category".

## Actor input object example

```json
{
  "queries": [
    "2018 Prizm Luka Doncic #280",
    "Charizard Base Set 4/102 holo"
  ],
  "site": "ebay.com",
  "days": 90,
  "maxItems": 100,
  "gradeFilter": "all",
  "graders": [],
  "excludeLots": true,
  "excludeParallels": false,
  "matchCardNumber": true,
  "excludeKeywords": [
    "reprint",
    "custom",
    "proxy"
  ],
  "category": "auto"
}
```

# Actor output Schema

## `results` (type: `string`):

Every saved sale with its grade and card details.

## `compsSummary` (type: `string`):

Price statistics per card and grade bucket (JSON).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "2018 Prizm Luka Doncic #280",
        "Charizard Base Set 4/102 holo"
    ],
    "excludeKeywords": [
        "reprint",
        "custom",
        "proxy"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("epicscrapers/ebay-trading-card-comps").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": [
        "2018 Prizm Luka Doncic #280",
        "Charizard Base Set 4/102 holo",
    ],
    "excludeKeywords": [
        "reprint",
        "custom",
        "proxy",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("epicscrapers/ebay-trading-card-comps").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "2018 Prizm Luka Doncic #280",
    "Charizard Base Set 4/102 holo"
  ],
  "excludeKeywords": [
    "reprint",
    "custom",
    "proxy"
  ]
}' |
apify call epicscrapers/ebay-trading-card-comps --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,epicscrapers/ebay-trading-card-comps"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/QoYobwyIxIQqreyCb/builds/kwpW2Xel0aTJDswYR/openapi.json
