# eBay Sold Comps — Pricing Intelligence (`midwest_united/ebay-sold-comps`) Actor

Real eBay sold prices & comps — average, median, and recommended resale price across 8 marketplaces, with lot normalization and an A–D confidence score.

- **URL**: https://apify.com/midwest_united/ebay-sold-comps.md
- **Developed by:** [Jim Giganti](https://apify.com/midwest_united) (community)
- **Categories:** E-commerce, Automation
- **Features:** Limited permissions
- **Stats:** 38 total users, 2 monthly users, 94.6% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 comp record returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 Sold Comps — eBay Sold Prices & Sold Listings API

Look up **eBay sold prices** for any item. This actor searches **eBay sold listings** (completed/sold results) and returns **aggregated comp pricing** — average, median, and a recommended resale price — with statistical outlier fencing, lot normalization, and a data-quality **confidence score (A–D grade)**.

Get real **eBay sold prices** and **sold listing** comps for resellers, pawn shops, flippers, auction tools, and any pricing service that needs to know what items *actually sold for* on eBay — not what sellers are hoping to get.

***

### Why this actor is different

Most eBay sold scrapers return a raw dump of listings and leave the pricing math to you. This actor does the work before it hands you results:

| Feature | What it does |
|---|---|
| **Lot normalization** | Detects multi-item listings ("lot of 3", "bundle of 5", "2x") and divides to per-unit price before computing averages |
| **IQR outlier fencing** | Removes statistical outliers using interquartile range fencing — one $500 anomaly won't skew your $45 avg |
| **Confidence score (A–D)** | Every result includes a grade based on comp count, price spread, and recency so you know when to trust the number |
| **Recommended listing price** | A single suggested price — weighted blend of median (60%) and p75 (40%) — so you don't have to do the math yourself |
| **Relevance filtering** | Token-based scoring drops junk comps that technically matched the keyword but aren't the item |
| **Condition-adjusted pricing** | Optional breakdown of avg sold price by condition tier (new / used / refurbished / for_parts) |
| **8 eBay marketplaces** | US, UK, DE, FR, IT, ES, CA, AU — search regional sold data with a single input field |
| **Clean schema** | One camelCase field per data point — no duplicate aliases, no mixed casing |

***

### Pricing

This actor uses **Pay Per Event** pricing — you only pay for what you get back.

| Event | Cost | When charged |
|---|---|---|
| `comp-record-returned` | $0.02 / record | Per individual sold listing in the dataset |
| `pricing-report-generated` | $0.10 / run | Once per run when aggregated stats are produced |

**Example:** A typical run returning 25 comp records = 25 × $0.02 + $0.10 = **$0.60 total**.

There is no subscription, no minimum spend, and no charge for runs that return zero results.

***

### Input

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `searchQuery` | string | ✅ | — | What to search for. Be specific — include brand, model, size. |
| `maxResults` | integer | | 25 | Max comp records to return (1–100). |
| `condition` | string | | all | Filter by: `new`, `used`, `refurbished`, `for_parts`. |
| `eBaySite` | string | | `ebay.com` | Marketplace: `ebay.com`, `ebay.co.uk`, `ebay.de`, `ebay.fr`, `ebay.it`, `ebay.es`, `ebay.ca`, `ebay.com.au`. |
| `minPrice` | number | | — | Drop listings below this price (applied at eBay search level). |
| `maxPrice` | number | | — | Drop listings above this price (applied at eBay search level). |
| `daysBack` | integer | | — | Only include comps sold within this many days (1–90). |
| `knownBrands` | string\[] | | `[]` | Brand mismatch filter. Listings with a different brand from this list are dropped. |
| `excludedPhrases` | string\[] | | `[]` | Plain-text phrases — matching titles are dropped. |
| `excludedPatterns` | string\[] | | `[]` | Regex patterns (case-insensitive) — matching titles are dropped. |
| `includeConditionPricing` | boolean | | `false` | Add per-condition price breakdown to stats output. |
| `proxyConfiguration` | object | | Apify residential | Proxy used by the crawler. Residential is strongly recommended for eBay — datacenter IPs are blocked or challenged often. |

#### Example input

```json
{
    "searchQuery": "dewalt 20v drill driver",
    "maxResults": 25,
    "condition": "used",
    "eBaySite": "ebay.com",
    "minPrice": 15,
    "maxPrice": 150,
    "daysBack": 30,
    "knownBrands": ["dewalt", "milwaukee", "makita"],
    "excludedPhrases": ["case only", "charger only"],
    "includeConditionPricing": true
}
```

***

### Output

#### Comp records — default dataset

One record per sold listing:

```json
{
    "id": "145023948271",
    "title": "DeWalt 20V MAX Drill Driver DCD771 Bare Tool",
    "url": "https://www.ebay.com/itm/145023948271",
    "soldDate": "Dec 18, 2024",
    "soldPrice": 42.00,
    "shippingCost": 0,
    "totalPrice": 42.00,
    "isLot": false,
    "inferredLotSize": null,
    "normalizedPrice": 42.00,
    "normalizationMethod": "none",
    "normalizationConfidence": 1.0,
    "condition": "Used",
    "conditionTier": "used",
    "relevanceScore": 0.88,
    "primaryImageUrl": "https://i.ebayimg.com/images/g/.../s-l500.jpg",
    "thumbnailUrl": "https://i.ebayimg.com/images/g/.../s-l225.jpg",
    "detailPageFetched": true,
    "detailPageFailReason": null
}
```

#### Aggregated stats — key-value store key: `stats`

```json
{
    "searchQuery": "dewalt 20v drill driver",
    "condition": "used",
    "compCount": 18,
    "rawCandidateCount": 24,
    "price": {
        "avg": 47.82,
        "median": 44.50,
        "low": 28.00,
        "high": 89.00,
        "p25": 36.75,
        "p75": 58.00,
        "stdDev": 14.21
    },
    "recommendedPrice": 49.90,
    "confidence": {
        "score": 0.74,
        "grade": "B",
        "compCount": 18,
        "priceSpread": 0.61,
        "recencyDays": 22,
        "outliersRemoved": 2,
        "lotNormalizedCount": 1,
        "notes": []
    },
    "conditionPricing": {
        "new":         { "avg": 89.00, "count": 2 },
        "used":        { "avg": 43.50, "count": 14 },
        "refurbished": { "avg": 55.00, "count": 2 },
        "for_parts":   { "avg": null,  "count": 0 }
    },
    "dropped": {
        "byRelevance": 3,
        "byNegativePhrase": 1,
        "byNegativePattern": 0,
        "byBrandMismatch": 2,
        "byDaysBack": 0,
        "byMaxResultsCap": 0
    },
    "lot": {
        "detected": 2,
        "normalized": 1
    },
    "outliers": {
        "removed": 2,
        "prices": [4.99, 220.00],
        "fencingApplied": true
    },
    "runtime": {
        "totalSeconds": 18.4,
        "searchSeconds": 4.1,
        "detailSeconds": 14.3
    }
}
```

***

### Confidence grade guide

| Grade | Score | What it means |
|---|---|---|
| **A** | ≥ 0.85 | High comp count, tight price spread, recent sales — strong signal |
| **B** | ≥ 0.65 | Solid data with minor caveats |
| **C** | ≥ 0.45 | Limited comps or noisy spread — use with judgment |
| **D** | < 0.45 | Thin market, old data, or very wide spread — treat with caution |

The confidence score is a weighted blend of three sub-signals: comp count (40%), price spread (35%), and recency (25%).

***

### Use cases

- **Pawn shops** — instant comp price before making an offer
- **Resellers / flippers** — verify buy prices against real sold data
- **Auction software** — embed real-time eBay comp pricing into bidding tools
- **Estate sale pricing** — bulk item valuation from actual market data
- **Consignment shops** — set listing prices based on what's actually selling
- **Pricing APIs** — embed as a data source in your own resale or inventory platform

***

### Notes

- This actor scrapes publicly available eBay sold listing data. It is not affiliated with or endorsed by eBay Inc.
- You are responsible for complying with eBay's Terms of Service when using data retrieved by this actor.
- Detail page fetches are used only when the search result card does not include an image. Most runs require few or no detail page fetches, keeping runtime low.
- Lot normalization confidence is 1.0 when no lot is detected, 0.85 for successful size-inferred division, and 0.30 when a lot is detected but size cannot be inferred.

# Actor input Schema

## `searchQuery` (type: `string`):

What item do you want eBay sold prices for? Enter the product to look up in completed/sold listings. Be specific — include brand, model number, and size for accurate comps. Example: 'dewalt 20v drill driver DCD771'.

## `maxResults` (type: `integer`):

How many sold comp records should be returned? More records give better average/median pricing but take longer to run. Range 1–100, default 25.

## `condition` (type: `string`):

Do you want to filter sold listings by item condition? Choose New, Used, Refurbished, or For parts — or leave blank to include all conditions and read the per-condition price breakdown instead (recommended for most searches).

## `knownBrands` (type: `array`):

Which brands should be treated as the target brand? If your search query names one of these brands, sold listings whose title shows a different brand from this list are dropped. Leave empty to disable brand filtering. Example: \["dewalt", "milwaukee", "makita"].

## `excludedPhrases` (type: `array`):

Which title phrases should exclude a sold listing? Any completed listing whose title contains one of these case-insensitive phrases is removed before pricing. Example: \["case only", "charger only", "holster only"].

## `excludedPatterns` (type: `array`):

Which regex patterns should exclude a sold listing? Sold listings whose titles match any of these case-insensitive regular expressions are dropped. Example: \["\bfor parts\b", "\bnot working\b"].

## `includeConditionPricing` (type: `boolean`):

Do you want the average sold price broken down by condition? When enabled, the stats output adds a per-condition price breakdown (new / used / refurbished / for parts) — useful for pawn shops and resellers who price by condition.

## `eBaySite` (type: `string`):

Which eBay marketplace should be searched for sold prices? Defaults to eBay.com (US). Choose a regional site like eBay.co.uk for local sold comps in that country's currency.

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

What is the lowest sold price to include? Completed listings below this amount (in the marketplace's native currency) are filtered out at the eBay search level. Useful for removing parts, accessories, or junk comps.

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

What is the highest sold price to include? Completed listings above this amount (in the marketplace's native currency) are filtered out at the eBay search level. Useful for capping high-variance searches.

## `daysBack` (type: `integer`):

How recent should the sold listings be? Only include comps sold within this many days — for example, 30 returns only the last 30 days. Leave blank for all available history (eBay shows ~90 days of completed listings). Tighter windows improve the confidence score's recency signal.

## `proxyConfiguration` (type: `object`):

Which proxies should the scraper use? Residential is strongly recommended for eBay — datacenter IPs are blocked or challenged frequently. Defaults to Apify residential proxies.

## Actor input object example

```json
{
  "searchQuery": "dewalt 20v drill driver",
  "maxResults": 25,
  "condition": "",
  "knownBrands": [],
  "excludedPhrases": [],
  "excludedPatterns": [],
  "includeConditionPricing": false,
  "eBaySite": "ebay.com",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `compRecords` (type: `string`):

Individual sold listing records with normalized pricing, lot detection, condition, and relevance score.

## `stats` (type: `string`):

Aggregated pricing summary (avg/median/high/low/p25/p75/stdDev), confidence score (A-D grade), outlier metrics, lot normalization counts, filter telemetry, and runtime. Stored as 'stats' key in the default key-value store.

# 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 = {
    "searchQuery": "nintendo switch console",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("midwest_united/ebay-sold-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 = {
    "searchQuery": "nintendo switch console",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("midwest_united/ebay-sold-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 '{
  "searchQuery": "nintendo switch console",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call midwest_united/ebay-sold-comps --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,midwest_united/ebay-sold-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/AEZ9JRjnGRSkxYaWb/builds/vsAPMTStKFVEVKgJ6/openapi.json
