# Changelog of eBay Sold Listings Scraper 💰 sold & live price comps (`tagadanar/ebay-sold-comps`) Actor

- **URL**: https://apify.com/tagadanar/ebay-sold-comps/changelog.md
- **Full Actor documentation**: https://apify.com/tagadanar/ebay-sold-comps.md

## Changelog

### 2026-10-01

- **Filtered searches stop when they stop matching.** With a tight price range
  or a condition set, eBay can keep serving page after page of listings that all
  fall outside what you asked for. The actor used to keep reading those pages
  (up to 50 per search) for rows it would never deliver. Now a search that
  returns three result pages in a row with nothing matching your filters is
  stopped there. Only what passes every filter counts — the price range, the
  condition, and listings not already seen in that search — so a search that is
  still finding matches, however few per page, is not affected, and a run with
  no filters behaves exactly as before.
- The run's status message names each search stopped this way, says how many
  pages and listings were read with nothing matching, and suggests widening the
  price range or the condition. It never reports such a search as having no
  results: eBay had listings, none matched. A run stopped by eBay's wall or by
  the run time limit is still reported as such.
- **Fixed: a run that delivered everything you asked for no longer reads as
  "incomplete".** A run that returned exactly your maximum number of results
  (say 40 of 40) could still say "the run is incomplete" if eBay's wall stopped
  a later page. It now leads with "40 listing(s) ..., the 40 asked for" and lists
  the wall, filtered rows, time limit or charge limit as notes. Runs that stop
  below your maximum keep the current wording.

### 2026-09-08

- **Fixed: runs from a European exit returned no listings at all.** eBay prints
  a price in the currency of the exit IP's region, not of the site — the same
  ebay.com search a US exit reads as `$232.00` comes back to a European one as
  `EUR 215.25`, an ISO code with no currency symbol. The parser only knew
  symbols, so it dropped every one of those rows as "not a real priced result":
  a 2.25 MB search page holding 206 real listings parsed as zero. This actor
  buys residential proxies, so which of the two a run saw was a coin toss, and
  the failure looked exactly like a quiet search.
- Prices now parse in all three shapes eBay ships: a symbol with its dollar-zone
  prefix (`$195.00`, `C $1,299.99`, `AU $50`), an ISO code in front
  (`EUR 215.25`, `GBP 12.34`), and a symbol or code behind the number
  (`215,25 €`). Both decimal conventions are read, so `1.299,99` and `1,299.99`
  are the same number, while `1,500` stays fifteen hundred. Where a page prints
  a local price and a US conversion beside it, the price eBay is charging in
  wins.
- Item location is read from `from Japan` as well as `Located in Japan` — the
  same fact in the wording each layout uses.
- The summary row now reports the currency the comps were actually quoted in, so
  an EUR page rolls up in EUR instead of being labelled USD.

### 2026-08-29 (later)

- **New: price range and condition filters.** Three new inputs, `priceMin`,
  `priceMax` and `condition` (any, new, used, or for parts). They go to eBay as
  its own search filters, so you page through fewer irrelevant results, and then
  they are applied a second time to the rows eBay actually sends back. eBay's
  filters leak (promoted tiles and multi-variation listings arrive outside the
  range you asked for), and on a comps actor one $20 broken unit is enough to
  move the median. Rows dropped by that second pass are never charged, and the
  run's status message says how many were dropped and why.
- A listing whose condition eBay does not state is kept, not dropped, so a gap
  in eBay's markup can never quietly remove data you paid to look for.
- If you set a minimum above the maximum, the two are swapped and the run says
  so, instead of returning nothing.

### 2026-08-29

- **Fixed: a short run gave up after one proxy attempt.** The time guard priced
  every retry at its worst case — a full 60-second timeout — and refused to
  start a retry it could not fit five times over. On a run of a few minutes that
  left room for exactly one attempt, so the search hit eBay's bot check, was
  refused in about a third of a second, and stopped there without ever rotating
  to the fresh exit IP that usually gets through. eBay's throttle is
  burst-shaped and scored per IP, so that rotation *is* the recovery. The actor
  now measures the time each attempt actually takes: the full ladder of five
  exits and fingerprints is walked while the clock allows, and only a genuinely
  spent run stops early.
- **Fixed: a run that ran out of time said eBay had blocked it.** A search
  stopped mid-rotation by the clock was reported as "eBay blocked every proxy IP
  and browser fingerprint", which also stopped the whole run and skipped every
  remaining search. A run stopped by the clock now reports the clock — "N of 5
  attempts tried before the crawl box closed" — ends successfully rather than
  red, does not spend a second walk double-checking a wall that was never
  proven, and never charges for the page it could not finish. The wall verdict
  is now reserved for a rotation ladder that really was walked to the end.
- Fixed: a short run timeout (180 s or less) reserved the whole budget for
  the finishing phase, so the run stopped immediately and returned nothing.
  Scraping now always keeps at least half of whatever time the run has.
- The run now watches its own clock. Long searches used to be killed by the
  platform timeout mid-page, losing every row that had not been pushed yet.
  The actor now stops walking pages while there is still time to charge and
  deliver what it collected, and ends **successfully** with a status message
  saying "Stopped at the run time limit: N rows delivered, raise the run
  timeout or lower maxResults."
- Page fetches are bounded by the time actually left, not by a fixed retry
  ladder. A single slow page could previously burn 5 minutes of retries past
  the point where the run had time for it.
- Honest limits in the input form: **Max listings** now tops out at 12,000
  (50 result pages × 240 items — the real depth of one eBay search) instead of
  advertising 20,000 that no run could reach, and **Products or eBay URLs**
  accepts up to 50 entries per run.
- Every run now ends with a status message, not only the empty ones — and a
  run that was blocked, cut short by the clock or stopped by your charge limit
  says which, instead of reporting "no listings matched".

### 2026-08-22

- A run that hits eBay's wall now stops instead of paying for every remaining
  search. The first blocked search is double-checked against the live-listings
  URL; if that is refused too, the run ends with a status message saying eBay
  blocked it, rather than finishing "successfully" with an empty dataset.
- Retries are now spaced out (1.2 s, 2.4 s, 3.6 s, 4.8 s). eBay's throttle is
  burst-shaped: five instant rotations look like exactly the traffic it exists
  to stop, and the same search answers normally a moment later.
- Any run that ends with zero listings now says why in its status message.

### 2026-07-12

- Invalid input no longer fails the run. The run now finishes cleanly with a clear explanation in its status message, so a typo or an empty list is easy to spot and fix.
- List inputs now accept datasets piped straight from another scraper: entries
  that are objects are read through their usual key names (url/link,
  query/keyword/title, name/company and similar) instead of being rejected.

### 2026-07-11

- Billing: on paid runs every row is billed before it is written, and a run
  now stops visibly if billing fails instead of continuing unbilled.
- Fixed a misleading "limit reached" log line when a run simply hit its own maxResults cap.

### 2026-07-10

- Fixed empty results on some searches: eBay serves two different result-page layouts and the actor now reads both.
- More reliable page fetching against eBay's bot checks.
- Price cut: $4.00 to $2.50 per 1,000 sold listings, and platform usage is now included in the price. What you see is the whole bill.

### 2026-07-09

- Initial public release on Apify Store.
- Scrape eBay sold and completed listings by keyword or by pasted eBay search URL.
- Clean records per sold item: item id, title, URL, sold price (numeric) and label, currency, sold date (ISO), condition, buying format, bids, shipping, item location, seller name and feedback, and image.
- Price-comps summary per search: sold count, average, median, lowest and highest sold price, and the date range. The comparison eBay keeps behind a paid Terapeak plan.
- Forces the sold and completed filter on any pasted URL, sorted by most recently ended for the freshest comps.
- Reads eBay's search results directly over HTTP, deduping by item id and walking pages until a page returns nothing new or your max is reached. No browser, no login.
- US residential proxy by default (eBay.com is the US storefront); override the proxy country to read another eBay market. Pay per sold listing returned, summary rows free, platform usage billed to your run, no subscription.
