eBay Listing Insights — Deals, Condition & Demand Signals avatar

eBay Listing Insights — Deals, Condition & Demand Signals

Pricing

Pay per usage

Go to Apify Store
eBay Listing Insights — Deals, Condition & Demand Signals

eBay Listing Insights — Deals, Condition & Demand Signals

eBay Listing Insights — Deals, Condition & Demand Signals extracts public eBay listing data, including prices, item condition, seller details, shipping, sales signals, availability, and listing URLs. Ideal for deal discovery, price analysis, demand research, and competitor monitoring.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

ScraperX

ScraperX

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

0

Monthly active users

57 days

Issues response

17 days ago

Last modified

Share

Paste any eBay link — a search results page, a category page, or a single listing — and get back clean, structured product intelligence: title, subtitle, current and previous price, a computed discount %, quantity available, units sold, watcher count, item condition, brand, item location, seller username, product identifiers (EAN / UPC / MPN), the full item-specifics table, category path and image.

Perfect for deal hunting, price tracking, product research, reselling and catalog building — with no code and no eBay developer account.


What makes this build different

  • Automatic discount math. Every row gets a computed discountPercent — no need to subtract originalPrice from currentPrice yourself.
  • Deals-only mode. Turn on dealsOnly and listings without a live strike-through discount are skipped entirely — not saved, not charged. Point it at a whole category and only pay for actual markdowns.
  • Condition & watcher-count signals. itemCondition (New / Used / Refurbished / …) and watcherCount add quality and demand context that a plain price/title scrape doesn't give you.
  • Full item specifics, not just a handful of fields. itemSpecifics captures every attribute eBay publishes on the listing (material, size, color, model, etc.) as one structured object, on top of the always-present brand/type/identifier fields.
  • Spreadsheet-friendly export toggle. Flip flattenLists on and nested fields (categoryPath, highlights, itemSpecifics) collapse into clean delimited text — ideal for a one-click CSV/Excel export.

What you get

🛒 Listing data💵 Pricing & deals📈 Demand & condition🏷️ Identifiers & seller
Title & subtitleCurrent price (numeric + display)Units soldeBay listing ID
"Highlights" bulletsOriginal/"was" price (numeric + display)Watcher countBrand and item type
Full category pathComputed discount %Item conditionEAN, UPC, MPN
Main product imageStock available (number + raw text)Seller username
Canonical listing URLShips-from location
Full item-specifics tableScraped-at timestamp

Key features

  • Search pages and single listings. Give it a search or category URL and it discovers the listings in the results grid; give it a listing URL and it extracts that item directly. Mix both in one run.
  • Bulk input. Paste as many eBay URLs as you like — every filter you set in your browser (condition, price range, Buy It Now, location, sort order) travels with the link.
  • Numeric and display prices, plus discount %. currentPrice is a clean float for calculations; currentPriceDisplay keeps the original string with its currency symbol. The same pair exists for originalPrice, and discountPercent does the subtraction for you.
  • Deal filtering that saves money. With dealsOnly on, non-discounted listings are dropped before they ever hit the dataset or your bill.
  • Demand + condition signals. unitsSold, watcherCount and itemCondition turn a listing into a real data point about market movement and item quality, not just an asking price.
  • Product identifiers for matching. EAN, UPC, MPN and brand let you join eBay data to Amazon, Google Shopping or your own catalog. itemSpecifics gives you everything else the listing publishes.
  • Honest failure rows. If a listing page cannot be loaded, the Actor writes a row containing the URL and the reason instead of silently dropping it — and does not charge for it. You always know exactly what was and wasn't collected.
  • Polite, resilient fetching. Requests are staggered and jittered, with an automatic fallback path when a page is refused, so large jobs stay stable.
  • Optional Apify Proxy. Enable it — and pick a country if you need region-specific pricing — for large or international runs.

Use cases

  • Deal hunting at scale — run dealsOnly over a whole category and only pay for listings that are actually marked down.
  • Price monitoring & repricing — track competitor prices on the same items daily and feed the numbers into your pricing rules.
  • Reseller & arbitrage research — compare eBay prices against your sourcing cost, using unitsSold and watcherCount to gauge real demand.
  • Product & market research — pull an entire category to see price distribution, brand share, condition mix and stock levels.
  • Competitor analysis — monitor a specific seller's listings, prices and sell-through.
  • Catalog building & enrichment — populate a product database with titles, images, identifiers, full specifics and categories.
  • Dropshipping product discovery — find high-demand, in-stock, new-condition items in a niche.
  • Lead generation — identify active sellers by username and location within a category.

How it works

  1. You paste eBay URLs — search results, category pages, listing pages, or a mix.
  2. Search and category URLs are expanded: the Actor reads the results grid and collects the individual listing URLs behind it.
  3. Each listing page is fetched with staggered, randomised timing and an automatic retry/fallback path if eBay refuses the first attempt.
  4. The page is parsed from its structured product data and page body into one flat record — condition, watcher count, discount % and the full specifics table are derived here.
  5. The dealsOnly filter runs (if enabled) before the row is saved — non-discounted listings are skipped and never charged.
  6. Rows stream into the dataset as they complete, with a progress log showing how many full product records have been saved so far.

Quick start

  1. Search for something on eBay in your browser and apply any filters you want.
  2. Copy the URL from the address bar.
  3. Open the Actor, paste it into Where should we look?.
  4. Set Cap how many products to collect — try 20 first, then scale up. Use 0 for no limit.
  5. (Optional) Turn on Only keep listings that are actually discounted if you're deal hunting.
  6. Click Start and export the Output tab as CSV, Excel or JSON.

Minimal input

{
"productLinks": [
"https://www.ebay.com/sch/i.html?_nkw=mechanical+keyboard"
],
"resultsLimit": 20
}

Deals-only input

{
"productLinks": [
"https://www.ebay.com/sch/i.html?_nkw=mechanical+keyboard"
],
"resultsLimit": 100,
"dealsOnly": true
}

Input configuration

FieldTypeDefaultDescription
productLinksarray— (required)One or more eBay URLs. Search / category pages are expanded into their listings; single listing pages are scraped directly. Accepts plain strings or { "url": "…" } objects.
resultsLimitinteger20Ceiling on how many product pages to process after URL discovery. 0 = no limit. Lower is faster and cheaper; higher gives broader coverage.
dealsOnlybooleanfalseSkip (and don't charge for) any listing without a live strike-through discount.
flattenListsbooleanfalseCollapse categoryPath, highlights and itemSpecifics into delimited text for clean CSV/Excel exports.
concurrentWorkersinteger4How many listing pages to fetch in parallel. Keep modest — eBay's anti-bot punishes bursts from a single IP.
requestDelaySecinteger1Base delay (plus built-in jitter/stagger) before each request.
networkSettingsobjectoptionalApify Proxy settings. Enable — and optionally choose a country or group — for large jobs or region-specific pricing.

Tip: for country-specific prices, use the matching eBay domain (ebay.co.uk, ebay.de, ebay.com.au…) and a proxy in that country.


Output data

One row per product listing.

FieldTypeDescription
listingUrlstringCanonical listing URL.
listingIdstringeBay item number.
listingTitlestringListing title.
listingSubtitlestringListing subtitle, when present.
highlightsarray / stringHighlight bullets eBay shows on the listing.
currentPricenumberCurrent price as a number, ready for maths.
currentPriceDisplaystringCurrent price exactly as displayed, with currency.
originalPricenumberStruck-through original price, when the item is discounted.
originalPriceDisplaystringThe same value as displayed.
discountPercentnumberNew. Computed live discount, e.g. 25.0 for 25% off. null when there's no discount.
stockAvailablenumberQuantity available as a number.
stockAvailableTextstringThe raw availability text (e.g. More than 10 available).
unitsSoldnumberUnits sold.
watcherCountnumberNew. How many people are watching the listing — a live demand signal alongside unitsSold.
itemConditionstringNew. New / Used / Refurbished / For parts, etc.
imageUrlstringMain product image URL.
sellerUsernamestringSeller username.
shipsFromstringWhere the item ships from.
brandNamestringBrand, or Unbranded when eBay reports none.
productTypestringItem type from the listing specifics.
eanCode, upcCode, mpnCodestringProduct identifiers, null when not published.
categoryPatharrayCategory breadcrumb path.
itemSpecificsobjectNew. Every attribute eBay publishes on the listing (material, size, color, model, …), not just the handful above.
scrapedAtstringNew. UTC timestamp the row was captured — useful for repeat-run price/condition history.

Diagnostic rows. If a listing cannot be fetched, the dataset receives { "listingUrl": …, "scrapeError": "unavailable", "errorReason": … } instead. These rows are not charged — they exist so nothing disappears from your export without explanation. Filter them out by keeping only rows where listingTitle is present.

Skipped rows (dealsOnly). When dealsOnly is on, non-discounted listings are simply skipped (logged, not written to the dataset) — they are never charged.

Example output

{
"listingUrl": "https://www.ebay.com/itm/123456789012",
"listingId": "123456789012",
"listingTitle": "Mechanical Gaming Keyboard RGB Hot-Swappable 75% Wireless",
"listingSubtitle": "Brand New · Free Shipping",
"highlights": ["Hot-swappable switches", "Tri-mode connectivity"],
"currentPrice": 59.99,
"currentPriceDisplay": "US $59.99",
"originalPrice": 79.99,
"originalPriceDisplay": "US $79.99",
"discountPercent": 25.0,
"stockAvailable": 12,
"stockAvailableText": "More than 10 available",
"unitsSold": 348,
"watcherCount": 27,
"itemCondition": "New",
"imageUrl": "https://i.ebayimg.com/images/g/abc/s-l1600.jpg",
"sellerUsername": "example_tech_store",
"shipsFrom": "Shenzhen, China",
"brandName": "Example",
"productType": "Keyboard",
"eanCode": "0712345678901",
"upcCode": "712345678901",
"mpnCode": "EX-KB75",
"categoryPath": ["Computers/Tablets & Networking", "Keyboards, Mice & Pointers", "Keyboards & Keypads"],
"itemSpecifics": {
"Connectivity": "Wireless, Bluetooth, USB-C",
"Switch Type": "Hot-Swappable Mechanical",
"Color": "Black"
},
"scrapedAt": "2026-08-17T22:54:00+00:00"
}

Illustrative values — a live run returns current eBay data.


Usage examples

Track a keyword across a whole category

{
"productLinks": ["https://www.ebay.com/sch/i.html?_nkw=vintage+film+camera&_sop=12"],
"resultsLimit": 200
}

Monitor a specific seller's inventory

Open the seller's store page on eBay, copy the URL, and run:

{
"productLinks": ["https://www.ebay.com/str/example-tech-store"],
"resultsLimit": 0
}

Watch exact listings for price and condition changes

{
"productLinks": [
"https://www.ebay.com/itm/123456789012",
"https://www.ebay.com/itm/210987654321"
]
}

Save as a Task, attach a daily Schedule, and compare currentPrice/itemCondition between runs using scrapedAt.

Find live discounts without paying for anything else

{
"productLinks": ["https://www.ebay.com/sch/i.html?_nkw=vintage+film+camera"],
"resultsLimit": 0,
"dealsOnly": true
}

Run it from your own code

Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_API_TOKEN>")
run = client.actor("YOUR_USERNAME/ebay-listing-insights-scraper").call(run_input={
"productLinks": ["https://www.ebay.com/sch/i.html?_nkw=mechanical+keyboard"],
"resultsLimit": 100,
"dealsOnly": False,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item.get("listingTitle"):
print(item["listingTitle"], item["currentPrice"], item.get("discountPercent"))

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_API_TOKEN>' });
const run = await client.actor('YOUR_USERNAME/ebay-listing-insights-scraper').call({
productLinks: ['https://www.ebay.com/sch/i.html?_nkw=mechanical+keyboard'],
resultsLimit: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

cURL

curl -X POST "https://api.apify.com/v2/acts/YOUR_USERNAME~ebay-listing-insights-scraper/runs?token=<YOUR_APIFY_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"productLinks":["https://www.ebay.com/sch/i.html?_nkw=mechanical+keyboard"],"resultsLimit":100}'

Integrations

Push results to Google Sheets, Airtable, Slack, Make, Zapier, Google Drive or any endpoint via webhooks, and use Schedules for automatic daily price/deal snapshots.


Pricing

Pay-per-event: a small Actor-start charge plus a charge for each fully extracted product record that passes your filters. Failed, unavailable, or (with dealsOnly on) non-discounted listings are not billed — you only pay for real, wanted data. Current rates are on the Pricing tab of this Actor's page, and Apify shows an estimated cost before and during each run.


Limits & good to know

  • resultsLimit applies after URL discovery, i.e. it caps how many listing pages get processed in total across all your input URLs.
  • eBay search pages are paginated by eBay itself — to go deeper, add more search URLs (different keywords, sort orders or filters).
  • Fields appear only when eBay publishes them. Many listings have no EAN/UPC/MPN; those come back as null. watcherCount returns null when eBay doesn't render a watcher count for that listing.
  • Prices reflect what an anonymous visitor sees on the domain you used. For local currency and availability, use the matching eBay country domain and a proxy in that country.
  • Auction-specific data (bid counts, time remaining) is outside this Actor's field set; it targets product, price, condition, stock and seller data.
  • Default run options are 4 GB memory and a 1-hour timeout — raise the timeout for very large jobs.

FAQ

Do I need an eBay account or developer API key? No. The Actor reads public listing pages only.

Which URLs can I paste? eBay search result URLs, category pages, seller/store pages and individual item pages — from any eBay country domain.

Can I scrape sold/completed listings? You can paste an eBay search URL that already has the Sold items filter applied; the Actor scrapes whatever that URL returns.

Why do some rows only contain a URL and an error? That listing page failed to load (removed, region-blocked, or temporarily refused). The row documents it, and you are not charged for it.

Why did fewer rows come back than my resultsLimit? If dealsOnly is on, listings without a live discount are skipped on purpose and not charged — check the run log for the skip count.

How do I get prices in EUR or GBP? Use the corresponding eBay domain (ebay.de, ebay.co.uk) and, ideally, a proxy located in that country.

Can I export to Excel? Yes — JSON, CSV, Excel (XLSX), XML and RSS, from the UI or the API. Turn on flattenLists first if you want nested fields as plain text.

Can it run automatically every day? Yes. Save your input as a Task and attach an Apify Schedule.


This Actor collects only publicly available information from eBay listing pages — the same data any visitor can see. It does not log in, bypass protections, or access private account data. You are responsible for ensuring your use of the exported data complies with eBay's terms and applicable law.

Support

Missing a field, hit a bug, or need a custom eBay workflow? Open an issue on the Issues tab.