# eBay Listings Scraper — with seller name, feedback & sold count (`henrycrawl/ebay-listings-scraper`) Actor

Scrape eBay search, category and filtered listing pages. Returns the seller username, feedback percent and feedback count that other eBay scrapers leave empty, prices parsed into numbers with currency, and a maxListings hard cap so you never get a surprise bill.

- **URL**: https://apify.com/henrycrawl/ebay-listings-scraper.md
- **Developed by:** [Henry Crawl](https://apify.com/henrycrawl) (community)
- **Categories:** E-commerce, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 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/platform/actors/running/actors-in-store#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 Listings Scraper — with seller identity and parsed prices

Scrape eBay search results, category pages and any filtered listing URL. Every row
comes back with the **seller username, seller feedback percentage and feedback
count**, prices already parsed into numbers with a currency code, and a hard cap on
how many listings a run may return.

### What you get per listing

| Field | Example | Notes |
|---|---|---|
| `itemId` | `197740124597` | Stable eBay id, use it to deduplicate across runs |
| `title` | `YETI Rambler 20 oz Tumbler…` | |
| `priceRaw` | `$35.00` | Exactly as eBay rendered it |
| `priceValue` | `35` | Parsed number, ready to filter and aggregate |
| `priceMax` | `48.5` | Filled when the listing shows a price range |
| `currency` | `USD` | Derived from the rendered price |
| `condition` | `Brand New` | |
| `sellerName` | `oliviabrian1234` | |
| `sellerFeedbackPercent` | `100` | |
| `sellerFeedbackCount` | `489` | `6K` and `94.2K` are expanded to real numbers |
| `soldCount` | `461` | Present on the listings where eBay shows it |
| `watchers` | `60` | |
| `bidCount` | `3` | Auctions only |
| `shippingRaw` | `+$28.60 delivery` | |
| `shippingValue` | `28.6` | `0` when shipping is free |
| `freeShipping` | `false` | |
| `itemLocation` | `United States` | Where the item ships from |
| `imageUrl`, `itemUrl` | | |
| `pageNumber`, `searchKeyword`, `inputUrl` | | Provenance of every row |
| `ebaySite`, `proxyCountry`, `scrapedAt` | | The exact context the data was captured in |

### Two ways to search

**1. Build a search from filters** — no URL needed. Add one or more keywords; each
runs as its own search with the same filters:

```json
{
  "keywords": ["yeti rambler 20 oz tumbler", "stanley quencher 40 oz"],
  "ebaySite": "www.ebay.com",
  "proxyCountry": "US",
  "condition": "new",
  "buyingFormat": "buy_it_now",
  "minPrice": 20,
  "maxPrice": 60,
  "sortBy": "price_lowest",
  "maxListings": 2000
}
```

**2. Paste URLs** — any eBay search, category or filtered listing page:

```json
{
  "startUrls": [
    "https://www.ebay.com/sch/i.html?_nkw=yeti+rambler&LH_Sold=1&LH_Complete=1"
  ],
  "proxyCountry": "US",
  "maxListings": 500
}
```

Filters available: eBay site, keyword exclusions, category, min/max price, condition,
buying format, free shipping, **sold items**, **completed items**, and the same sort
options as eBay's own dropdown.

### Sold and completed listings

Set `soldItems` or `completedItems` to scrape prices items actually sold at, rather
than what sellers are asking. eBay's public API does not expose this, which makes it
the most useful signal here for pricing, resale and market research.

### Proxy country matters more than you would expect

eBay localises listing pages: **prices, currency, shipping costs, and even which
listings appear depend on the country of the IP making the request.** Requesting
`www.ebay.com` from outside the US can return prices in a different currency
entirely. Set `proxyCountry` to the market you care about — it defaults to `US`.

`ebaySite` and `proxyCountry` are independent: `ebaySite` picks which regional eBay
to load, `proxyCountry` decides which market you appear to be shopping from.

Residential proxies are used by default. eBay refuses datacenter IP ranges, so a
datacenter group will simply produce a failed run.

### The result cap is real

`maxListings` stops the run at exactly that number. Scrapers that treat their limits
as suggestions produce surprise bills; this one exits as soon as the cap is met, and
also stops on its own if three consecutive pages return nothing usable.

### Runs fail loudly, not silently

Every run writes a `DIAGNOSTICS` record to the key-value store with the block rate,
bytes per item, and the fill rate of every single output field:

```json
{
  "itemsExtracted": 200,
  "blockRate": "0%",
  "mbPer1000Items": 19.06,
  "fieldCoverage": { "priceValue": "100%", "sellerName": "92%", "currency": "100%" }
}
```

If nothing was extracted, or more than half the pages were blocked, the run is marked
**failed** with the reason. A dataset full of empty columns is worse than an error,
because the problem only shows up after you have used the data.

### Typical uses

- Competitor and marketplace price monitoring, with the seller behind each price
- Resale and arbitrage research on sold listings
- Tracking which sellers list a given brand, and at what price
- Building product and pricing datasets for internal tools or dashboards

### Notes and limits

- `soldCount` and `watchers` appear only on the listings where eBay displays them;
  they are reported as `null` elsewhere rather than guessed.
- eBay places a promotional label in the footer of every result card, organic ones
  included, so this actor does not claim to separate promoted listings from organic
  ones. It does drop the "Shop on eBay" placeholder cards, which carry no data.
- Keep `maxConcurrency` low. eBay authorises by session, so parallelism burns
  sessions faster than it saves time.

### Support

Found a field that stopped filling, or need a filter that is not exposed yet? Open an
issue on the actor page with the input you used — layout changes on eBay are normal
and get fixed.

# Actor input Schema

## `keywords` (type: `array`):

Each keyword runs as its own search using the filters below. Leave empty if you paste URLs instead.

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

Paste eBay search, category or filtered listing URLs. Scraped in addition to any keywords.

## `ebaySite` (type: `string`):

Which regional eBay to search. Independent from Proxy country.

## `proxyCountry` (type: `string`):

eBay localizes prices, currency, shipping costs and even which listings appear, based on the IP's country. Requesting ebay.com from outside the US can return a different currency entirely. Set this to the market you actually care about.

## `maxListings` (type: `integer`):

The run stops at exactly this many listings. Enforced, not a suggestion, so you cannot be billed for more rows than you asked for. Default is deliberately small so a first run is cheap and fast; raise it for real harvests.

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

Same sort options as eBay's own dropdown.

## `soldItems` (type: `boolean`):

Sold listings are the closest thing to real market prices. eBay's public API does not expose this data.

## `completedItems` (type: `boolean`):

Include only auctions and listings that have ended, sold or not.

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

Filter by item condition, same values eBay offers.

## `buyingFormat` (type: `string`):

Restrict to Buy It Now or auction listings only.

## `minPrice` (type: `integer`):

Lowest price to include, in the currency of the selected eBay site.

## `maxPrice` (type: `integer`):

Highest price to include, in the currency of the selected eBay site.

## `freeShipping` (type: `boolean`):

Only listings that ship for free.

## `excludeWords` (type: `string`):

Comma or space separated. Applied as eBay negative keywords.

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

Optional. Narrows the search to one eBay category.

## `excludeSponsored` (type: `boolean`):

Removes eBay's 'Shop on eBay' promo cards, which carry no real listing data. Note: eBay puts a reversed 'Sponsored' string in every card footer, so it cannot be used to tell ads from real listings, and this option does not claim to filter promoted listings.

## `itemsPerPage` (type: `integer`):

eBay supports 60, 120 or 240. Use 240: about 4x fewer requests per 1,000 rows, so lower proxy cost. Lower it only if you hit blocks.

## `maxConcurrency` (type: `integer`):

Keep this low. eBay gates access by session, so hammering it burns sessions faster than it saves time.

## `debugRawText` (type: `boolean`):

Adds the raw text of each result card to the output. Useful when a field stops filling and you want to see what eBay changed.

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

Defaults to Apify residential proxy in the selected country. eBay refuses datacenter IP ranges, so a datacenter group will produce a failed run.

## Actor input object example

```json
{
  "keywords": [
    "yeti rambler 20 oz tumbler"
  ],
  "startUrls": [],
  "ebaySite": "www.ebay.com",
  "proxyCountry": "US",
  "maxListings": 100,
  "sortBy": "best_match",
  "soldItems": false,
  "completedItems": false,
  "condition": "any",
  "buyingFormat": "any",
  "freeShipping": false,
  "excludeSponsored": true,
  "itemsPerPage": 240,
  "maxConcurrency": 2,
  "debugRawText": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `listings` (type: `string`):

One row per eBay listing: title, parsed price and currency, condition, seller username with feedback percent and count, sold count, shipping, item location, image and listing URL.

## `diagnostics` (type: `string`):

Block rate, pages processed, bytes per item and the fill rate of every output field for this run. Use it to verify the dataset is complete before relying on it.

# 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 = {
    "keywords": [
        "yeti rambler 20 oz tumbler"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("henrycrawl/ebay-listings-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 = { "keywords": ["yeti rambler 20 oz tumbler"] }

# Run the Actor and wait for it to finish
run = client.actor("henrycrawl/ebay-listings-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "keywords": [
    "yeti rambler 20 oz tumbler"
  ]
}' |
apify call henrycrawl/ebay-listings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=henrycrawl/ebay-listings-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/oqbTbbsFbbEVb7aR7/builds/9DlVkZ2BBntulrxtl/openapi.json
