# eBay Sold Listings API (`trawl/ebay-sold-listings-api`) Actor

Real eBay sold prices as JSON: search 400M+ completed sales on ebay.com and ebay.co.uk by keyword or category, with history past eBay's 90 days. Final price, sale date, condition, shipping, item id. No scraping, no login wall.

- **URL**: https://apify.com/trawl/ebay-sold-listings-api.md
- **Developed by:** [Colin Daniels](https://apify.com/trawl) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 sold listings

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

Real eBay sold prices as JSON, from a database of **400M+ completed sales** on ebay.com and ebay.co.uk. Type a keyword or a category id, get every matching sale newest first: **final price, sale date, condition, shipping, buying format, location, item id and link**. No scraping at run time, no eBay developer approval, no login wall, and history that reaches back **well past the 90 days eBay shows**.

Try it: leave the sample input as it is and press Start. The run finishes in seconds and the dataset shows what an iPhone 15 Pro 256GB actually sold for this week.

### What is the eBay Sold Listings API?

eBay retired `findCompletedItems` and the Finding API in February 2025, and its Marketplace Insights API is closed to new developers. The Browse API only returns listings that are still for sale. So there is no official way to ask eBay "what did this sell for?"

This Actor answers that question from [trawl](https://trawl.dev)'s database of completed eBay sales. trawl records sales on ebay.com and ebay.co.uk continuously and keeps them, so one request returns real sold listings with the fields a pricing tool needs, in a consistent JSON shape, with a sale from last spring as easy to get as one from today.

### What can you do with eBay sold listings data?

- **Price before you list.** The median and range of real completed sales for the exact item and condition.
- **Build comps into your own product.** A pricing app, a reseller dashboard, an estate-sale tool, a spreadsheet.
- **Track a market over time.** Filter by `dateFrom` and `dateTo` to compare months, including ones eBay no longer shows.
- **Research a whole category.** Set a category id with no keyword and get every sale in it.
- **Filter by item specifics.** Brand, storage capacity, card grade, size, colour: `Grade:PSA 10` returns only slabbed PSA 10 sales.
- **Feed an AI agent.** The Actor runs through Apify's API and MCP server like any other, so an agent can ask for comps in a tool call.

### How to search eBay sold listings

Fill in the input and start the run. Everything except the keyword or category is optional.

| Input | What it does |
|---|---|
| **Keyword** | Words that must all appear in the title, in any order. |
| **Marketplace** | eBay US (prices in USD) or eBay UK (prices in GBP). |
| **Max results** | How many sales to return, newest first. Up to 20,000 per run. |
| **Condition** | New, used, for parts, other. |
| **Exclude words** | Words that must not appear in the title (`case screen protector`). |
| **Category ID** | A numeric eBay leaf category. On its own, every sale in the category. |
| **Min / max sold price** | In the marketplace's currency. |
| **Sold from / to** | A date window, `YYYY-MM-DD`. |
| **Item specifics** | `Key:Value` lines, exact match: `Brand:Apple`, `Storage Capacity:256 GB`. |
| **Include full listing details** | Adds each listing page's item specifics, description, images, seller and returns, and the accepted Best Offer amount where eBay publishes it. |

A run that finds nothing costs nothing.

### Output: one sold listing per dataset item

```json
{
  "title": "Apple iPhone 15 Pro 256GB Unlocked",
  "sale_price": 525,
  "shipping_price": 0,
  "currency": "$",
  "condition": "used",
  "condition_raw": "Pre-Owned",
  "date_sold": "2026-07-18T00:00:00.000Z",
  "buying_format": "Buy It Now",
  "bids": null,
  "best_offer_available": true,
  "location": "United States",
  "item_id": "256637082114",
  "epid": "13051890211",
  "categoryId": "9355",
  "item_link": "https://www.ebay.com/itm/256637082114",
  "image_url": "https://i.ebayimg.com/images/g/abc/s-l500.webp",
  "site": "EBAY_US"
}
```

`sale_price` is the listed price, because that is what eBay's sold search shows. For Best Offer sales, turn on **Include full listing details** and read `details.sale_price` where `details.best_offer_accepted` is true; eBay publishes the accepted amount on Collectibles listings (trading cards, coins, comics). Download the dataset as JSON, CSV, Excel or XML from the run's Storage tab, or read it through the Apify API.

### How much does it cost to get eBay sold listings?

You pay per sold listing returned, nothing per run and nothing for a search that finds no matches.

| Event | Price |
|---|---|
| Sold listing | $2.50 per 1,000 |
| Sold listing with full details | $5.00 per 1,000 |

Apify's free plan includes $5 of monthly usage, which is 2,000 sold listings a month at no cost. Apify platform usage is included in the price; a 1,000-listing run finishes in a few seconds.

### Using the Actor from code

Python, with the [Apify client](https://docs.apify.com/api/client/python/):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("trawl/ebay-sold-listings-api").call(run_input={
    "keyword": "iphone 15 pro 256gb",
    "condition": ["used"],
    "maxResults": 300,
})
sales = list(client.dataset(run["defaultDatasetId"]).iterate_items())
prices = sorted(s["sale_price"] for s in sales)
print(len(prices), "sales, median", prices[len(prices) // 2])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('trawl/ebay-sold-listings-api').call({
  keyword: 'nintendo switch oled', marketplace: 'EBAY_GB', maxResults: 200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, 'sales, latest', items[0]);
```

Need the same data at higher volume, or straight from your backend without Apify in the middle? The same database is available as a plain HTTPS API with a free key at [trawl.dev](https://trawl.dev): one GET, up to 2,000 results a call, and `GET /item` for any listing's full page.

### eBay sold listings API vs scraping eBay yourself

| | This Actor | A scraper |
|---|---|---|
| Source | A database of completed sales, kept continuously | eBay's sold search page, fetched on each run |
| Login wall | Not affected | eBay now redirects sold searches to a sign-in page |
| History | Kept past eBay's 90-day window | What eBay shows: about 90 days |
| Speed | Seconds for thousands of sales | Minutes, and proxies to pay for |
| Breakage | None when eBay changes its HTML | Every time it does |
| Cost | Per listing returned | Per run, whether or not it finds anything |

### FAQ

#### Is this an official eBay API?

No. trawl is an independent service and is not affiliated with or endorsed by eBay Inc. The data is the public record of completed sales that eBay publishes on its sold-listings pages, collected and kept by trawl.

#### Which marketplaces are covered?

ebay.com (US) and ebay.co.uk (UK). Prices are in the marketplace's own currency and nothing is converted.

#### How far back does the history go?

Past the 90 days eBay shows. trawl keeps every sale it has recorded, so a date window on a month eBay no longer displays still returns the real sales from that month. Set `dateFrom` and `dateTo` to pick the range.

#### How fresh is the data?

New sales appear within minutes in busy categories and within the day in quieter ones.

#### Does it return the accepted Best Offer price?

The listed price is what eBay's sold search shows. With **Include full listing details** on, `details.sale_price` carries the accepted amount where eBay publishes it, which is Collectibles listings.

#### Can I filter by item specifics like card grade or storage size?

Yes: **Item specifics** takes `Key:Value` lines and matches exactly, case-insensitive. Only listings whose full page was read carry specifics, so results are a subset of a plain keyword search.

#### What replaces findCompletedItems?

This. The guide at [trawl.dev/guides/findcompleteditems-alternative](https://trawl.dev/guides/findcompleteditems-alternative) maps the old Finding API fields to this response one by one.

#### Is it legal to use eBay sold listings data?

The sold listings are information eBay publishes publicly. Use the data under your own jurisdiction's rules and eBay's terms for whatever you build; trawl's terms are at [trawl.dev/terms](https://trawl.dev/terms).

### Support

Something wrong, or a field you need that is not here? Open an issue on this Actor or write to the address on [trawl.dev/contact](https://trawl.dev/contact). Parser changes on eBay's side do not affect this Actor; the database behind it is maintained by the trawl team.

# Actor input Schema

## `keyword` (type: `string`):

Words that must ALL appear in the sold listing's title, in any order (up to 32 words). Leave empty to get every sale in a category.

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

ebay.com (prices in USD) or ebay.co.uk (prices in GBP).

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

How many sold listings to return at most, newest first. You are charged per listing actually returned, so a search with fewer matches costs less.

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

Only sales in these conditions. Leave empty for all.

## `exclude` (type: `string`):

Words that must NOT appear in the title (for example: case screen protector box). Up to 32 words, none of them in the keyword.

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

A numeric eBay leaf category id (for example 9355 for Cell Phones & Smartphones on ebay.com). Ids differ per marketplace. On its own, with no keyword, returns every sale in the category. Look ids up at https://trawl.dev/docs or with GET /categories.

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

Lowest final price to include, in USD on ebay.com or GBP on ebay.co.uk.

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

Highest final price to include, in the marketplace's currency.

## `dateFrom` (type: `string`):

Earliest sale date, inclusive, as YYYY-MM-DD. History reaches back well past eBay's own 90-day window.

## `dateTo` (type: `string`):

Latest sale date, inclusive, as YYYY-MM-DD.

## `attributes` (type: `array`):

Filter on item specifics as Key:Value, one per line, exact match, case-insensitive (Brand:Apple, Storage Capacity:256 GB, Grade:PSA 10). Different keys must all match; the same key twice matches either value. Up to 16. Only listings whose full details were read carry specifics.

## `includeDetails` (type: `boolean`):

Add a `details` object to every sale with the listing page's item specifics, description, all images, seller, shipping and returns, and the accepted Best Offer amount where eBay publishes it. Costs twice as much per listing and limits results to listings with details available.

## Actor input object example

```json
{
  "keyword": "iphone 15 pro 256gb",
  "marketplace": "EBAY_US",
  "maxResults": 100,
  "includeDetails": false
}
```

# Actor output Schema

## `soldListings` (type: `string`):

JSON array of completed eBay sales: title, sale_price, currency, condition, date_sold, buying_format, shipping_price, location, item_id, item_link, image_url, and details when requested.

# 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 = {
    "keyword": "iphone 15 pro 256gb"
};

// Run the Actor and wait for it to finish
const run = await client.actor("trawl/ebay-sold-listings-api").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 = { "keyword": "iphone 15 pro 256gb" }

# Run the Actor and wait for it to finish
run = client.actor("trawl/ebay-sold-listings-api").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 '{
  "keyword": "iphone 15 pro 256gb"
}' |
apify call trawl/ebay-sold-listings-api --silent --output-dataset

```

## MCP server setup

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

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/dgCs0DCTeokalp6IY/builds/KsMojkwFBROKf4AK4/openapi.json
