# 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
- **Stats:** 24 total users, 4 monthly users, 97.9% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.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 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
