# eBay Scraper — Listings, Prices & Sellers (`tortuga/ebay-scraper`) Actor

Scrape eBay search results on ebay.com, ebay.co.uk, ebay.de and more: price, shipping, condition, auction bids and time left, sold count, seller feedback; optional item specifics.

- **URL**: https://apify.com/tortuga/ebay-scraper.md
- **Developed by:** [Trevor Ortega](https://apify.com/tortuga) (community)
- **Categories:** E-commerce
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 listing scrapeds

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 Scraper — Listings, Prices & Sellers

Scrape eBay search results from ebay.com, ebay.co.uk, ebay.de, ebay.com.au, ebay.at and ebay.ie into a clean dataset: title, price and currency, strike-through and coupon price, shipping cost, condition, buying format (auction, Buy It Now, Best Offer), bids and time left, sold count, watchers, item location, seller username, feedback score and positive percentage, image and item URL. Turn on item details for item specifics (brand, model, MPN, EAN / UPC and every other attribute), quantity available and sold, watch count, start and end date, shipping service and delivery estimate, return policy, categories and all images.

No login, no browser and no Unblocker fees: one request returns up to 240 listings. Download the results as JSON, CSV or Excel, or pull them through the API into your own app, Google Sheets or a repricing / arbitrage pipeline. You pay per listing you get.

### What data does eBay Scraper extract?

Every listing from a search page (the `result` event):

| Field | Description |
|---|---|
| `itemId`, `url` | eBay item number and item URL on the marketplace you searched |
| `title`, `subtitle` | Listing title; the attribute line eBay prints under it (platform, model, or the seller's subtitle) |
| `price`, `priceMax`, `currency` | Price (lowest variation price for multi-variation listings), highest variation price, ISO currency |
| `originalPrice`, `couponPrice`, `unitPrice` | Strike-through "was" price, price with the seller's coupon, unit price text (`EUR 0,50/1 Stk.`) |
| `condition`, `sellerType` | Condition as shown (`Pre-Owned`, `Brand New`, `Very Good - Refurbished`, `Gebraucht`); on ebay.de also `Gewerblich` / `Privat` |
| `buyingFormat`, `bestOfferAccepted` | `AUCTION`, `BUY_IT_NOW` or `AUCTION_WITH_BUY_IT_NOW`; whether the seller accepts offers |
| `bids`, `timeLeft`, `endTimeText` | Auctions: number of bids, time left (`23m left`, `2d 4h left`, `9 T 18 Std`) and end time as shown (`Today 04:45 PM`) |
| `shippingCost`, `freeShipping`, `shippingText`, `deliveryEstimate` | Shipping fee (0 for free shipping), the delivery line (`+$12.97 delivery`, `Free delivery in 2-3 days`), "Get it by" date |
| `itemLocation` | Country / region the item ships from, when eBay shows it (`United States`, `China`, `Polen`) |
| `freeReturns` | `true` when the card says "Free returns" |
| `soldCount`, `soldText` | Units sold for multi-quantity listings (`366+ sold`) |
| `watchers`, `availabilityText` | Watcher count; stock hints such as `Last one`, `Almost gone` |
| `sellerUsername`, `sellerFeedbackScore`, `sellerFeedbackScoreText`, `sellerPositivePercent`, `topRatedSeller` | Seller's public eBay username, feedback score (eBay rounds large ones on search pages: `41.7K`; the exact number comes with details), positive feedback %, Top Rated badge. ebay.de search pages do not print the seller; turn on details to get it |
| `badges`, `promotions`, `otherInfo` | `eBay Refurbished`, `Authenticity Guarantee`, `LEGO Authorised seller`...; multi-buy discounts; any other line on the card (`Click & Collect`, `Includes import fees`) |
| `image`, `epid`, `newListing`, `listedTimeText` | Main image (1600 px), eBay catalog product id when the listing is linked to one, "New listing" flag, listing time (with "Newly listed" sort) |
| `position`, `page`, `totalResults` | Rank in the search results, result page, total results eBay reports for the search |
| `partialMatch` | `true` for eBay's "No exact matches found" suggestions (only saved with **Include partial matches** on) |
| `searchTerm`, `marketplace`, `sourceUrl`, `scrapedAt` | Provenance |
| `changeType`, `previousValues` | Only with **Only new or changed items** on: `new` or `changed`, and for changed listings the old values of the fields that changed |

With **Include item details** on, or for item URLs (the extra `detail` event), each listing also gets:

| Field | Description |
|---|---|
| `itemSpecifics` | Every item specific as a dict: `{"Brand": "Apple", "Model": "Apple iPhone 13", "Storage Capacity": "128 GB", "Seller Notes": "...", ...}` |
| `brand`, `model`, `mpn`, `gtin` | Identifiers (EAN / UPC in `gtin`), `null` when the seller did not give them |
| `listPrice`, `priceText`, `approxPriceText`, `priceDiscountText` | List / was price, price as shown (`US $239.00`), converted price on foreign listings (`Approximately £239.75`), discount line |
| `conditionType`, `availability` | `New` / `Used` / `Refurbished`; `InStock` / `OutOfStock` |
| `quantityAvailable`, `quantityAvailableMoreThan`, `quantitySold`, `quantityText` | `7 available / 340 sold`; "More than 10 available" gives 10 and `true` |
| `watchCount`, `activitySignal` | Watchers; eBay's activity line (`In 187 carts`, `45 viewed today`) |
| `currentBid`, `hasReservePrice`, `startDate`, `endDate`, `listingStatus` | Auction details and the listing's start / end time (ISO), `ACTIVE` / `ENDED` |
| `sellerFeedbackScore`, `sellerPositivePercent`, `sellerItemsSold`, `sellerMemberSince`, `businessSeller`, `sellerStoreUrl` | Exact feedback score, positive %, items sold, member since, business seller flag, eBay Store link |
| `itemLocation`, `shippingDetailText`, `shippingDestination`, `deliveryText` | Item location city / region / country, shipping service and price for the visitor's country, delivery estimate |
| `returnsAccepted`, `returnDays`, `freeReturns`, `returnsText` | Return policy (`60 days returns. Seller pays for return shipping`) |
| `categories`, `images` | Category path and every listing image |

### How to use eBay Scraper

1. Type one or more **Search terms** and pick the **Marketplace** (ebay.com, ebay.co.uk, ebay.de, ...), and/or paste **Start URLs**: search pages with any filters you set on eBay, or item pages (`/itm/...`).
2. Optionally set **Sort by**, **Buying format** (auction / Buy It Now / accepts offers), **Condition**, **Min / Max price** or a **Category ID**.
3. Set **Max items** to cap the run (and the cost).
4. Turn on **Include item details** only if you need item specifics, quantity sold or the return policy: it opens one more page per listing and costs a little extra. For large detail runs pick **Residential** proxies (see below).
5. Click **Start**. Results appear in the **Dataset** tab; export from there or use the API.

### Input example

```json
{
  "searchTerms": ["nintendo switch", "steam deck"],
  "marketplace": "com",
  "startUrls": [
    { "url": "https://www.ebay.co.uk/sch/i.html?_nkw=lego&LH_BIN=1&_udlo=20&_udhi=40" },
    { "url": "https://www.ebay.com/itm/134353979702" }
  ],
  "maxItems": 500,
  "maxPagesPerSearch": 5,
  "sort": "newly_listed",
  "listingType": "all",
  "condition": "used",
  "minPrice": 50,
  "maxPrice": 300,
  "includeDetails": false,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

### Output example

A listing from an ebay.com search page:

```json
{
  "itemId": "336658132752",
  "title": "New Nintendo Switch 2 Handheld Console System with Mario Kart World Bundle",
  "url": "https://www.ebay.com/itm/336658132752",
  "price": 598.49,
  "priceMax": null,
  "currency": "USD",
  "originalPrice": 629.99,
  "couponPrice": null,
  "unitPrice": null,
  "condition": "Open Box",
  "subtitle": "Nintendo Switch · Nintendo Switch",
  "sellerType": null,
  "buyingFormat": "BUY_IT_NOW",
  "bestOfferAccepted": false,
  "bids": null,
  "timeLeft": null,
  "endTimeText": null,
  "shippingCost": 19.99,
  "freeShipping": false,
  "shippingText": "+$19.99 delivery",
  "deliveryEstimate": null,
  "itemLocation": "United States",
  "freeReturns": null,
  "soldCount": null,
  "soldText": null,
  "watchers": 48,
  "availabilityText": "Last one",
  "sellerUsername": "cocosprinkles",
  "sellerFeedbackScore": 41700,
  "sellerFeedbackScoreText": "41.7K",
  "sellerPositivePercent": 99.8,
  "topRatedSeller": false,
  "badges": [],
  "promotions": [],
  "otherInfo": [],
  "image": "https://i.ebayimg.com/images/g/BK4AAeSwEeNp4Rtw/s-l1600.webp",
  "epid": null,
  "newListing": false,
  "listedTimeText": null,
  "position": 1,
  "page": 1,
  "searchTerm": "nintendo switch",
  "marketplace": "ebay.com",
  "sourceUrl": null,
  "totalResults": 32000,
  "scrapedAt": "2026-10-06T22:20:11+00:00",
  "detailFetched": false
}
```

An auction listing with `includeDetails: true` additionally carries, for example:

```json
{
  "buyingFormat": "AUCTION",
  "bids": 1,
  "currentBid": 100,
  "hasReservePrice": false,
  "timeLeft": "Ends in 21m",
  "startDate": "2026-09-29T23:45:47.000Z",
  "endDate": "2026-10-06T23:45:47.000Z",
  "listingStatus": "ACTIVE",
  "conditionType": "Used",
  "watchCount": 5,
  "activitySignal": "45 viewed today",
  "sellerUsername": "micksamson27",
  "sellerFeedbackScore": 157,
  "sellerItemsSold": 124,
  "sellerMemberSince": "Dec 2002",
  "itemLocation": "Andover, Connecticut, United States",
  "shippingDetailText": "US $12.97 USPS Ground Advantage ®",
  "deliveryText": "Estimated between Fri, Oct 9 and Thu, Oct 15 to 90011",
  "returnsAccepted": false,
  "returnsText": "Seller does not accept returns",
  "itemSpecifics": {
    "Condition": "Used: An item that has been used previously. The item may have some signs of cosmetic wear, but is ...",
    "Brand": "Nintendo",
    "Type": "Handheld System",
    "Platform": "Nintendo Switch",
    "Color": "Red, Blue",
    "Model": "Nintendo Switch",
    "Connectivity": "HDMI, USB-A"
  },
  "brand": "Nintendo",
  "model": "Nintendo Switch",
  "categories": ["Electronics", "Video Games & Consoles", "Video Game Consoles"],
  "images": ["https://i.ebayimg.com/images/g/QOUAAeSwLyRqvEzm/s-l1600.jpg", "..."],
  "detailFetched": true
}
```

### How much does it cost to scrape eBay?

Pay per result: `result` per listing saved, plus `detail` per listing whose item page was opened (see the Pricing tab). Platform usage is small: a search page of 240 listings takes a few seconds, so 1,000 listings use roughly $0.005-0.01 of compute on Apify's datacenter proxy. Set **Max items** to cap a run; the Actor stops opening pages as soon as the cap is reached and only opens item pages for listings it can still save.

### Can I scrape eBay sold and completed listings?

No. Since 22 July 2026 eBay only shows sold and completed listings (`LH_Sold=1`, `LH_Complete=1`) to signed-in members; logged-out visitors are redirected to the sign-in page on every marketplace. This Actor does not log in, so such URLs are skipped and listed in the run summary (`soldUrlsSkipped`). For resale research it still gives you live asking prices, the units already sold on multi-quantity listings (`soldCount`, `quantitySold`), watchers and bid counts.

### How many results can I get per search?

eBay serves at most about 10,000 listings per search (42 pages of 240). For more, split the search by category (`categoryId`), condition, buying format or price range (`minPrice` / `maxPrice`) and run several searches.

### Does it work without login or an eBay API key? Which proxy should I use?

Yes. The Actor reads eBay's public search and item pages, the same pages any visitor sees, and needs no eBay account or developer keys. eBay sometimes answers automated traffic with a "Pardon our interruption" check; the Actor then retries with a different browser fingerprint and IP, and reports the number of such pages in the run summary. The default Apify datacenter proxy is enough for search pages (one request per 240 listings). Item pages are checked harder: on datacenter IPs about half of the item-page requests on ebay.com need a retry and a few can fail after 9 tries (they keep their search data and get a `detailError`), while Residential proxies loaded 98% of item pages on the first try in our tests. Residential traffic is billed per GB by Apify (about 170 KB per item page).

### Why do shipping prices differ on ebay.de or ebay.co.uk?

Search pages show the marketplace's own delivery line (`+EUR 2,10 Lieferung`, `+£4.90 delivery`). Item pages compute shipping for the visitor's country, which is the proxy's country (usually the US), so with details on the item page's line is saved separately in `shippingDetailText` (for example "May not post to United States"). Use a proxy in the marketplace's country if you need the item-page shipping for that country.

### Monitor changes on a schedule

Turn on **Only new or changed items** and the Actor remembers what earlier runs of the same search returned: each run outputs only listings that are new or whose price, price range, struck-through original price or stock hint ("Last one") changed (shipping is not compared: eBay calculates it for the visitor's location, so it varies from run to run). Unchanged listings are dropped before anything is saved or any item page is opened, so they are not charged. Save the input as a task (for example "newly listed" sort, **Max items** 100: the newest 100 listings are checked each run), then add a Schedule to it in Apify Console (Schedules → Create new, daily or hourly). Every output listing carries `changeType` (`new` or `changed`), and changed ones carry `previousValues`, e.g. `{"price": 249.99}` for a listing that dropped to 229.99. Use **Monitoring key** to keep several schedules on the same search separate.

### Legal and data notes

The Actor collects only what eBay shows publicly to any logged-out visitor: listings, prices and the public seller username and feedback numbers. It does not log in, does not access members-only pages (such as sold listings), and does not collect buyer data. You are responsible for using the data in line with eBay's terms and the laws that apply to you (for example GDPR when you process sellers' usernames).

# Actor input Schema

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

Keywords to search on eBay, one per line (e.g. "nintendo switch", "rolex submariner"). Each term is searched separately on the chosen marketplace and paginated automatically (240 listings per page).

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

eBay site to search for the search terms. Prices come in the site's currency. Start URLs always use the site in the URL.

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

eBay URLs to scrape instead of (or in addition to) search terms: search result pages with any filters you set on eBay (https://www.ebay.com/sch/i.html?\_nkw=lego\&LH_BIN=1) or single item pages (https://www.ebay.com/itm/134353979702, returned with full details). Sold / completed searches (LH_Sold=1) need an eBay login since July 2026 and are skipped.

## `maxItems` (type: `integer`):

Stop after this many listings in total (across all search terms and URLs). Keeps cost predictable.

## `maxPagesPerSearch` (type: `integer`):

How many result pages to open per search term or search URL (240 listings each). eBay shows at most about 10,000 listings per search (42 pages); split big searches by category or price range to go deeper.

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

Also open every listing's item page for item specifics (brand, model, MPN, EAN/UPC and all other attributes), exact seller feedback score, quantity available and sold, watch count, start and end date, item location city, shipping service and delivery estimate, return policy, category path and all images. Slower and charged extra per listing (see pricing). eBay checks item pages harder than search pages: use RESIDENTIAL proxies for large detail runs (~98% first-try success vs ~50% on datacenter).

## `sort` (type: `string`):

Result order for search terms (start URLs keep their own sort).

## `listingType` (type: `string`):

Only auctions, only Buy It Now listings, or only listings that accept offers (search terms only).

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

Item condition filter (search terms only).

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

Lowest item price in the marketplace currency (search terms only). Leave empty for no limit.

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

Highest item price in the marketplace currency (search terms only). Leave empty for no limit.

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

Optional eBay category ID to search in (the number in eBay category URLs, e.g. 139971 for Video Game Consoles on ebay.com). Search terms only.

## `includePartialMatches` (type: `boolean`):

When eBay finds no exact matches for a search it shows loosely related listings instead ("No exact matches found"). By default those are skipped; turn this on to save them too (flagged with partialMatch: true).

## `onlyNewOrChanged` (type: `boolean`):

Remember what earlier runs of this search returned and output only new items or items whose price/status changed. Use with a Schedule; unchanged items are not charged. With this on, Max items is the number of listings checked each run (the watched window, e.g. the newest 100), so a run never digs deeper than the first one. Price, the struck-through original price and the stock hint ("Last one") are compared; shipping is not (eBay calculates it per visitor location).

## `monitoringKey` (type: `string`):

Name for this watch, so several schedules on the same search stay separate; defaults to a key derived from the search input.

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

Apify Proxy. Datacenter (the default) works well for search pages: the actor rotates browser fingerprints and IPs when eBay shows its 'Pardon our interruption' check. For item details, RESIDENTIAL proxies get through far more often (they cost per GB of traffic, about 170 KB per item page, roughly $1.40 per 1,000 item pages at $8/GB). No Unblocker charges.

## Actor input object example

```json
{
  "searchTerms": [
    "nintendo switch"
  ],
  "marketplace": "com",
  "startUrls": [],
  "maxItems": 100,
  "maxPagesPerSearch": 10,
  "includeDetails": false,
  "sort": "best_match",
  "listingType": "all",
  "condition": "any",
  "includePartialMatches": false,
  "onlyNewOrChanged": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

# 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": [
        "nintendo switch"
    ],
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tortuga/ebay-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": ["nintendo switch"],
    "startUrls": [],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("tortuga/ebay-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": [
    "nintendo switch"
  ],
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call tortuga/ebay-scraper --silent --output-dataset

```

## MCP server setup

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