# eBay Search Scraper - Listings, Prices & Sellers (`scrapeworks/ebay-search-scraper`) Actor

Scrape eBay search results in bulk - get product titles, prices, condition, shipping, sellers, watchers and image URLs as clean JSON. No eBay API key needed. Pass many keywords or eBay search URLs per run, paginate deep, on any eBay marketplace.

- **URL**: https://apify.com/scrapeworks/ebay-search-scraper.md
- **Developed by:** [Nicolas van Arkens](https://apify.com/scrapeworks) (community)
- **Categories:** E-commerce, Lead generation
- **Features:** Limited permissions
- **Stats:** 106 total users, 41 monthly users, 77.1% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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?

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 Search Scraper — Listings, Prices, Conditions & Shipping

Scrape **eBay search results at scale** and get every listing as clean, structured
JSON — **no eBay API key, no developer account, no login required.** Just type
keywords (or paste eBay search URLs) and the actor returns titles, prices,
condition, shipping, watchers and image URLs, paginating deep automatically.

Built for **bulk**: pass a whole list of keywords or search URLs in a single run,
and set how many listings you want per query. Works on **any eBay marketplace**
(ebay.com, ebay.co.uk, ebay.de, ebay.com.au, ebay.ca and more).

### What you can do with it

- **Price research & repricing** — track what identical items sell for across thousands of listings.
- **Product & market research** — measure supply, price spread and demand (watchers) for a niche.
- **Reseller / arbitrage sourcing** — pull every "Buy It Now" under a price, with free shipping only.
- **Competitor & brand monitoring** — watch new listings for a brand or model, sorted newest-first.
- **Dropshipping / catalog building** — harvest titles, images and prices to seed a catalog.

### Input

| Field | Type | What it does |
|---|---|---|
| `searchTerms` | array of strings | Keywords to search. Each is searched and paginated separately. Add as many as you want. |
| `directUrls` | array of strings | Optional. Paste full eBay `/sch/i.html?...` search URLs (with your own filters/category). |
| `domain` | string | eBay marketplace: `ebay.com`, `ebay.co.uk`, `ebay.de`, `ebay.com.au`, `ebay.ca`, `ebay.fr`, `ebay.it`, `ebay.es`, `ebay.nl`, `ebay.ie`, `ebay.in`. |
| `maxResultsPerQuery` | integer | Max listings to return per keyword/URL (default 100). Paginates 240 per page. |
| `sortBy` | string | `best_match`, `ending_soonest`, `newly_listed`, `price_low`, `price_high`. |
| `conditionFilter` | string | `any`, `new`, `used`, `open_box`, `refurbished`. |
| `buyingFormat` | string | `any`, `buy_it_now`, `auction`. |
| `freeShippingOnly` | boolean | Only listings with free shipping. |
| `proxyConfiguration` | object | Proxy. **RESIDENTIAL Apify Proxy is strongly recommended** — eBay blocks datacenter IPs. |

#### Example input

```json
{
  "searchTerms": ["mechanical keyboard", "vintage rolex"],
  "domain": "ebay.com",
  "maxResultsPerQuery": 200,
  "sortBy": "best_match",
  "conditionFilter": "any",
  "buyingFormat": "any",
  "freeShippingOnly": false,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

### Output

Each listing is one dataset row:

| Field | Description |
|---|---|
| `listingId` | eBay item number. |
| `title` | Listing title. |
| `url` | Canonical listing URL (`/itm/<id>`). |
| `condition` | New, Pre-Owned, Open box, Refurbished, etc. |
| `subtitle` | Item aspects eBay shows under the condition (e.g. material), when present. |
| `price` | Price text as shown (single price or a range). |
| `priceValue` | Numeric low price. |
| `priceMax` | Numeric high price (for ranges; otherwise null). |
| `currency` | Currency symbol/code of the marketplace. |
| `buyingFormat` | "Buy It Now", "or Best Offer", or auction. |
| `bids` | Bid count for auctions. |
| `shipping` | Shipping/delivery text. |
| `watchers` | Number of watchers, when shown. |
| `sold` | Units sold, when shown. |
| `image` | Thumbnail image URL. |
| `searchTerm` | The keyword/URL that produced this row. |
| `domain` | Marketplace scraped. |
| `scrapedAt` | UTC timestamp. |

#### Example output row

```json
{
  "listingId": "335537700823",
  "title": "LEGO® Star Wars 75394 Imperial Star Destroyer EXCLUSIVE! NEW!",
  "url": "https://www.ebay.com/itm/335537700823",
  "condition": "Brand New",
  "subtitle": null,
  "price": "$189.99",
  "priceValue": 189.99,
  "priceMax": null,
  "currency": "$",
  "buyingFormat": "Buy It Now",
  "bids": null,
  "shipping": "+$17.90 shipping",
  "watchers": null,
  "sold": 1056,
  "image": "https://i.ebayimg.com/images/g/r40AAeSwTDxqIwjn/s-l500.jpg",
  "searchTerm": "lego star wars",
  "domain": "ebay.com",
  "scrapedAt": "2026-07-17T10:22:35Z"
}
```

> Prices come back in the **marketplace's local currency**. eBay converts displayed
> prices to the currency of the country your IP is in, so with a RESIDENTIAL proxy
> the actor automatically pins the proxy exit country to the marketplace's home
> country (US for `ebay.com` → USD, GB for `ebay.co.uk` → GBP, ...). Set
> `apifyProxyCountry` yourself to override. On non-English marketplaces the text fields come
> back **in that marketplace's language** (e.g. `buyingFormat: "Sofort-Kaufen"`,
> `shipping: "+EUR 25,00 Lieferung"` on ebay.de) — `priceValue`/`priceMax` are
> always clean numbers regardless of locale. `bids`, `watchers` and `sold` are
> populated when eBay shows them on the results page — for most fixed-price
> listings eBay omits watchers/bids there, so they are often null (that's eBay,
> not missing data). `subtitle` only appears when a listing has extra aspect text.

### Pricing

This actor is **pay per result**: you are charged **$0.001 per listing** returned
to your dataset. Blocked or empty pages are never charged — you only pay for real
rows. A 1,000-listing run costs about **$1.00** plus Apify proxy/compute usage.

### Tips

- Use **RESIDENTIAL** proxy groups. eBay blocks datacenter traffic; residential is the reliable path.
- To use eBay's own advanced filters (price range, category, location), build the search on eBay, copy the URL, and drop it into `directUrls`.
- `maxResultsPerQuery` paginates automatically; eBay itself caps a single search at a few thousand results.

### FAQ

**Do I need an eBay API key or account?** No. The actor reads eBay's public search pages.

**Why residential proxy?** eBay aggressively blocks datacenter IPs. The actor bootstraps
session cookies and rotates proxy sessions on blocks, but residential IPs are what keep it reliable.

**Can I scrape multiple keywords at once?** Yes — that's the point. Pass a list in
`searchTerms`; each is paginated independently, and every row records which `searchTerm` it came from.

**Which marketplaces are supported?** ebay.com, ebay.co.uk, ebay.de, ebay.com.au,
ebay.ca, ebay.fr, ebay.it, ebay.es, ebay.nl, ebay.ie and ebay.in.

**Is this legal?** It reads publicly available, non-logged-in search pages. You are
responsible for complying with eBay's terms and applicable law in your use of the data.

# Actor input Schema

## `searchTerms` (type: `array`):

One or more keywords/phrases to search on eBay (e.g. 'mechanical keyboard', 'vintage rolex'). Each term is searched separately and paginated deep up to 'Max results per query'. Add as many as you like in a single run.

## `directUrls` (type: `array`):

Optional: paste full eBay search-results URLs (e.g. an /sch/i.html?... link with your own filters, category or price range already applied). Each URL is scraped and paginated just like a keyword. Use this when you want eBay's own advanced filters; otherwise just use 'Search keywords'.

## `domain` (type: `string`):

Which eBay site to search. Prices are returned in that site's local currency. Most-used is ebay.com (US).

## `maxResultsPerQuery` (type: `integer`):

Maximum listings to return for EACH keyword/URL. The actor paginates automatically (240 listings per page). eBay itself caps a single search at a few thousand results.

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

Result order, same as eBay's own sort dropdown.

## `conditionFilter` (type: `string`):

Only return listings of this condition. 'Any' returns everything.

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

Restrict to a buying format. 'Any' returns both fixed-price and auction listings.

## `freeShippingOnly` (type: `boolean`):

If on, only return listings that offer free shipping.

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

Proxy used to reach eBay. eBay blocks datacenter traffic, so RESIDENTIAL Apify Proxy is strongly recommended for reliable results. With RESIDENTIAL, the proxy country is automatically matched to the chosen marketplace (US for ebay.com etc.) so prices come back in the site's local currency — pick a country yourself to override.

## Actor input object example

```json
{
  "searchTerms": [
    "mechanical keyboard"
  ],
  "domain": "ebay.com",
  "maxResultsPerQuery": 100,
  "sortBy": "best_match",
  "conditionFilter": "any",
  "buyingFormat": "any",
  "freeShippingOnly": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "searchTerms": [
        "mechanical keyboard"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapeworks/ebay-search-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 = {
    "searchTerms": ["mechanical keyboard"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapeworks/ebay-search-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 '{
  "searchTerms": [
    "mechanical keyboard"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call scrapeworks/ebay-search-scraper --silent --output-dataset

```

## MCP server setup

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