# eBay Price Comparison Scraper (`apt_marble/ebay-price-comparison-scraper`) Actor

Compare every live seller offer for one eBay product in a single run. Give a product number, a product link, or a search phrase, and get each offer's price, condition, shipping and seller, plus a market summary of the cheapest and dearest by condition. No eBay account needed.

- **URL**: https://apify.com/apt\_marble/ebay-price-comparison-scraper.md
- **Developed by:** [Hamza](https://apify.com/apt_marble) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 offer 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?

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 Price Comparison Scraper

Find out what the market is charging for the same eBay product — in one run. Give the actor a product number (ePID), a product page link, or just a search phrase, and it returns each live Buy-It-Now offer with its price, condition and shipping, alongside a market summary that shows the cheapest and most expensive offer for each condition. It is built for resellers, deal hunters, pricing analysts and anyone who needs the true spread of what a product actually sells for on eBay right now.

### What you can do with it

- **See the real price spread** for a product across every live seller, not just the one "from" price eBay shows on the product page.
- **Compare by condition** — the summary breaks the floor and ceiling down into New, Used, Open Box, Refurbished and Parts, so you can price a used unit against used competition.
- **Resolve a phrase to a product** — type "sony wh-1000xm5" and the actor picks the single eBay catalog product your phrase most points to, and tells you which one it chose.
- **Track a product over time** by scheduling the actor and keeping the summary rows — watch the floor price and offer count move day to day.
- **Source inventory** by finding the cheapest live offer for a product you resell.
- **Feed pricing models** with clean, per-offer rows you can group, average or chart however you like.

### What you get

Two kinds of rows land in the same dataset, told apart by `recordType`. One row per live offer:

```
{
  "recordType": "offer",
  "epid": "22054478105",
  "listingId": "257203712796",
  "price": { "amount": 138.56, "currency": "USD" },
  "condition": "Pre-Owned",
  "shippingCost": 34.94,
  "freeShipping": false,
  "buyingFormat": "buy-it-now",
  "bestOffer": false,
  "sellerName": null,
  "imageUrl": "https://i.ebayimg.com/images/g/8VMAAeSwdEdpFCef/s-l300.jpg",
  "url": "https://www.ebay.com/itm/257203712796",
  "source": "live-listing",
  "rank": 2,
  "marketplace": "US"
}
```

And one market summary per product (when enabled):

```
{
  "recordType": "product-summary",
  "epid": "22054478105",
  "productName": "Sony WH-1000XM5 Wireless Noise Canceling Headphones - Black",
  "brand": "Sony",
  "mpn": "WH-1000XM5",
  "gtin13": "0027242923232",
  "aggregateRating": 4.7,
  "ratingsCount": 148,
  "offerCount": 327,
  "offersCollected": 30,
  "minPrice": 14.99,
  "maxPrice": 208.97,
  "currency": "USD",
  "priceByCondition": {
    "Brand New": { "min": 184, "max": 208.97, "offerCount": 4 },
    "Pre-Owned": { "min": 14.99, "max": 153.24, "offerCount": 12 }
  },
  "soldOut": false,
  "resolvedFrom": "keyword",
  "sourceQuery": "sony wh-1000xm5",
  "epidFrequency": 12
}
```

### Input reference

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `products` | list of text | — | The products to compare. Each entry is a product number (ePID), a product page link, or a search phrase. Duplicates are collapsed; empty entries are skipped. Up to 1,000 products per run. |
| `condition` | select | `any` | Limit offers to New, Used or Refurbished — or leave on Any to compare across every condition. |
| `maxOffersPerProduct` | integer | `100` | How many live offers to collect per product, in eBay's own listing order. Up to 1,000. |
| `includeProductSummary` | boolean | `true` | Add one market-summary row per product (name, identifiers, rating, offer count, and price spread by condition). Turn off to keep only the individual offer rows. |
| `marketplace` | select | `US` | Which country's eBay site to compare on. Prices come back in that site's own currency. |
| Parallel products | integer | `4` | How many products to work on at the same time. Higher is faster, but eBay serves fewer complete pages when pushed hard. |

### Output fields

#### Offer rows (`recordType: "offer"`)

| Field | Description |
| --- | --- |
| `epid` | The eBay catalog product this offer belongs to. |
| `listingId` | The individual listing's id. |
| `price` | The offer price as `{ amount, currency }`. |
| `condition` | The listed condition (e.g. Brand New, Pre-Owned, Open Box). |
| `shippingCost` | Shipping cost when shown; `0` for free shipping, `null` when not stated. |
| `freeShipping` | Whether the offer ships free. |
| `buyingFormat` | Buying format — Buy-It-Now for these offers. |
| `bestOffer` | Whether the seller accepts a best offer. |
| `sellerName` | The seller, when the offer shows it. |
| `imageUrl` | The listing's image. |
| `url` | Direct link to the listing. |
| `source` | Always `live-listing`. |
| `rank` | Position in eBay's own listing order for this product. |

#### Product-summary rows (`recordType: "product-summary"`)

| Field | Description |
| --- | --- |
| `productName`, `brand`, `mpn`, `gtin13` | Catalog identity; `gtin13` is `null` when eBay does not publish it. |
| `aggregateRating`, `ratingsCount` | Overall star rating and how many ratings it is based on. |
| `offerCount` | eBay's own count of Buy-It-Now offers for this product (an estimate, see limits). |
| `offersCollected` | How many offers this run actually gathered. |
| `minPrice`, `maxPrice`, `currency` | The floor and ceiling across the offers gathered. |
| `priceByCondition` | The floor and ceiling within each condition. |
| `soldOut` | Whether the product's own page shows it as sold out. |
| `resolvedFrom`, `sourceQuery`, `epidFrequency` | How the product was resolved — and, for a phrase, how strongly it pointed to the chosen product. |

### Pricing

This actor uses pay-per-event pricing:

- **Offer scraped — $0.0007 each.** Charged once for every live offer row returned.
- **Product market summary — $0.002 each.** Charged once per product, only when the summary is included.

**Worked example.** Comparing 10 products, gathering up to 100 offers each with the summary on: about 1,000 offer rows (~$0.70) plus 10 summaries (~$0.02) — roughly **$0.72** for the run. Turn the summary off and you pay only for the offer rows.

### Limits & what this actor cannot do

- **Prices, stock and ratings are a snapshot** at the moment of collection and keep changing afterwards. Two runs minutes apart can differ.
- **`offerCount` is eBay's own estimate** of the Buy-It-Now offers for a product and can differ from `offersCollected`. eBay publishes more than one count for a product; this one covers Buy-It-Now offers only.
- **A search phrase is matched to a single product** — the one it most points to. A broad phrase can resolve to a product you did not mean; pass an ePID or a product link when you need to be exact. `resolvedFrom` and `epidFrequency` tell you how the choice was made.
- **The floor and ceiling are computed only from the offers gathered,** up to your chosen maximum — raise `maxOffersPerProduct` to widen the picture.
- **eBay's buying-options comparison lists each offer's price, condition and shipping, but not the seller's name,** so `sellerName` is usually empty on offer rows. To attach seller details to a listing, take its `listingId` into the eBay Product Scraper.
- **Products that are removed or have no live offers are reported as unavailable** in the run summary rather than returned as empty rows.
- **Speed depends on the size of the job and on eBay's own response times;** no fixed speed is promised.
- **eBay's terms govern automated access.** You are responsible for using the data lawfully and in line with eBay's terms, and for handling any personal data in line with applicable privacy law.

### FAQ

**Do I need an eBay account?** No. The actor reads publicly visible product and offer pages — just run it.

**Does it need my login or password?** No. No account, no login and no personal credentials of any kind are used.

**Can I give it a keyword instead of a product number?** Yes. Type a phrase and the actor resolves it to the single eBay catalog product it most points to, reporting which product it chose and how strongly the phrase matched.

**Can I schedule it?** Yes. Schedule it and keep the summary rows to watch a product's floor price and offer count change over time.

**Is the data complete?** It returns the live Buy-It-Now offers eBay serves for a product, up to the maximum you set. Because eBay's own offer count is an estimate and its listing order shifts between reads, treat the gathered offers as a representative, up-to-the-minute sample rather than a guaranteed census.

**Which eBay sites are supported?** United States, United Kingdom, Germany, Australia, Canada, France, Italy and Spain. Prices come back in each site's own currency.

# Actor input Schema

## `products` (type: `array`):

The products to gather offers for. Each entry can be an eBay product number (ePID), a product page link (a /p/ link), or a plain search phrase. A phrase is matched to the single eBay catalog product it most points to, and that choice is reported back. Duplicates are collapsed; empty entries are skipped. Up to 1,000 products per run.

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

Limit offers to a single item condition, or leave on Any to compare across all conditions.

## `maxOffersPerProduct` (type: `integer`):

How many live offers to collect for each product, taken in eBay's own listing order. Up to 1,000.

## `includeProductSummary` (type: `boolean`):

Add one summary row per product with its name, brand, identifiers, overall rating, the number of Buy-It-Now offers eBay lists, and the price spread broken down by condition. Turn this off to collect only the individual offer rows.

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

Which country's eBay site to compare offers on. Prices come back in that site's own currency.

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

How many products to work on at the same time. Higher is faster, but eBay serves fewer complete pages when pushed hard. Leave at 4 unless you have a reason.

## Actor input object example

```json
{
  "products": [
    "22054478105",
    "sony wh-1000xm5"
  ],
  "condition": "any",
  "maxOffersPerProduct": 100,
  "includeProductSummary": true,
  "marketplace": "US",
  "maxConcurrency": 4
}
```

# Actor output Schema

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

Every offer and product-summary row this run produced.

## `runSummary` (type: `string`):

What this run compared, how each product was resolved, and anything it could not read.

# 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 = {
    "products": [
        "22054478105",
        "sony wh-1000xm5"
    ],
    "condition": "any",
    "maxOffersPerProduct": 100,
    "includeProductSummary": true,
    "marketplace": "US",
    "maxConcurrency": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("apt_marble/ebay-price-comparison-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 = {
    "products": [
        "22054478105",
        "sony wh-1000xm5",
    ],
    "condition": "any",
    "maxOffersPerProduct": 100,
    "includeProductSummary": True,
    "marketplace": "US",
    "maxConcurrency": 4,
}

# Run the Actor and wait for it to finish
run = client.actor("apt_marble/ebay-price-comparison-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 '{
  "products": [
    "22054478105",
    "sony wh-1000xm5"
  ],
  "condition": "any",
  "maxOffersPerProduct": 100,
  "includeProductSummary": true,
  "marketplace": "US",
  "maxConcurrency": 4
}' |
apify call apt_marble/ebay-price-comparison-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,apt_marble/ebay-price-comparison-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/K1onINgFnp21EioQE/builds/cgO6DvdjU6aO9OhhF/openapi.json
