eBay Scraper - Listings, Sellers & Sold Price Check avatar

eBay Scraper - Listings, Sellers & Sold Price Check

Under maintenance

Pricing

from $3.50 / 1,000 listings

Go to Apify Store
eBay Scraper - Listings, Sellers & Sold Price Check

eBay Scraper - Listings, Sellers & Sold Price Check

Under maintenance

Track competitor prices on eBay without the eBay API. Scrape any search into typed rows: price with currency, sold count, condition, shipping, seller username and feedback. Then pass item IDs to checkItems to see which ones sold, at what price and on what date. Hard cap on results.

Pricing

from $3.50 / 1,000 listings

Rating

0.0

(0)

Developer

Henry Crawl

Henry Crawl

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

eBay Scraper - Listings, Sellers, Feedback & Sold Count

Track competitor prices on eBay without the eBay API. Point it at any eBay search, category page or filtered listing URL and get typed rows back — no developer account, no OAuth, no rate-limit paperwork.

Every row carries the seller username, feedback percentage and feedback count that most eBay scrapers leave empty, prices already parsed into numbers with a currency code, the sold counter where eBay shows one, and a hard cap on how many listings a run may return so the bill cannot surprise you.

Common uses: repricing against competitors, tracking a category's price band over time, building a supplier or seller shortlist, and feeding price data into a dashboard.

What you get per listing

FieldExampleNotes
itemId197740124597Stable eBay id, use it to deduplicate across runs
titleYETI Rambler 20 oz Tumbler…
priceRaw$35.00Exactly as eBay rendered it
priceValue35Parsed number, ready to filter and aggregate
priceMax48.5Filled when the listing shows a price range
currencyUSDDerived from the rendered price
conditionBrand New
sellerNameoliviabrian1234
sellerFeedbackPercent100
sellerFeedbackCount4896K and 94.2K are expanded to real numbers
soldCount461Present on the listings where eBay shows it
watchers60
bidCount3Auctions only
shippingRaw+$28.60 delivery
shippingValue28.60 when shipping is free
freeShippingfalse
itemLocationUnited StatesWhere the item ships from
imageUrl, itemUrl
pageNumber, searchKeyword, inputUrlProvenance of every row
ebaySite, proxyCountry, scrapedAtThe exact context the data was captured in

1. Build a search from filters — no URL needed. Add one or more keywords; each runs as its own search with the same filters:

{
"keywords": ["yeti rambler 20 oz tumbler", "stanley quencher 40 oz"],
"ebaySite": "www.ebay.com",
"proxyCountry": "US",
"condition": "new",
"buyingFormat": "buy_it_now",
"minPrice": 20,
"maxPrice": 60,
"sortBy": "price_lowest",
"maxListings": 2000
}

2. Paste URLs — any eBay search, category or filtered listing page:

{
"startUrls": [
"https://www.ebay.com/sch/i.html?_nkw=yeti+rambler&_sacat=0&rt=nc&LH_BIN=1"
],
"proxyCountry": "US",
"maxListings": 500
}

Filters available: eBay site, keyword exclusions, category, min/max price, condition, buying format, free shipping, and the same sort options as eBay's own dropdown.

eBay puts sold search behind sign-in — signed out, …&LH_Sold=1&LH_Complete=1 redirects to signin.ebay.com/...&sgfl=srch. Getting past that would mean running automated searches through a real eBay account, and the account, not the scraper, is what eBay suspends. This actor does not go there.

An individual listing page is a different surface, and it is open: signed out it answers normally, eBay's robots.txt allows /itm/<id>, and the sale is stated in plain text. So pass checkItems the listings you care about and get the real numbers:

{
"checkItems": [
"225076150467",
"https://www.ebay.com/itm/223223631102",
"398249946847"
],
"proxyCountry": "US"
}
223223631102 SOLD AU $9.98 sold 2026-07-09T06:19:17.000Z
225076150467 SOLD C $40.00 sold 2026-07-12T01:24:17.000Z
398249946847 ACTIVE US $100.00
186082326577 ENDED_NOT_SOLD US $9.99
117340485562 ENDED_PRICE_UNAVAILABLE

saleStatus is the field to trust, and it has five values:

ValueMeaning
SOLDIt sold. soldAt carries the exact timestamp, price what it went for
ACTIVEStill listed; price is the current asking price
ENDED_NOT_SOLDThe seller pulled it. Not a sale
ENDED_NO_SALEAn auction closed with no bids
ENDED_PRICE_UNAVAILABLEEnded auction on a catalogue-matched item — see the limit below

Why not just read availability? Because eBay marks a pulled listing OutOfStock exactly like a sold one. Treating that as a sale quietly turns unsold stock into fake comps, and nothing downstream can spot the error. The sentence eBay prints is the only field that separates them, so that is what saleStatus is built from.

The honest limits

  • There is no keyword search for sold items here. That is the part eBay gates. You supply the listings — usually item IDs a previous search run returned, re-checked days later.
  • Ended auctions can lose their final price. When the item matches an eBay catalogue product, eBay redirects the ended listing to that catalogue page, which does not show the winning bid. Those rows come back ENDED_PRICE_UNAVAILABLE with no price rather than carrying the catalogue's asking price as if it were a sale.
  • One page per row. A search page yields up to 240 listings; a listing page yields one. Set maxListings accordingly — it caps this mode too.
  • checkItems ignores keywords and startUrls; run the search separately.

Still free, still public: soldCount on active listings — the "X sold" figure eBay prints — needs no item check at all and comes with every search row.

Proxy country matters more than you would expect

eBay localises listing pages: prices, currency, shipping costs, and even which listings appear depend on the country of the IP making the request. Requesting www.ebay.com from outside the US can return prices in a different currency entirely. Set proxyCountry to the market you care about — it defaults to US.

ebaySite and proxyCountry are independent: ebaySite picks which regional eBay to load, proxyCountry decides which market you appear to be shopping from.

Residential proxies are used by default. eBay refuses datacenter IP ranges, so a datacenter group will simply produce a failed run.

The result cap is real

maxListings stops the run at exactly that number. Scrapers that treat their limits as suggestions produce surprise bills; this one exits as soon as the cap is met, and also stops on its own if three consecutive pages return nothing usable.

Runs fail loudly, not silently

Every run writes a DIAGNOSTICS record to the key-value store with the block rate, bytes per item, and the fill rate of every single output field:

{
"itemsExtracted": 200,
"blockRate": "0%",
"mbPer1000Items": 19.06,
"fieldCoverage": { "priceValue": "100%", "sellerName": "92%", "currency": "100%" }
}

If nothing was extracted, or more than half the pages were blocked, the run is marked failed with the reason. A dataset full of empty columns is worse than an error, because the problem only shows up after you have used the data.

Typical uses

  • Competitor and marketplace price monitoring, with the seller behind each price
  • Turnover research using soldCount on live listings
  • Tracking which sellers list a given brand, and at what price
  • Building product and pricing datasets for internal tools or dashboards

Notes and limits

  • soldCount and watchers appear only on the listings where eBay displays them; they are reported as null elsewhere rather than guessed.
  • eBay places a promotional label in the footer of every result card, organic ones included, so this actor does not claim to separate promoted listings from organic ones. It does drop the "Shop on eBay" placeholder cards, which carry no data.
  • Keep maxConcurrency low. eBay authorises by session, so parallelism burns sessions faster than it saves time.

Support

Found a field that stopped filling, or need a filter that is not exposed yet? Open an issue on the actor page with the input you used — layout changes on eBay are normal and get fixed.

FAQ

Do I need an eBay API key or developer account? No. This reads eBay's public search and category pages, so there is nothing to register for and no OAuth flow. You only need an Apify account.

How do I get eBay sold prices without the API? Read the listing page instead of the search. An individual /itm/<id> page is public — it answers a signed-out request normally, and eBay's robots.txt allows that path — and it states the sale outright: "This listing sold on Sat, Jul 11 at 6:24 PM." Pass those item IDs to checkItems and you get the sold price, the exact ISO timestamp and the seller, with no key, no OAuth and no account. What stays out of reach is searching sold items by keyword; that particular page is the one eBay puts behind sign-in.

I applied for eBay's Marketplace Insights API and was denied. What are the alternatives? That API returns 90 days of sold data but is Limited Release, and denials are the norm rather than the exception — developers with apps in production for years and thousands of users report being turned down, including ones already in the eBay Partner Network. Rather than reapply, two public sources cover most of what it was wanted for: soldCount on active listings (the "X sold" figure eBay prints itself) and checkItems on specific listings, which returns the actual sale price and date from the listing page.

How can I tell whether an eBay listing ended because it sold or because the seller pulled it? Not from the availability field, which is the usual mistake — eBay marks both cases OutOfStock. The difference is the sentence eBay prints on the page, and this actor reads it: This listing sold on … becomes saleStatus: SOLD, while

This listing was ended by the seller on … because …
becomes ENDED_NOT_SOLD, and an auction that closed without bids becomes ENDED_NO_SALE. Treating "ended" as "sold" is what quietly fills a comps table with prices nobody ever paid.

Can I get eBay sold data without logging in? For specific listings, yes — listing pages are served to signed-out visitors, and that is all checkItems uses. For keyword searches of sold items, no: signed out, a sold search redirects to signin.ebay.com. The workarounds circulating for that involve driving automated searches through a real eBay account, and it is the account that gets suspended, so this actor does not implement them.

Can it get sold prices and completed listings? Yes for specific listings, no for keyword searches. Pass checkItems a list of item IDs or /itm/ URLs and each row comes back with saleStatus, the actual sold price and the exact sale timestamp, read from the public listing page — no eBay account or cookies involved. What it cannot do is search for sold items by keyword: that surface is behind eBay's sign-in wall, and the only way through is to automate someone's real account, which risks that account.

How do I get the item IDs to check? From a search run of this same actor. Scrape a keyword today, keep the itemId column, then feed those IDs to checkItems a week later — the ones that come back SOLD give you the price and the date they sold at, which is the turnover picture sold comps are usually bought for.

Does an ended listing always mean it sold? No, and this is where sold data usually goes wrong. eBay marks a listing the seller pulled as OutOfStock, exactly like one that sold. This actor reads the status sentence instead, so a pulled listing returns ENDED_NOT_SOLD and never enters your dataset as a sale.

Why do my prices come back in the wrong currency? eBay prices by IP country. Requested from outside the US, ebay.com can answer in the local currency with local delivery. Set proxyCountry to match the marketplace you actually want, and check the currency field on the rows rather than assuming.

How do I avoid a surprise bill? maxListings is a hard stop, not a suggestion. The run also fails loudly rather than returning half a dataset: zero items, or a block rate above 50%, ends the run with an error so you never pay for a quietly incomplete scrape.

What happens when eBay blocks a request? The session is retired and the request retried on a fresh one. Every run reports its block rate, bytes per item and per-field coverage in the log, so you can see the quality of the data instead of guessing.

How do I get eBay sold data? Three routes exist and only one is open to most people. eBay's Marketplace Insights API returns 90 days of sold data but is Limited Release, and denials are routine — developers with apps in production for years report being turned down. Terapeak shows the same data in a browser but has no public API behind it. The third route is the listing page itself: /itm/<id> is served to signed-out visitors, eBay's robots.txt allows it, and it states the outcome in plain text along with an exact timestamp. That is what checkItems reads. You supply the item IDs — typically ones a search run of this actor returned earlier — and you get back the real sale price and date.

How do I find eBay sold prices for items I am tracking? Run a search for the products you care about and keep the itemId column, then pass those IDs to checkItems a few days or weeks later. Listings that sold come back saleStatus: SOLD with the price they went for and an exact soldAt timestamp; ones still running come back ACTIVE with the current asking price. Repeating that on a schedule is what turns a list of listings into a price history, and none of it needs an eBay account.

Is there an eBay sold listings API I can call? Not a public one from eBay. This actor is the closest practical substitute for the item-level case: give it eBay item IDs and it returns typed rows — saleStatus, price, currency, soldAt, sellerName, quantitySold — over Apify's normal API, so you can call it from any language. The honest gap versus the official API is search: eBay gates keyword search of sold items behind sign-in, so this cannot find sold items by keyword, only report on listings you already have IDs for.

How do I see eBay sold history without a browser extension? The sold-history extensions people use are reading the same public pages, one at a time, in your browser. This does it server-side and in bulk, and returns typed rows instead of a rendered page, which is the difference that matters if you want the numbers in a spreadsheet or a database rather than on screen.

How do I build an eBay price history for a product? By snapshotting it yourself, because eBay does not publish one. Run a search for the product on a schedule and keep every row — each carries priceValue, currency, soldCount and scrapedAt, so a week of runs is already a price series with the seller behind each point. Where it gets more useful is combining that with checkItems: feed back the itemId values from earlier runs and the listings that have since sold return SOLD with the price they actually went for and an exact timestamp, which turns an asking-price series into a record of what the market paid.

Same approach applied elsewhere — typed rows, a cap that is actually enforced, and a diagnostics record on every run: