# eBay Sold Scraper · Price Analytics (`santamaria-automations/ebay-sold-scraper`) Actor

Scrape eBay sold listings for real transaction prices. Filter by date range and condition. Returns avg, median, and recommended price analytics per query. Supports 8 eBay marketplaces.

- **URL**: https://apify.com/santamaria-automations/ebay-sold-scraper.md
- **Developed by:** [NanoScrape](https://apify.com/santamaria-automations) (community)
- **Categories:** E-commerce
- **Stats:** 5 total users, 3 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## eBay Sold Listings Scraper

Scrape completed eBay sales for real transaction prices. For every query, the actor produces a summary record with avg price, median price, P10/P90 bands, and a recommended sell price. No post-processing needed.

Built for sellers, resellers, and pricing teams who need to answer one question quickly: what does this item actually sell for?

***

### What It Does

- Scrapes sold and completed listings from any eBay marketplace
- Outputs a per-query analytics record: avg, median, P10, P90, and recommended price
- Filters to items sold within a configurable window (up to 90 days)
- Accepts keyword queries and direct eBay sold-search URLs
- Captures condition, shipping cost, best-offer flag, and sale date per listing
- Runs multiple queries in one actor invocation

***

### Sample Output

```json
[
  {
    "recordType": "listing",
    "itemId": "325871204933",
    "title": "Vintage Rolex Oyster Perpetual Date Ref 1500 Steel 34mm Automatic Watch",
    "url": "https://www.ebay.com/itm/325871204933",
    "marketplace": "ebay.com",
    "soldPrice": 3850.00,
    "currency": "USD",
    "condition": "Pre-Owned",
    "soldDate": "2026-06-01T14:22:00.000Z",
    "shippingCost": 0.00,
    "freeShipping": true,
    "isBestOfferAccepted": false,
    "imageUrl": "https://i.ebayimg.com/images/g/abc123/s-l500.jpg",
    "searchQuery": "vintage rolex",
    "scrapedAt": "2026-06-13T09:15:00.000Z"
  },
  {
    "recordType": "analytics",
    "searchQuery": "vintage rolex",
    "marketplace": "ebay.com",
    "totalSalesFound": 94,
    "avgSoldPrice": 4812.50,
    "medianSoldPrice": 4650.00,
    "recommendedPrice": 4417.50,
    "priceLow": 1200.00,
    "priceHigh": 9800.00,
    "p10Price": 2100.00,
    "p90Price": 7400.00,
    "currency": "USD",
    "daysAnalyzed": 30,
    "scrapedAt": "2026-06-13T09:15:44.000Z"
  }
]
```

The dataset mixes `recordType: "listing"` rows with one `recordType: "analytics"` row per query at the end.

***

### Pricing

**$0.001 per actor start + $0.003 per listing record. About $3 per 1,000 listings.**

Analytics summary records aren't charged. You only pay for the listing rows.

**New to Apify?** Every account gets a $5 free monthly platform credit, enough for around 1,600 listing results on this actor before you commit to paying anything. Test extensively first.

***

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `searchQueries` | array of strings | — | Search terms. Each term produces its own result set and analytics record. |
| `startUrls` | array of `{url}` | — | Direct eBay sold-search URLs. Useful with pre-filtered category or condition constraints. |
| `marketplace` | string | `"ebay.com"` | eBay domain to scrape. See Supported Marketplaces below. |
| `maxResults` | integer | `100` | Maximum listing records per query. |
| `soldWithinDays` | integer | `30` | Only include items sold within this many days. Maximum is 90 (eBay's historical limit). |
| `condition` | array of strings | — | Filter by condition: `"new"`, `"used"`, `"refurbished"`, `"open_box"`, `"for_parts"`. |
| `sortBy` | string | `"best_match"` | Sort order for results. |
| `minPrice` | float | — | Minimum sold price filter. |
| `maxPrice` | float | — | Maximum sold price filter. |
| `categoryId` | string | — | eBay category ID to narrow results (e.g. `"9355"` for Cell Phones). |
| `includeAnalytics` | boolean | `true` | Appends one `recordType: "analytics"` record per query after its listings. |
| `concurrency` | integer | `5` | Parallel workers. Advanced: lower this for more conservative throughput. |

At least one of `searchQueries` or `startUrls` is required.

#### Example Input

```json
{
  "searchQueries": ["vintage rolex", "rolex submariner 16610"],
  "marketplace": "ebay.com",
  "maxResults": 100,
  "soldWithinDays": 30,
  "includeAnalytics": true
}
```

***

### Output Fields

#### Listing record fields

| Field | Type | Description |
|---|---|---|
| `recordType` | string | Always `"listing"`. |
| `itemId` | string | eBay item ID. |
| `title` | string | Full listing title. |
| `url` | string | Canonical eBay listing URL. |
| `marketplace` | string | eBay domain the listing was found on. |
| `soldPrice` | number | Final sold price. |
| `currency` | string | ISO 4217 currency code (e.g. `USD`, `GBP`, `EUR`). |
| `condition` | string | Condition label as listed (e.g. `Pre-Owned`, `New`). |
| `soldDate` | string | ISO 8601 timestamp of when the item sold. |
| `shippingCost` | number | Stated shipping cost. `0` when free. |
| `freeShipping` | boolean | `true` if the seller offered free shipping. |
| `isBestOfferAccepted` | boolean | `true` if the final price was the result of a Best Offer. |
| `imageUrl` | string | Primary listing image URL. |
| `searchQuery` | string | The query or URL that produced this result. |
| `scrapedAt` | string | ISO 8601 timestamp of when this record was collected. |

#### Analytics record fields

| Field | Type | Description |
|---|---|---|
| `recordType` | string | Always `"analytics"`. |
| `searchQuery` | string | The query this summary covers. |
| `marketplace` | string | eBay domain. |
| `totalSalesFound` | integer | Number of sold listings analysed. |
| `avgSoldPrice` | number | Arithmetic mean of all sold prices. |
| `medianSoldPrice` | number | Median sold price (50th percentile). |
| `recommendedPrice` | number | Suggested list price: 95% of median, giving a competitive edge over recent comps. |
| `priceLow` | number | Lowest sold price in the result set. |
| `priceHigh` | number | Highest sold price in the result set. |
| `p10Price` | number | 10th percentile price (bottom 10% of sales). |
| `p90Price` | number | 90th percentile price (top 10% of sales). |
| `currency` | string | ISO 4217 currency code. |
| `daysAnalyzed` | integer | The `soldWithinDays` window used for this run. |
| `scrapedAt` | string | ISO 8601 timestamp. |

***

### Use with AI Agents (MCP)

Connect this actor to any MCP-compatible AI client: Claude Desktop, Claude.ai, Cursor, VS Code, LangChain, LlamaIndex, or custom agents.

**Apify MCP server URL:**

`https://mcp.apify.com?tools=santamaria-automations/ebay-sold-scraper`

**Example prompt once connected:**

> "Use `ebay-sold-scraper` to analyse the last 30 days of 'vintage rolex' sales on ebay.com. Show me the median price, recommended selling price, and P10/P90 range."

Clients that support dynamic tool discovery (Claude.ai, VS Code) will receive the full input schema automatically.

***

### Why This Scraper

Built-in price analytics means you don't need to export to a spreadsheet to get avg and median. The `recommendedPrice` field (95% of median) gives you a competitive anchor price in the response. HTTP-only, 128MB RAM, no browser overhead.

***

### Common Use Cases

- **Reseller pricing**: Anchor your list price on real sold comps, not wishful asking prices
- **Inventory valuation**: Bulk-query a catalogue of SKUs and pull the median sold price for each
- **Trend analysis**: Schedule recurring runs and store the analytics records to track how median price shifts week over week
- **Arbitrage research**: Cross-reference `recommendedPrice` against supplier costs to surface margin-positive opportunities

***

### Supported Marketplaces

| Value | Marketplace |
|---|---|
| `ebay.com` | United States (default) |
| `ebay.co.uk` | United Kingdom |
| `ebay.de` | Germany |
| `ebay.fr` | France |
| `ebay.it` | Italy |
| `ebay.es` | Spain |
| `ebay.com.au` | Australia |
| `ebay.ca` | Canada |
| `ebay.at` | Austria |
| `ebay.nl` | Netherlands |

***

### Related Actors

- [eBay Product Scraper](https://apify.com/santamaria-automations/ebay-scraper): Scrapes active (unsold) eBay listings. Use it alongside this actor to compare asking prices against what items actually sell for.

***

### Support

For bugs, feature requests, or marketplaces not yet supported, open a ticket on the [Issues tab](https://apify.com/santamaria-automations/ebay-sold-scraper/issues). We typically respond within 24 hours.

Contact: contact@nanoscrape.com

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords to search on eBay sold listings (e.g. 'vintage rolex', 'iphone 15 pro'). Each keyword is scraped separately.

## `startUrls` (type: `array`):

eBay search or category page URLs to scrape directly. Overrides searchQueries if both provided.

## `marketplace` (type: `string`):

Which eBay regional site to scrape sold listings from. Each marketplace returns prices in the local currency.

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

Maximum total sold listings to return across all queries.

## `soldWithinDays` (type: `integer`):

Only include listings sold within this many days. eBay allows up to 90 days of history.

## `condition` (type: `array`):

Filter by item condition. Leave empty for all.

## `sortBy` (type: `string`):

Sort order for sold results.

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

Minimum sold price filter.

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

Maximum sold price filter.

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

eBay category ID to narrow results (e.g. '9355' for Cell Phones). Leave empty to search all categories.

## `includeAnalytics` (type: `boolean`):

Adds a summary record per query with avg price, median price, recommended price, and price range statistics. Distinguishable by recordType='analytics'.

## `concurrency` (type: `integer`):

Number of parallel requests. Increase for faster scraping of many queries.

## Actor input object example

```json
{
  "searchQueries": [
    "vintage camera"
  ],
  "marketplace": "ebay.com",
  "maxResults": 100,
  "soldWithinDays": 30,
  "sortBy": "best_match",
  "includeAnalytics": true,
  "concurrency": 5
}
```

# Actor output Schema

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

Dataset of scraped sold listings plus per-query analytics summaries. Listing rows contain soldPrice, soldDate, condition, and shippingCost. Analytics rows contain avgSoldPrice, medianSoldPrice, recommendedPrice, p10Price, and p90Price.

# 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 = {
    "searchQueries": [
        "vintage camera"
    ],
    "maxResults": 100,
    "soldWithinDays": 30,
    "concurrency": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("santamaria-automations/ebay-sold-scraper").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 = {
    "searchQueries": ["vintage camera"],
    "maxResults": 100,
    "soldWithinDays": 30,
    "concurrency": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("santamaria-automations/ebay-sold-scraper").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 '{
  "searchQueries": [
    "vintage camera"
  ],
  "maxResults": 100,
  "soldWithinDays": 30,
  "concurrency": 5
}' |
apify call santamaria-automations/ebay-sold-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,santamaria-automations/ebay-sold-scraper"
        }
    }
}

```

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/u6ao24maffAKV4lhj/builds/bw2BBcBlUaGRiqxrL/openapi.json
