eBay Product Details Scraper β€” Watchlist & Price Details avatar

eBay Product Details Scraper β€” Watchlist & Price Details

Pricing

from $4.99 / 1,000 results

Go to Apify Store
eBay Product Details Scraper β€” Watchlist & Price Details

eBay Product Details Scraper β€” Watchlist & Price Details

πŸ›οΈ eBay Product Details Scraper grabs rich listing data in one click β€” titles, prices, images, specs, seller & shipping, variations, stock, category, ratings & reviews. ⚑ Fast, API-ready. Export CSV/JSON. πŸ” Ideal for market research, price tracking, SEO, analytics & dropshipping.

Pricing

from $4.99 / 1,000 results

Rating

0.0

(0)

Developer

Scraper Engine

Scraper Engine

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

4 days ago

Last modified

Share

eBay Price Tracker β€” Price History, Watchers, Bids and Sold Counts

Paste in eBay listing links and get back the full listing record β€” title, price, condition, images, seller, shipping, returns, description and item specifics β€” plus a cross-run price watchlist: whether the price moved since your last run, the drop percentage, the lowest and highest price ever seen, and live demand signals (watcher count, sold count, auction bid count and time remaining). Output is structured JSON with a stable schema, no HTML parsing required. Re-run the same list on a schedule and watch the price history build up. πŸ‘‰ Paste a listing URL into the input and hit Start to see your first watchlist row.

What is eBay Price Tracker?

eBay Price Tracker is an Apify Actor that fetches one or more eBay listing pages, extracts the complete product record, and layers a cross-run price watchlist on top β€” price change, drop %, lowest/highest price ever seen, watcher count, sold count, and auction bid/time-remaining data β€” all read from the same page fetch, with no extra requests. No eBay account or login is required β€” every field comes from the public listing page. It's built for resellers and dropshippers tracking sourcing prices, deal hunters chasing markdowns, and analysts or AI agents that need structured eBay pricing data on a schedule.

One clarification worth making up front: the "watchlist" here is this Actor's own feature β€” a per-listing price history it keeps in Apify storage under the watchlistId you choose. It has nothing to do with signing into an eBay account or eBay's own native watchlist button.

What eBay listing data is publicly available to scrape?

Everything a shopper sees on an eBay listing page without signing in is accessible: title, price, condition, photos, item specifics, description, return policy, seller store name and feedback rate, current watcher count, sold count, and β€” for auctions β€” the live bid count and countdown. eBay gates a smaller set of things behind an account sign-in: a delivery estimate personalized to your own address, full bidder history on an auction, and adding an item to your own eBay account watchlist.

Data CategoryPublicly Available (no login)Requires an eBay Account / Sign-In
Title, price, condition, photosβœ…β€”
Item specifics, description, return policyβœ…β€”
Watcher count, sold countβœ…β€”
Auction bid count and countdownβœ…β€”
Seller store name, feedback %, items soldβœ…β€”
Default shipping / delivery estimateβœ…β€”
Delivery estimate personalized to your addressβ€”βœ…
Full bidder history / buyer usernamesβ€”βœ…

eBay Price Tracker only returns publicly visible data β€” what any visitor sees. Nothing behind a login wall.

What data can I extract with eBay Price Tracker?

eBay Price Tracker returns three groups of data for every listing: the listing and seller record itself, the live demand and price metrics on the page, and the cross-run price-watch history computed against your previous check.

πŸ“„ Listing, seller and record details

Field NameDescription
product_titleListing title
item_numbereBay's own item number for the listing
product_conditionCondition as stated by the seller (e.g. "New", "Pre-owned")
product_imageArray of full-size image URLs from the listing's photo carousel
detail_urlCanonical listing URL read from the page itself
source_urlThe listing URL you supplied in the input
seller_nameSeller's store or account name
seller_items_soldSeller's total items-sold figure, as displayed on the page
positive_feedbackSeller's positive feedback percentage, as displayed on the page
shipping_infoShipping cost, carrier and seller location text
delivery_infoEstimated delivery window text
return_policyReturn policy text
item_descriptionPlain-text item description (fetched from the description iframe when eBay serves it separately)
item_specificsObject of the seller's declared item specifics (e.g. {"Brand": "Apple", "Model": "..."}) β€” keys vary per listing
successtrue once a listing is fetched and parsed; false on any error row
proxyModeWhich connection route returned this page: direct, datacenter, residential, or failed
scrapedAtISO-8601 timestamp of this fetch

πŸ“Š Demand, price and auction metrics

Field NameDescription
product_priceRaw price text as displayed on the page (e.g. "US $289.00")
priceValueParsed numeric price from the same headline price box
priceCurrencyCurrency code parsed alongside priceValue (e.g. "USD")
watcherCountNumber of shoppers currently watching the listing
soldCountUnits sold, as displayed on the page
availabilityTextStock/availability text (e.g. "3 available"), when eBay shows it
listingFormat"auction" or "fixed_price"
isAuctionBoolean version of the same flag
bidsCurrent bid count β€” only populated for auctions, null otherwise
timeRemainingAuction countdown text β€” only populated for auctions
listingEndsAtAuction end time in ISO-8601 β€” only populated for auctions
hoursRemainingHours until listingEndsAt β€” only populated for auctions

πŸ“‰ Price-watch history (cross-run)

Field NameDescription
watchlistIdThe watchlist name this row was checked under
watchKeyStable storage key for this listing (item number, or the URL if no item number is found)
checkedAtTimestamp of this check
isFirstChecktrue if this is the first time this listing has ever been checked under this watchlistId
timesCheckedHow many times this listing has been checked in total
firstSeenAtTimestamp of the very first check
previousCheckedAtTimestamp of the previous check, or null on the first check
previousPricePrice recorded on the previous check, or null on the first check
priceChangedSinceLastRuntrue/false once there's a previous price to compare against, null on the first check
priceChangeAmountSigned price change since the previous check
priceChangePercentSigned percentage change since the previous check
priceDropPercentPercentage the price dropped by (0 if it didn't drop)
isPriceDropAlerttrue when priceDropPercent meets or exceeds your priceDropAlertPercent threshold
lowestPriceSeenLowest price recorded for this listing across all checks
highestPriceSeenHighest price recorded for this listing across all checks
priceHistoryArray of { "checkedAt": ..., "price": ... } snapshots, most recent 50

Error rows (success: false) carry a smaller shape instead: source_url, success, error, errorReason (invalid_url, not_found, or unavailable), scrapedAt, checkedAt, and proxyMode when a connection was attempted.

πŸ€– Add-on: Need additional eBay data?

If you need to discover listing URLs rather than supply them yourself, pair this Actor with eBay Search Scraper β€” run a keyword search, then feed the resulting item URLs straight into watchlistUrls here to start tracking their prices.

Why not build this yourself?

eBay doesn't hand out clean pricing data for free, and scraping it reliably takes more than a single HTTP request. This Actor already handles the parts that break a homemade scraper: a browser-realistic session (Chrome TLS/HTTP fingerprint impersonation, warmed on eBay's homepage first) reused across every listing, because eBay ties its anti-bot clearance to the session that earned it rather than to any single request; telling a permanently removed listing (a fixed 403/404/410 "item not found" page) apart from a temporary block so retries aren't wasted on dead items; escalating through direct β†’ datacenter proxy β†’ residential proxy only when needed; and a price-history store keyed per listing so drop %, and lowest/highest price ever seen, are computed correctly across runs. On top of that, the item-specifics and description parsing has to be rebuilt every time eBay reshuffles its page markup β€” this Actor's extraction layer already absorbs that.

How to use eBay Price Tracker

eBay Price Tracker runs on Apify β€” there's no separate signup or API key beyond your Apify account.

  1. Open the Actor on its Apify Store page and click Start, or create a task from it in the Apify Console.
  2. Add at least one eBay listing URL under watchlistUrls (this is the only input that needs a value β€” every other field has a working default).
  3. Optionally set watchlistId to group this project's price history separately from others, priceDropAlertPercent to control when isPriceDropAlert fires, minWatchers or listingFormatFilter to narrow what gets saved, and onlyPriceChangedItems to skip unchanged listings.
  4. Start the run.
  5. Read results from the OUTPUT tab, or export as JSON, CSV, Excel, or another supported format from the dataset.

How to scale to bulk listing tracking

watchlistUrls is an array β€” the schema places no maximum on how many listing links you add, so a single run can track your whole watchlist in one go. Each URL gets its own row and its own independent price history, keyed by eBay item number. To build price history over time, set up an Apify Schedule that re-runs the same input (same URLs, same watchlistId) on a recurring basis β€” for example daily β€” so each run compares against the last.

What can you do with eBay listing data?

  • 🏬 Resellers and dropshippers sourcing inventory use priceValue and priceDropPercent to catch a supplier's price drop before restocking or re-listing elsewhere.
  • πŸ›’ Deal hunters use isPriceDropAlert together with their own priceDropAlertPercent threshold to get flagged only when a tracked listing genuinely moves, not on every check.
  • πŸ“Š Price-monitoring dashboards chart priceHistory, lowestPriceSeen and highestPriceSeen to show a listing's full trend line, not just today's price.
  • πŸ”¨ Auction bidders use bids, timeRemaining and listingEndsAt to know exactly when to place a last-minute bid.
  • πŸ€– AI agents and RAG pipelines feed item_description, item_specifics and priceValue into an LLM to answer questions like "has this part gotten cheaper" or to power an automated price-comparison agent.

How does eBay Price Tracker handle rate limits and blocking?

Each run keeps a single warmed browsing session β€” a Chrome-impersonating HTTP client warmed on eBay's homepage first β€” and reuses it for every listing, since eBay ties its clearance to the session, not the request. If a page comes back blocked (a CAPTCHA, "pardon our interruption", access denied, or a suspiciously short response) or the connection fails outright, the fetcher escalates through routes: direct connection β†’ Apify Proxy datacenter group β†’ Apify Proxy residential group, retrying up to 3 times on the residential tier before giving up on that listing. A 403/404/410 response is checked against eBay's fixed "item not found" page signatures first β€” if it matches, the listing is reported as permanently gone immediately instead of being retried, since no route change can fix a listing that no longer exists. A small randomized pause is added between listings. No CAPTCHA-solving happens β€” blocking is handled purely by rotating connection routes. If every route fails, that listing is saved as an error row (success: false) instead of stopping the run, so the rest of your list still gets checked.

⬇️ Input

ParameterRequiredTypeDescriptionExample Value
watchlistUrlsNoarrayOne eBay item link per line, copied from the address bar. Add as many as you like β€” each one gets its own price history. Keep the same list between runs so the comparison has something to compare against.["https://www.ebay.com/itm/287245300280"]
watchlistIdNostring, default "default"Groups price history under one name so separate projects never mix. Runs sharing this name share their price history; change it to start a clean, independent history."sneaker-deals"
priceDropAlertPercentNointeger, default 5, min 0, max 100Sets isPriceDropAlert to true when a listing's price fell by at least this percentage since the previous run. On a listing's very first run there is nothing to compare with, so the flag is reported as empty.5
onlyPriceChangedItemsNoboolean, default falseWhen on, a listing whose price is identical to the previous run is skipped instead of saved. Its price history is still updated, and first-time listings are always saved.false
minWatchersNointeger, default 0, min 0Only save listings that at least this many shoppers are watching right now. Use 0 to keep everything.0
listingFormatFilterNostring, default "any", enum "any" / "auction" / "fixed_price"Keep every listing, only live auctions (bids + countdown), or only fixed-price (Buy It Now) listings."any"
urlsNoarrayCompatibility field. Older setups that send listing links under this name keep working unchanged β€” used only when watchlistUrls is empty.[]
startUrlsNoarraySecond compatibility field for listing links under this name β€” used only when both watchlistUrls and urls are empty.[]
proxyConfigurationNoobjectLeave enabled so the run can switch routes automatically if a listing page is slow to respond. Turn it off to connect directly only.{"useApifyProxy": true}

No parameter is required β€” a run with no input simply has no listings to check and exits with an error asking you to add at least one URL.

Example input

{
"watchlistUrls": [
"https://www.ebay.com/itm/287245300280",
"https://www.ebay.com/itm/315689412207"
],
"watchlistId": "sneaker-deals",
"priceDropAlertPercent": 5,
"onlyPriceChangedItems": false,
"minWatchers": 0,
"listingFormatFilter": "any",
"proxyConfiguration": {
"useApifyProxy": true
}
}

⬆️ Output

Every checked listing is written to the Actor's dataset as one typed, normalized JSON record with a consistent schema across runs β€” export it as JSON, CSV, Excel, or any other format the dataset export supports. Only rows pushed with the row_result event are charged: a listing that was fetched, parsed, and passed your onlyPriceChangedItems / minWatchers / listingFormatFilter settings. Error rows (success: false β€” an invalid URL, a delisted listing, or a fetch that failed on every route) are still saved to the dataset for visibility but are not charged; filter them out with success == true. Listings dropped by your filters aren't saved to the dataset at all (though their price history keeps updating in the background), so you're never charged for those either.

Example output

{
"success": true,
"product_title": "Apple Watch Series 9 GPS 45mm Midnight Aluminum Sport Band",
"product_image": [
"https://i.ebayimg.com/images/g/ab0AAOSwml1n/s-l1600.jpg",
"https://i.ebayimg.com/images/g/9pAAAOSwEz9o/s-l1600.jpg"
],
"product_price": "US $289.00",
"product_condition": "Pre-owned",
"shipping_info": "$0.00 USPS Ground Advantage; Located in: Columbus, Ohio, United States",
"delivery_info": "Estimated between Wed, Aug 5 and Mon, Aug 10",
"return_policy": "30 days returns. Buyer pays for return shipping.",
"item_number": "287245300280",
"item_description": "Apple Watch Series 9, GPS, 45mm case, Midnight aluminum case with Midnight Sport Band...",
"item_specifics": {
"Brand": "Apple",
"Model": "Apple Watch Series 9",
"Case Size": "45mm",
"Connectivity": "GPS"
},
"detail_url": "https://www.ebay.com/itm/287245300280",
"seller_name": "electronics-outlet-2024",
"seller_items_sold": "12.4K",
"positive_feedback": "99.2% positive",
"source_url": "https://www.ebay.com/itm/287245300280",
"proxyMode": "direct",
"scrapedAt": "2026-07-30T14:02:11.123Z",
"watchlistId": "sneaker-deals",
"watchKey": "287245300280",
"priceValue": 289.00,
"priceCurrency": "USD",
"watcherCount": 47,
"soldCount": 128,
"availabilityText": "3 available",
"listingFormat": "fixed_price",
"isAuction": false,
"bids": null,
"timeRemaining": null,
"listingEndsAt": null,
"hoursRemaining": null,
"checkedAt": "2026-07-30T14:02:11.123Z",
"isFirstCheck": false,
"timesChecked": 6,
"firstSeenAt": "2026-06-20T09:15:02.000Z",
"previousCheckedAt": "2026-07-23T14:00:05.000Z",
"previousPrice": 305.00,
"priceChangedSinceLastRun": true,
"priceChangeAmount": -16.00,
"priceChangePercent": -5.25,
"priceDropPercent": 5.25,
"isPriceDropAlert": true,
"lowestPriceSeen": 279.00,
"highestPriceSeen": 319.00,
"priceHistory": [
{ "checkedAt": "2026-06-20T09:15:02.000Z", "price": 319.00 },
{ "checkedAt": "2026-07-23T14:00:05.000Z", "price": 305.00 },
{ "checkedAt": "2026-07-30T14:02:11.123Z", "price": 289.00 }
]
}

How does it work?

Each listing URL is fetched with an HTTP client that impersonates a real Chrome browser's TLS and HTTP fingerprint, warmed on eBay's homepage first and then reused for every listing in the run β€” no headless browser or JavaScript rendering is involved, since the fields this Actor needs are already present in the page's HTML and embedded JSON. If a fetch is blocked, the Actor retries through Apify Proxy, escalating from a direct connection to datacenter and then residential exit nodes. The page is then parsed with targeted selectors and regular expressions into a fixed set of fields β€” title, price, seller, specifics, watcher count, bid count and so on β€” so the output schema stays the same shape run after run even as eBay tweaks its page markup. The price and demand numbers are compared against the last snapshot stored for that listing to compute the watchlist fields. Only what's visible on the public listing page is ever returned.

Integrations

eBay Price Tracker runs on the Apify platform, so it works with anything that can call the Apify API.

Calling eBay Price Tracker programmatically

from apify_client import ApifyClient
client = ApifyClient("<APIFY_API_TOKEN>")
run = client.actor("<your-username>/ebay-product-details-scraper-watchlist-and-price-details").call(
run_input={
"watchlistUrls": ["https://www.ebay.com/itm/287245300280"],
"watchlistId": "sneaker-deals",
"priceDropAlertPercent": 5,
}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["product_title"], item["priceValue"], item["priceDropPercent"])

Works in Go, Ruby, Node.js, cURL β€” any language that can make an HTTP request.

No-code tools (n8n, Make, LangChain)

In n8n, use the HTTP Request node (or the Apify integration node) pointed at this Actor's run endpoint to trigger a watchlist check and pass the resulting dataset items downstream. In Make, use the Apify module's "Run an Actor and get dataset items" action the same way. In LangChain, or any agent framework, wrap the Apify Run Actor API call as a tool so an agent can check for price drops on demand.

Scraping publicly available product and pricing data is generally lawful; eBay Price Tracker returns only what is visible on a listing page without logging in, and does not access private account data, messages, or anything behind a sign-in wall. Listing and price data is business/product information rather than personal data, so the relevant framework is eBay's own Terms of Service and database-rights law, not a personal-data regime like GDPR or CCPA. Consult legal counsel if your use case involves bulk storage of personal data, or if you plan to republish scraped content commercially.

Frequently asked questions

What eBay listing fields does eBay Price Tracker return?

The core fields are product_title, priceValue, priceDropPercent, watcherCount and bids β€” see the data fields section above for the complete list across listing details, demand metrics, and price-watch history.

Does eBay Price Tracker require an eBay account or login?

No. Every listing page is fetched as a public, unauthenticated page β€” the Actor's source code makes a plain page request with no OAuth flow or login step.

How many eBay listings can I track in one run?

There's no hard cap in the input schema or the code β€” watchlistUrls accepts as many links as you add, and each is processed one after another with a short randomized pause between requests.

What happens if a listing is delisted, ended, or removed?

eBay serves a fixed "item not found" page (a small stub or a full error page) for a removed listing, which the Actor recognizes by its status code and title. That listing is saved as an error row with success: false and errorReason: "not_found" instead of being retried, since no retry can bring back a listing that no longer exists.

Can I track multiple eBay listings at once?

Yes β€” pass an array of URLs in watchlistUrls. Every URL gets its own dataset row and its own independent price history, keyed by eBay item number.

Does eBay Price Tracker work with Claude, ChatGPT, and other AI agent tools?

Yes, as an HTTP endpoint. Any agent framework that can call the Apify API β€” via apify-client or a plain HTTP request β€” can trigger a run and read back the resulting JSON as a tool call.

What makes eBay Price Tracker's price data different from a single one-off scrape?

A one-off scrape only ever tells you today's price. eBay Price Tracker stores a snapshot per listing (keyed by watchlistId) after every run, so each new run can report previousPrice, priceChangedSinceLastRun, priceDropPercent, and the lowestPriceSeen/highestPriceSeen across all checks β€” computed from the same page fetch, with no extra requests.

Does eBay Price Tracker return data in a format LLMs can use directly?

Yes. Typed, normalized JSON with consistent field names across runs β€” no HTML parsing or CSS selectors needed. Pass it directly to an LLM, index it into a vector store, or feed it to an agent tool.

What happens when eBay changes its layout or anti-bot system?

The Actor is maintained and its output schema is designed to stay stable across eBay's page changes, since field extraction is isolated behind dedicated parsing functions rather than baked into the row structure. No specific turnaround time is promised for fixes.

Can I use eBay Price Tracker without managing proxies or browser infrastructure?

Yes β€” Apify Proxy rotation and session warming are handled internally; you don't need to supply your own proxies. Note this Actor does not run a headless browser: it fetches pages with a browser-impersonating HTTP client, which is enough for the fields it extracts.

Which eBay listing fields work best for AI training data and RAG indexing?

For RAG, index item_description, item_specifics and product_title β€” the highest-information text fields. For structured training data, priceValue, watcherCount, soldCount and priceHistory return as consistent typed primitives (numbers, booleans, and timestamped arrays) across every listing.

ScraperWhat it extracts
eBay Search ScrapereBay search-result listings and item URLs by keyword β€” feed the URLs straight into this Actor's watchlistUrls
Etsy Reviews Scraper With Sentiment & AnalyticsEtsy product reviews with sentiment scoring and analytics
Shein Search Products ScraperShein product search results and pricing

πŸ’¬ Your feedback

Found a bug or missing a field? Let us know via the Issues tab on this Actor's Apify Store page β€” that feedback goes directly into what gets fixed next.