eBay Scraper — Active & Sold Listings, Prices & Analytics
Pricing
from $5.00 / 1,000 detailed item (full item page)s
eBay Scraper — Active & Sold Listings, Prices & Analytics
Scrape eBay active & sold listings across 17 marketplaces. Search by keyword or URL — get prices, sold price & date, sell-through rate, condition, shipping, item specifics, identifiers (UPC/MPN), images & seller details. Fast/full-detail modes + change monitoring
Pricing
from $5.00 / 1,000 detailed item (full item page)s
Rating
5.0
(5)
Developer
Muhamed Didovic
Maintained by CommunityActor stats
1
Bookmarked
745
Total users
278
Monthly active users
3.5 hours
Issues response
20 hours ago
Last modified
Categories
Share
eBay Search Results and Listing Details Scraper
Overview
The eBay Search Results and Listing Details Scraper allows you to efficiently extract detailed product information from eBay's search results as well as the product details page for each item. Whether you're interested in gathering insights for market analysis, tracking product trends, or simply collecting eBay data for competitive research, this scraper can help streamline the process.
Search by plain keyword (with condition, price, sort, listing-type, free-shipping, seller & category filters) or paste eBay URLs, which keep the filters you set on eBay: item location, brand and other item specifics, several conditions, accepts offers, sellers to include or exclude. Scrape active listings, sold/completed listings (real sold prices + sell-through rate for comps), or both — across 17 marketplaces. Choose fast search-results data or detailed item-page enrichment, and optionally monitor for new listings and price changes between runs.
With eBay hosting millions of products, this scraper is a useful tool for scraping structured data from search result listings and diving into individual product details for in-depth analysis.
🚀 Try It Now
Get started with our scraper in seconds:
- Open this actor in Apify Console (Try for free on this page)
- Enter your target eBay URLs
- Start scraping!
🌟 Real-World Examples
Seller and store names in these examples are placeholders. Put a real eBay username in place of <seller>, <store>, seller1 and seller2 before you run them.
1. Search with Seller Filter
https://www.ebay.com/sch/i.html?_nkw=louis+vuitton&_ssn=<seller>
2. Seller Store Page
https://www.ebay.com/str/<store>
3. Several Sellers at Once
https://www.ebay.com/sch/i.html?_nkw=running+shoes&_fss=1&LH_SpecificSeller=1&_saslop=1&_sasl=seller1%2Cseller2
Only listings from the sellers you name; _saslop=2 leaves them out instead. Store categories (store_cat) are not supported: a /str/ URL always returns the whole store.
4. A Whole eBay Category (no keyword)
https://www.ebay.de/sch/i.html?_sacat=33717
Every listing in the category (here ebay.de's Blinkleuchten, turn-signal lamps), in eBay's order; set Marketplace to ebay.de. Add a keyword, or an item-specific filter copied from eBay, to narrow it.
A plain category page also works pasted as it is: https://www.ebay.com/b/Cell-Phones-Smartphones/9355/bn_320094 is scraped through eBay's search as category 9355 (Cell Phones & Smartphones), so sold mode, the sold-price summary and fast mode all work; brand, model and curated /b/ pages are covered under Category pages (/b/ URLs).
5. Individual Product Page
https://www.ebay.co.uk/itm/226771215916
Set Marketplace to ebay.co.uk for an ebay.co.uk URL.
6. Keyword Search with Filters (no URL needed)
{ "searchQuery": "vintage rolex submariner", "condition": "used", "minPrice": 2000, "sortBy": "price_asc" }
7. Sold Price Comps on a Regional Marketplace
{ "searchQuery": "pokemon charizard psa 10", "mode": "sold", "marketplace": "ebay.co.uk" }
8. Fast / Cheap Active Listings (search-results data only)
{ "searchQuery": "mechanical keyboard", "detailedItems": false, "maxItems": 2000 }
9. Seller Feedback / Buyer Reviews
{ "feedbackProfiles": ["<seller>"], "feedbackReceivedAs": "seller", "maxItems": 500 }
Scrapes a seller's buyer-review feedback profile, one row per review. Accepts a username, a /fdbk/feedback_profile/… URL, or a /usr/… URL (you can also paste a /fdbk/ URL into Start URLs).
10. eBay Motors — Vehicles & Parts
{ "searchQuery": "honda civic", "motorsCategory": "6001", "minYear": 2018, "maxYear": 2022, "condition": "used" }
Pick a Motors preset (Cars & Trucks, Motorcycles, Boats, RVs, parts categories…) plus an optional model-year range — no category IDs or URL building needed. Vehicle listings return a structured vehicle object (year, make, model, trim, mileage, VIN, transmission, fuel type, colors, title status…) when detailed mode is on.
11. A Whole Keyword List in One Run
{ "searchQueries": ["lego 42115", "lego 42143", "lego 42083"], "mode": "sold", "marketplace": "ebay.co.uk", "maxItems": 200, "titleMustMatchQuery": true }
Each keyword runs as its own search with the same marketplace, mode and filters, and maxItems applies to each keyword. Every row says which keyword found it (searchQuery), and sold searches return one price summary per keyword. titleMustMatchQuery keeps each keyword's rows to listings whose title contains that keyword, so eBay's near matches stay out of its rows and its summary.
12. Filters Copied From eBay
{ "startUrls": [{ "url": "https://www.ebay.de/sch/i.html?_nkw=laufschuhe&Marke=Nike&LH_LocatedIn=1&_salic=77" }], "marketplace": "ebay.de", "detailedItems": false }
Nike running shoes located in Germany. Set the filters on eBay, copy the address bar, and set Marketplace to the same site. The next section lists what carries over.
🔗 Filters you can paste
Build the search on eBay's own site, click the filters you want, then copy the address bar into Start URLs. eBay applies the filters and the actor pages through the results, one row per listing. Each filter below was checked in October 2026 against eBay's mobile search, which is what this actor reads, by comparing one page of results with and without it.
Check the shape of the copied address first. The filters carry over from search URLs shaped /sch/i.html?… (and from /usr/<seller> and /str/<store> pages). eBay often writes a category search as /sch/<number>/i.html?… (or /sch/<name>/<number>/i.html?…). Paste it as it is: it is searched as /sch/i.html?_sacat=<number>&… with its other parameters. A plain category page (/b/<name>/<number>/bn_<id>) can be pasted as it is; for other /b/ pages see Category pages (/b/ URLs). Any other shape is read from eBay's website instead: Listing mode, fast mode and the actor's own filters do not apply there, every row is a detailed row, and the website can block the run.
| Filter | Add to a /sch/i.html URL | What the check showed |
|---|---|---|
| Items located in one country | LH_LocatedIn=1&_salic=45 (45 = China) | 212 of 212 results "Located in China" |
| Only items in the site's own country | LH_LocatedIn=1&_salic=77 on ebay.de (codes for every site below) | 212 of 212 domestic; without it, 21 of 212 came from abroad |
| Brand or any other item specific | Brand=Nike on ebay.com, Marke=Nike on ebay.de | "Nike" in 212 of 213 titles, against 9 of 213 without |
| Several conditions at once | LH_ItemCondition=1000%7C3000 (New or Used; %7C joins two condition codes) | only Brand New and Pre-Owned left; New (Other) dropped out |
| Accepts offers | LH_BO=1 | 213 of 213 rows bestOfferEnabled |
| Free shipping | LH_FS=1 | 213 of 213 rows with free shipping |
| A whole category, no keyword | _sacat=33717 on ebay.de, with no _nkw | 199 of 212 titles name a turn signal (the category is Blinkleuchten, turn-signal lamps) |
| Category plus item specific | _sacat=9355&Brand=Apple on ebay.com | 211 of 212 titles Apple or iPhone |
| A plain category page | paste /b/<name>/<id>/bn_<id> as it is | searched as _sacat=<id>; other /b/ pages: see Category pages (/b/ URLs) |
| Only these sellers | _fss=1&LH_SpecificSeller=1&_saslop=1&_sasl=seller1%2Cseller2 | only the two sellers |
| Leave out these sellers | the same with _saslop=2 | none of the three listed sellers, who had 37 of 213 rows without it |
| Sold listings with filters | any of the above, with Listing mode set to Sold | Brand=Nike&LH_ItemCondition=1000: 200 of 200 sold rows Brand New |
Copy filters from the site you are scraping. Item-specific names are in that site's language. On ebay.de Marke=Nike filtered (Nike in 210 of 211 titles) while Brand=Nike changed nothing. eBay drops a filter it does not recognise without any error, so a mistyped filter returns, and bills, the unfiltered results. If a copied URL contains LH_PrefLoc, which the mobile search ignores, replace it with LH_LocatedIn=1&_salic=<code> from the table below.
Few matches can come with extra rows. When a filter leaves fewer listings than one page holds (about 200), eBay can fill the page with near matches under a "Results matching fewer words" or "items found from eBay international sellers" heading. In one check, an ebay.ph search with 4 matching listings came back with 200 more from other countries. The actor returns those rows and they are billed like any other, so try a new URL with a small Max number of items first.
Set Marketplace to the site your URLs come from. A regional domain in a URL (ebay.de, ebay.co.uk, …) picks the site for that URL, and an ebay.com URL is searched on the Marketplace site. A /b/ category URL and a /sch/<number>/i.html category search are the exception: they are always searched on their own site, so a www.ebay.com /b/ URL is searched on ebay.com whatever Marketplace says. The connection country always follows Marketplace (on the free plan, your proxy setting), and eBay shows a connection from outside a site's country only part of that site: on ebay.com, a connection from outside the US got 393 of the 594 sold results that a US connection got. Run ebay.de URLs with Marketplace set to ebay.de, and put URLs from different sites in separate runs.
Location labels. itemLocation is eBay's own label, and its form depends on the site. On ebay.com search rows read Located in <country>. ebay.co.uk, ebay.de, ebay.fr, ebay.it, ebay.com.au, ebay.ca and ebay.ch label only listings from abroad (from Italy), so a listing in the site's own country has no itemLocation. ebay.com.hk, ebay.com.my, ebay.ph and ebay.com.sg label every listing, their own country included (from Singapore). A single /itm/ URL reports the item page's location instead, such as Southall, United Kingdom.
What applies to a pasted /sch/i.html, /sch/<number>/i.html, /usr/ or /str/ URL: Listing mode (Sold adds eBay's sold filter for you), Sold within last N days, Title must match the search keyword (it uses the URL's own _nkw), Title must include, Min/Max model year, monitoring mode, Fetch full item details, Include the seller's full description, and Max number of items, which counts per URL (in Both mode, per URL for active and again for sold). What does not: Condition, Min/Max price, Sort by, Listing type, Free shipping only, Returns accepted only, Category ID and eBay Motors category build keyword searches only; put those filters in the URL instead. Search query, Search queries and Seller start a separate search of their own, billed like the rest, when set next to Start URLs; they do not filter your URLs. To narrow a URL to one seller, add _ssn=<seller> to it.
The same search twice runs once. Two Start URLs that are one search on one site (the same filters in another order, or a keyword next to its own URL) are scraped once, and the run log names the repeat. The same search on two eBay sites is two searches. In Both mode, a URL that already holds LH_Sold=1&LH_Complete=1 runs once, as a sold search.
Monitoring history is kept per exact URL. Changing a URL, even by adding a filter, starts a new history, and the next run is the first run of that history (see Monitoring mode under Input Fields Explanation). A /b/ category page or a /sch/<number>/i.html search scraped through eBay's search also skips every listing an earlier monitoring run read from an eBay web page (earlier runs of that same URL included), so it does not return them again. Its first run on eBay's search is still a first run (see Monitoring mode under Input Fields Explanation).
Paging is automatic. _pgn and _ipg in a pasted URL do not limit the run: it starts at page 1 and stops at Max number of items or at the last result. A sort order in the URL (_sop=) is kept.
Category-only URLs return everything filed in that category in eBay's order, including listings that sellers put in the wrong category. A keyword or an item-specific filter tightens it.
Not supported. eBay's mobile search ignores these, so the run would return unfiltered results:
- store categories (
store_cat=on a/str/page returns the whole store; narrow a seller with a keyword instead,/sch/i.html?_ssn=<seller>&_nkw=<words>) - Preferred location (
LH_PrefLoc); useLH_LocatedIn=1&_salic=<code>from the table below - distance or ZIP-code radius, and sorting by distance
- sold-date ranges; use Sold within last N days
One example per site
Each URL keeps only listings located in the site's own country. Every code was checked in October 2026 and returned only listings from its country, either on its own site or pasted on ebay.com, where every row names its country. Swap the keyword for your own and add any filter from the table above.
| Site | Example start URL | Own-country _salic |
|---|---|---|
| ebay.com | https://www.ebay.com/sch/i.html?_nkw=running+shoes&LH_LocatedIn=1&_salic=1 | 1 |
| ebay.co.uk | https://www.ebay.co.uk/sch/i.html?_nkw=lego&LH_LocatedIn=1&_salic=3 | 3 |
| ebay.de | https://www.ebay.de/sch/i.html?_nkw=laufschuhe&Marke=Nike&LH_LocatedIn=1&_salic=77 | 77 |
| ebay.fr | https://www.ebay.fr/sch/i.html?_nkw=nintendo+switch&LH_LocatedIn=1&_salic=71 | 71 |
| ebay.it | https://www.ebay.it/sch/i.html?_nkw=macbook&LH_LocatedIn=1&_salic=101 | 101 |
| ebay.es | https://www.ebay.es/sch/i.html?_nkw=iphone&LH_LocatedIn=1&_salic=186 | 186 |
| ebay.ca | https://www.ebay.ca/sch/i.html?_nkw=hockey+jersey&LH_LocatedIn=1&_salic=2 | 2 |
| ebay.com.au | https://www.ebay.com.au/sch/i.html?_nkw=airpods+pro&LH_LocatedIn=1&_salic=15 | 15 |
| ebay.nl | https://www.ebay.nl/sch/i.html?_nkw=fiets&LH_LocatedIn=1&_salic=146 | 146 |
| ebay.at | https://www.ebay.at/sch/i.html?_nkw=ski&LH_LocatedIn=1&_salic=16 | 16 |
| ebay.ch | https://www.ebay.ch/sch/i.html?_nkw=uhr&LH_LocatedIn=1&_salic=193 | 193 |
| ebay.ie | https://www.ebay.ie/sch/i.html?_nkw=iphone&LH_LocatedIn=1&_salic=99 | 99 |
| ebay.pl | https://www.ebay.pl/sch/i.html?_nkw=iphone&LH_LocatedIn=1&_salic=163 | 163 |
| ebay.com.hk | https://www.ebay.com.hk/sch/i.html?_nkw=iphone&LH_LocatedIn=1&_salic=92 | 92 |
| ebay.com.my | https://www.ebay.com.my/sch/i.html?_nkw=iphone&LH_LocatedIn=1&_salic=127 | 127 |
| ebay.ph | https://www.ebay.ph/sch/i.html?_nkw=shoes&LH_LocatedIn=1&_salic=162 | 162 |
| ebay.com.sg | https://www.ebay.com.sg/sch/i.html?_nkw=watch&LH_LocatedIn=1&_salic=180 | 180 |
Run each with Marketplace set to the same site. On the smaller sites a narrow keyword can match only a few local listings and bring in the extra rows described above; ebay.ph had 4 local results for iphone and 67 for shoes.
✨ Features
-
Keyword Search & Filters (no URL building required)
- Search by plain keyword (
searchQuery) instead of hand-crafting eBay URLs - Search a whole keyword list (
searchQueries, up to 500) in one run. Each keyword is its own search with its ownmaxItems, its own sold summary (a separate charged row) and its own monitoring state. Every row is tagged with the keyword that found it, and the run's status line names any keyword that returned nothing, was not reached, or had no exact matches. It also names searches that lost pages and stopped early (see Run Status and Partial Results). - Filter by condition (New / Used / Refurbished / Open box / Certified pre-owned / For parts), min/max price, and sort order
- Or paste raw eBay URLs — both work through the same pipeline
- Search by plain keyword (
-
eBay Motors — Vehicles & Parts
- Category presets for Cars & Trucks, Motorcycles, Boats, RVs & Campers, Powersports, Commercial Trucks, and all major parts categories (
motorsCategory) - Model-year range filter for vehicle searches (
minYear/maxYear) - Structured
vehicleoutput object on vehicle listings: year, make, model, trim, mileage, VIN, transmission, fuel type, body type, drivetrain, engine, colors, title status
- Category presets for Cars & Trucks, Motorcycles, Boats, RVs & Campers, Powersports, Commercial Trucks, and all major parts categories (
-
Active, Sold & Completed Listings
mode: active (live listings), sold (confirmed sold prices for comps, mostly from the last ~90 days;soldWithinDayssets an exact window), or both- Sold rows include the actual sold price and sold date — ideal for resale pricing, market research, and Terapeak-style comps
-
17 eBay Marketplaces
- US, UK, DE, FR, IT, ES, CA, AU, NL, AT, CH, IE, PL, HK, MY, PH, SG
- Set
marketplaceto the site you scrape. A pasted regional URL (ebay.co.uk,ebay.de, …) picks its site, but the connection country followsmarketplace. Prices come in the site's currency
-
Sell-through & demand analytics (sold / both mode)
- Per search: avg / median / min / max sold price + a recommended price
- Plus sell-through rate, total sold, total active, and units-sold-per-day — the Terapeak-style demand metric
-
Fast or Detailed (cost control)
detailedItems: false→ returns rich data straight from the search results (price, condition, shipping and shipping cost, seller name and feedback score, image, availability) — much faster & cheaperdetailedItems: true(default) → also visits each item page for item specifics, gallery images, seller details, returns and product identifiersincludeDescription: true→ adds the seller's own description text in either mode (one extra request per item)
-
Comprehensive Data Extraction
- Product titles, prices (display + numeric + currency), conditions, shipping (display, numeric cost and price + shipping total), and seller name / feedback score on every row
- Auction info (bid count, time left) and Buy-It-Now
- Seller details and ratings, item specifics and, with
includeDescription, the seller's own description - Product images and variations
- Sold price & sold date for completed listings
-
Paste any filtered eBay search
- Search results, seller pages, stores, category pages (/b/…), single items and seller-feedback URLs from all 17 sites
- Filters you set on eBay carry over: item location, brand and other item specifics, several conditions at once, accepts offers, free shipping, category browse, sellers to include or exclude (see Filters you can paste)
-
Seller Feedback / Buyer Reviews
- Scrape a seller's full feedback profile — one row per review: comment, sentiment (positive / neutral / negative), masked buyer + their feedback score, linked item (title / ID / URL / price), relative date
- Input via
feedbackProfiles(usernames or feedback URLs) or a/fdbk/Start URL; filter by sort (recent / relevant), rating, received-as (seller / buyer / both), images-only, and exclude-automated - Paginated (thousands of reviews per seller) for reputation analysis, seller due diligence, and competitor monitoring
-
Change & Price Monitoring
monitoringModereturns only new listings vs. previous runsenablePriceMonitoringflags items whose price changed since the last run
-
Reliable Performance
- Search, seller, store and item URLs are read through eBay's mobile API, which sits outside the website's bot protection (Datadome); other eBay page types fall back to the website and can be blocked
- Explicit, loud failure handling: a bad/404 URL, an expired auth token, and a genuinely empty (0-result) search are reported distinctly — no silent failures
- Customizable concurrency, automatic retry with session/proxy rotation, efficient pagination, structured JSON output
How to Use
- Set Up: Ensure you have an Apify account and access to the Apify platform.
- Provide a search: type a Search query, list several keywords in Search queries (
searchQueries, each one runs as its own search), or paste eBay URLs into Start URLs. A pasted search URL keeps the filters you set on eBay (see Filters you can paste). - Adjust Scraper Settings: Modify settings such as
maxConcurrency,minConcurrency, andmaxRequestRetriesto match your requirements. - Pick the Marketplace: set it to the eBay site you are searching. On a paid Apify plan the actor then connects from that country by itself; on the free plan, also set the proxy country (see below).
- Run the Scraper: Execute the scraper on the Apify platform. The output will be available in various formats, including JSON, CSV, or Excel.
⚠️ Important: Marketplace and Connection Country
eBay shows each connection the version of a site that matches the connection's country, and a connection from outside a site's country sees only part of it: on ebay.com, a connection from outside the US got 393 of the 594 sold results that a US connection got. The country the actor connects from matters as much as the URL.
- Paid Apify plan: nothing to configure. The actor connects through a residential address in the Marketplace country (US for ebay.com, GB for ebay.co.uk, and so on) and does not use the proxy setting.
- Free plan: the proxy setting is used. Keep the
RESIDENTIALgroup and setapifyProxyCountryto the Marketplace country.
Either way, set Marketplace to the site your start URLs come from, and put URLs from different sites in separate runs.
Proxy Setup on the Free Plan
A free run checks Apify Proxy once before it starts. If Apify Proxy refuses the country (HTTP 407), the run goes on without a country and says so in the log, so results can differ by region. If it refuses the settings without the country too, the run ends at once and its message names the settings to change.
For US eBay (ebay.com):
{"proxy": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"],"apifyProxyCountry": "US"}}
For UK eBay (ebay.co.uk):
{"proxy": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"],"apifyProxyCountry": "GB"}}
For German eBay (ebay.de):
{"proxy": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"],"apifyProxyCountry": "DE"}}
Country Codes Reference
Match the proxy country to the marketplace:
US- United States (ebay.com)GB- United Kingdom (ebay.co.uk)DE- Germany (ebay.de)FR- France (ebay.fr)IT- Italy (ebay.it)ES- Spain (ebay.es)CA- Canada (ebay.ca)AU- Australia (ebay.com.au)NL- Netherlands (ebay.nl)AT- Austria (ebay.at)CH- Switzerland (ebay.ch)IE- Ireland (ebay.ie)PL- Poland (ebay.pl)HK- Hong Kong (ebay.com.hk)MY- Malaysia (ebay.com.my)PH- Philippines (ebay.ph)SG- Singapore (ebay.com.sg)
Input Configuration
Here is an example input. Start URLs can be:
- Search results pages (
/sch/i.html?…, or a category search/sch/<category id>/i.html?…), with any filters you set on eBay - Seller and store pages (
/usr/<seller>,/str/<store>): every listing by that seller - Individual item pages (
/itm/<id>): one detailed row per item
{"startUrls": [{ "url": "https://www.ebay.com/sch/i.html?_nkw=louis+vuitton&_ssn=<seller>" },{ "url": "https://www.ebay.com/str/<store>" },{ "url": "https://www.ebay.com/sch/i.html?_nkw=running+shoes&Brand=Nike&LH_ItemCondition=1000%7C3000" },{ "url": "https://www.ebay.com/sch/i.html?_sacat=9355&Brand=Apple" }],"marketplace": "ebay.com","mode": "active","detailedItems": true,"maxItems": 1000,"maxConcurrency": 5,"minConcurrency": 1,"maxRequestRetries": 20,"proxy": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"],"apifyProxyCountry": "US"}}
Each start URL is an object with a url key. All four are on ebay.com, matching marketplace. <seller> and <store> stand for a real seller username and store name. For a single item from another site use e.g. { "url": "https://www.ebay.co.uk/itm/226771215916" } with "marketplace": "ebay.co.uk".
Or skip URLs entirely and search by keyword:
{"searchQuery": "iphone 16 pro 256gb","marketplace": "ebay.co.uk","mode": "sold","condition": "used","minPrice": 200,"maxPrice": 900,"sortBy": "price_asc","maxItems": 500,"proxy": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"],"apifyProxyCountry": "GB"}}
Or search many keywords at once:
{ "searchQueries": ["iphone 16 pro 256gb", "iphone 16 pro max 256gb"], "marketplace": "ebay.com", "mode": "sold", "condition": "used", "maxItems": 200, "titleMustMatchQuery": true }
In the Console you can leave the example Start URL as it is: while searchQueries is in use, an untouched example is ignored.
Input Fields Explanation
-
Start URLs (
startUrls): URLs to start scraping from (optional if you usesearchQueryorsearchQueries), from any of the 17 sites. These can be:- Search results pages,
https://www.ebay.com/sch/i.html?…orhttps://www.ebay.com/sch/<category id>/i.html?…, with any filters set on eBay (see Filters you can paste) - Seller pages,
https://www.ebay.com/usr/<seller>, and stores,https://www.ebay.com/str/<store> - Category pages (e.g.,
https://www.ebay.com/b/Cell-Phones-Smartphones/9355/bn_320094), see Category pages (/b/ URLs) - Individual product pages,
https://www.ebay.co.uk/itm/123456789 - Seller feedback pages,
https://www.ebay.com/fdbk/feedback_profile/<seller>
In the Console you can also upload a text file of URLs, or link one, with the Start URLs editor's bulk options (one URL per line). A URL typed without
https://gets it added. An entry that is not a URL is skipped with a note in the log, and the other searches still run.A category search shaped
/sch/<category id>/i.htmlis searched as/sch/i.html?_sacat=<category id>&…with its other parameters. When eBay's search refuses its category (a top-level category with no keyword, or a category id eBay does not know), the URL is read from eBay's website instead. A/b/page that is not a plain category is read from eBay's website instead (unlesscategoryPageModesays otherwise; see Category pages (/b/ URLs)). On the website, fast mode and the actor's own filters do not apply, every row is a detailed row, and the website can block the run. Listing mode does not apply there either, with one exception: for a/b/page that has a category number, Sold and Both add eBay's sold filters to the page URL. All Start URLs read from the website share one Max number of items between them. - Search results pages,
-
Search Query (
searchQuery): Search by keyword instead of building URLs — e.g."iphone 16 pro". Combined with the marketplace, mode, condition, price and sort options below. Leave empty if you provided Start URLs. -
Search Queries (
searchQueries): a list of keywords, e.g.["lego 42115", "lego 42143"]. Each keyword runs as its own search with the same marketplace, mode and filters, andmaxItemsapplies to each keyword (and to each half of abothrun). It combines withsearchQueryandstartUrls; the untouched example Start URL is ignored while the list is in use. A keyword listed twice (ignoring case and spacing) runs once.seller, if set, filters every keyword. When eBay has few or no exact matches for a keyword it fills the page with "Results matching fewer words"; settitleMustMatchQuery: trueto drop those. Up to 500 keywords per run. -
Marketplace (
marketplace): which eBay site to scrape, one of 17:ebay.com,ebay.co.uk,ebay.de,ebay.fr,ebay.it,ebay.es,ebay.ca,ebay.com.au,ebay.nl,ebay.at,ebay.ch,ebay.ie,ebay.pl,ebay.com.hk,ebay.com.my,ebay.ph,ebay.com.sg. Prices come in the site's currency. On search rows eBay's own labels (condition, shipping, location) come back in English;volumeDiscount,timeLeftand theconditionof a single/itm/row stay in the site's language. A regional domain in a pasted URL (e.g.ebay.de) picks the site for that URL and anebay.comURL follows this setting. A/b/category URL and a/sch/<number>/i.htmlcategory search are the exception: they are always searched on their own site. The connection country always follows this setting, so set it to the site your URLs come from. Defaultebay.com. -
Listing Mode (
mode):active(live listings, default),sold(confirmed sold / completed listings for price comps, mostly from the last ~90 days with a thin tail of older sales;soldWithinDayssets an exact window), orboth. Sold rows includesoldandsoldDate. -
Category page (/b/) URLs (
categoryPageMode):exact(default) scrapes a /b/ page through eBay's search when it is the plain category, and reads any other /b/ page from the page itself.keywordsearches a brand or model page as its category plus the page-title words.categorysearches the whole category. Pages without a category number and invalid category ids are read from the page itself in every mode. -
Condition (
condition):any(default),new,used,refurbished,open_box,certified_pre_owned(vehicles), orfor_parts— applies to keyword searches. -
Min / Max Price (
minPrice/maxPrice): Price bounds in the marketplace currency — applies to keyword searches. -
Sort By (
sortBy):best_match(default),ending_soon,newest,price_asc, orprice_desc. -
Listing Type (
listingType):all(default),auction,bin(Buy It Now), orbest_offer(listings that accept offers) — keyword-search only. In a pasted URL,LH_BO=1does the same. -
Free shipping only (
freeShipping) / Returns accepted only (returnsAccepted): booleans, keyword-search only. -
Seller (
seller): limit a keyword search to one seller's username. -
Category ID (
category): limit a keyword search to an eBay category by numeric ID (e.g.9355). Takes precedence overmotorsCategory. -
eBay Motors category (
motorsCategory): friendly preset for Motors searches — vehicles (6001Cars & Trucks,6024Motorcycles,26429Boats,50054RVs & Campers,66466Powersports,63732Commercial Trucks,6038Other Vehicles) or parts (6028all Parts & Accessories,6030Car & Truck Parts,10063Motorcycle Parts,26443Boat Parts,43962ATV/UTV Parts). Uses the eBay US category tree; keyword-search only. -
Min / Max model year (
minYear/maxYear): model-year range for vehicle searches. The actor reads the year at the start of each listing title, for keyword searches and pasted URLs alike; listings whose title does not start with a year (parts, accessories) are kept. -
Seller feedback profiles (
feedbackProfiles): list of seller usernames or feedback-profile URLs to scrape buyer reviews from (e.g.["<seller>"]). You can also paste a/fdbk/URL into Start URLs. When set, the actor returns one row per review (see Output).maxItemscaps reviews per seller. -
Feedback sort (
feedbackSort):most_recent(default) ormost_relevant— feedback scraping only. -
Feedback received as (
feedbackReceivedAs):seller(default),buyer, orboth— whose perspective to scrape. -
Feedback rating (
feedbackRating):all(default),positive,negative, orneutral. -
Feedback with images only (
feedbackImagesOnly) / Exclude automated feedback (feedbackExcludeAutomated): booleans, feedback scraping only. -
Fetch Full Item Details (
detailedItems): Whentrue(default), each active listing's item page is fetched for item specifics, gallery, seller details, returns and product identifiers, one extra request per listing. Whenfalse, active listings are returned straight from search results (much faster & cheaper). Sold listings always come from search results. -
Include the seller's full description (
includeDescription): addsdescription, the seller's own text, fetched separately at one extra request per item. Works in fast and detailed mode. Defaultfalse. -
Include legacy fields (
includeLegacyFields):true(default) keeps every field rows had before. Full-detail rows also carry eBay's raw item-page modules (vls,buy_box,semantic_data_v2,about_this_item, …), and every row carries a copy of the search card underbasic_info. That legacy data is about 90% of a full-detail row (~45 KB of ~50 KB, up to ~1 MB on large listings) and about 40% of a fast or sold row. Setfalsefor lean, flat rows. Every documented field stays, full-detail rows get 10× or more smaller, fast and sold rows about 40% smaller, and billing does not change. Legacy fields are deprecated and are planned to default tofalsein a future major version, so new integrations should setfalse. -
Sold within last N days (
soldWithinDays): sold / both mode; keeps only sales from the last N days. The filter runs before rows are written, so older sales are not billed. Empty means eBay's full sold history. -
Include sold-price summary row (
includeSummary): one analytics row per sold search (see Output). Defaulttrue. A summary is skipped once the run's maximum cost is used up. -
Title must match the search keyword (
titleMustMatchQuery) / Title must include these words (titleMustInclude): keep only listings whose title contains every word of the keyword (taken from each URL's own_nkw) or of the words you give. Dropped listings are not billed. -
Monitoring mode (
monitoringMode) / Enable price monitoring (enablePriceMonitoring): return only listings not seen in earlier runs and, with price monitoring, seen listings whose price changed. History is kept per exact URL: changing a URL, even by adding a filter, starts a new history (a/b/category page or a/sch/<category id>/i.htmlsearch keeps the history it built in earlier runs). The first run of a monitor (and the first run after a URL change) returns up tomaxItemslistings and records every listing it read as seen, so later runs return only new listings. That includes the listings that did not fit under the maximum cost. A/b/category page or a/sch/<category id>/i.htmlsearch that earlier runs read from eBay's website skips the listings those runs returned. Its first run on eBay's search is still a first run: it records every listing it read, the new ones it did not return included. After that, new listings on the first results page that do not fit undermaxItemsare returned by the next run. On later pages, every new listing a run reads is recorded as seen, including the ones pastmaxItems. Do not run two monitoring runs of the same search at the same time: each run reads the history once, when it starts on that search, so both would return the same new listings. If the platform fails to record a listing as seen, the listing is still returned, and the next run may return it once more. A listing whose item page could not be read is not kept as seen, so the next run returns it. That includes the item pages a run did not reach because eBay rejected its access (HTTP 401) and the run stopped. -
Max Items (
maxItems): Maximum number of items per search. Each keyword, thesearchQueryand each start URL is its own search, and inbothmode the active and sold halves each return up to this many. Default1000, so a run with 20 keywords can return up to 20 ×maxItems. Start URLs read from eBay's website (/b/pages that are not scraped through eBay's search, other URL shapes) are the exception: all of them together share onemaxItems. Only the sold half of such a/b/page inbothmode counts its own. -
Max Concurrency (
maxConcurrency): Maximum number of pages processed simultaneously. Default is5. -
Min Concurrency (
minConcurrency): Minimum number of pages processed simultaneously. Default is1. -
Max Request Retries (
maxRequestRetries): Number of times the scraper will retry a failed request before giving up. Default is20, minimum12. Retries after an eBay rate limit (HTTP 429) and the fresh-IP retries of an empty page count toward this number, so keep the default unless you have a reason to lower it. -
Proxy Configuration (
proxy): used on the free Apify plan only; on a paid plan the actor connects from the Marketplace country by itself. On the free plan:useApifyProxy:trueapifyProxyGroups:["RESIDENTIAL"]apifyProxyCountry: the Marketplace country ("US"for ebay.com,"GB"for ebay.co.uk, …)
Category pages (/b/ URLs)
An eBay category page URL looks like /b/<page title>/<category id>/bn_<page id>. eBay builds several such pages per category. One is the category itself (/b/Cell-Phones-Smartphones/9355/bn_320094). Others are pages for a brand, a model or a hand-picked selection inside it (/b/Apple-iPhone/9355/bn_319682 is also category 9355). The filter behind those pages lives on eBay's side, not in the URL.
The actor checks each page against eBay's own name for its category.
- The page is the category. Its title matches the category name: "Cell Phones Smartphones" for Cell Phones & Smartphones, or "Womens Clothing Shoes Accessories" for Women, whose parent is Clothing, Shoes & Accessories. It is then scraped through eBay's search, like a
/sch/URL. Sold mode, the sold-price summary and fast mode (detailedItems: false) work, and filters in the URL's query string (?LH_BIN=1,?Brand=Apple, price ranges) are applied. - Brand, model and curated pages are decided by
categoryPageMode:exact(default): the page itself is read. Rows always carry full item details, and there is no sold-price summary for such a page. Insoldmode the actor adds eBay's sold filters (LH_Sold=1&LH_Complete=1) to the page URL. Inbothmode it reads the page twice, once as it is and once with those filters, and the sold reading returns up to Max number of items of its own.keyword: eBay's search is asked for the category plus the title words the category name does not contain. Apple iPhone becomes the keyword "Apple iPhone" in 9355; all of the first 213 results were iPhones, about as many as eBay's own Brand=Apple filter finds. A one-letter model name stays in the keyword: Apple iPhone X becomes "Apple iPhone X", not every iPhone. This works for brand and model pages. It works badly for curated pages: Luxury Watches becomes the keyword "Luxury" in Wristwatches. When the title has no words beyond the category name, the whole category is searched, as incategorymode.category: eBay's search is asked for the whole category, ignoring the page's own filter. Searched as the plain category, the Apple iPhone page gave 39 iPhones among the first 212 listings.
- Top-level categories. eBay's search lists a top-level category only together with a keyword.
keywordmode therefore searches such a page only when its title has words the category name lacks:/b/Gaming/1249/…becomes the keyword "Gaming" in Video Games & Consoles. A page titled like its category, such as/b/Sporting-Goods/888/…, is read from the page itself in every mode, and so is every top-level page inexactandcategorymode. - Pages without a category number, such as
/b/Electronics/bn_7000259124, and invalid category ids are read from the page itself in every mode.
A page read from the page itself gives detailed rows only: no sold-price summary, no fast mode and no _searchMeta row (see Rows read from eBay's web pages under Output Structure). The sold filters are added only when the URL has a category number. A page without one is read as it is, whatever the Listing mode.
Two Start URLs that are the same /b/ page written differently (parameter order, a #fragment, utm_ parameters, a trailing slash) run as one search.
The most exact way to scrape a brand or model page through eBay's search is this: open it, pick the filters (brand, model, condition) in eBay's sidebar, and paste the resulting URL.
A page that keyword or category mode scrapes through eBay's search gets one free _searchMeta row that says what was searched:
{"_searchMeta": true,"type": "category-page","url": "https://www.ebay.com/b/Apple-iPhone/9355/bn_319682","match": "filtered","action": "keyword","reason": "slug-differs","categoryId": "9355","categoryName": "Cell Phones & Smartphones","browseNodeId": "319682","pageTitle": "Apple iPhone","keyword": "Apple iPhone","mappedSearchUrl": "https://www.ebay.com/sch/i.html?_sacat=9355&_nkw=Apple+iPhone","categoryTotalResults": 116811,"note": "\"Apple iPhone\": it looks like a filtered page inside eBay category 9355 \"Cell Phones & Smartphones\" ... Scraped as that category plus the keyword \"Apple iPhone\". ...","searchQuery": "Apple iPhone","searchUrl": "https://www.ebay.com/b/Apple-iPhone/9355/bn_319682"}
match is filtered or top-level. action is keyword or whole-category. mappedSearchUrl opens the same search in a browser. A plain category page, or a page read from the page itself, writes no marker row.
Run Status and Partial Results
The run's status message says what happened. Read it before you rely on an empty or a short dataset.
- No rows, run SUCCEEDED. This is a real answer: eBay had no matches, your filters (
titleMustMatchQuery,titleMustInclude,soldWithinDays,minYear/maxYear, orfeedbackRatingon a seller with no review of that rating) kept nothing, or monitoring mode found nothing new. The message says which, and how many listings or reviews the filters dropped. With a keyword list it says so per keyword. - Partial result. A search page that keeps failing is given up on, and that search stops early. The message then starts with
Partial result, names the search, says how many listings it read and whether the cause was an eBay rate limit (HTTP 429) or a failed request. With several searches it names the first three, counts the rest and says how many searches were complete; the run log lists all of them. A run that also stopped at your maximum cost says that in place of the count, because the searches it did not finish are not complete either. When a run with several searches has no rows at all, the message can start withNo listings, but this run cannot be called emptyinstead. The rows already in the dataset are complete and correct. Re-run the named searches a few minutes later for the rest. - One search in the run. The run ends FAILED when that search lost a material part of its results (more than about a tenth of what it could have returned) to a failed request. When the cause was a rate limit and some rows were delivered, the run ends SUCCEEDED with the partial result. In monitoring mode a short result alone never fails the run.
- Several searches in the run (several keywords or Start URLs, or mode
both, where the active half and the sold half of each search count separately). The run ends FAILED only when every search was lost that way. Otherwise it ends SUCCEEDED with thePartial resultmessage. - Listings found, none read. A detailed search reads each listing from its item page. When a search finds listings and every one of those item pages fails, the run has no rows but is not empty: it ends SUCCEEDED with a status message that starts with
Found N listing(s)and says that no row was delivered. Outside monitoring mode the whole crawl is tried again first, up to three attempts in total. Re-run it a few minutes later. - No rows, run FAILED. The usual causes are an input URL eBay does not know (HTTP 404), input with nothing usable in it, or an empty run that nothing explains. Before it fails such an empty run, the actor runs the whole crawl again, up to three attempts in total. A seller-feedback profile that returns no review at all ends this way too: that answer cannot be told apart from a block or a mistyped seller name.
- Retries. A search page that fails part-way is picked up by its retry (log line
Resuming page N of <url>), so the rest of that page and the later pages are still scraped. When eBay does not return those listings to the retry, the page is fetched again from up to three new connections. If they still do not come back, the search goes on with its next page, and the status message says how many listings may be missing (... were read on a page that failed part-way ...). If the run crashes or is migrated at that moment, a row can appear twice in the dataset.
Maximum cost per run (pay-per-event). Before each row the actor checks that its charge still fits under the maximum cost you set for the run. Only rows that fit are delivered, and then the run stops by itself. A sold-price summary that no longer fits is skipped. In monitoring mode, after a search's first run, fast and sold listings that did not fit are not recorded as seen, so the next run delivers them. The first run records every listing it read (see Monitoring mode under Input Fields Explanation), except on a results page where not one row fit: that page records nothing, so a first run that could not deliver a row is still the first run next time. A detailed listing is recorded as seen when its search page is read, so one whose item page was still waiting when the limit was reached is not delivered by a later run. With a keyword list the status message names the keywords the run did not reach. A run that cannot afford a single row ends SUCCEEDED with 0 rows and the message "Stopped at your maximum charge before any listing could be delivered. Raise the maximum cost per run to get results."
Output Structure
In the Apify Console, the Output tab shows the results as three table views: Overview (the main listing fields), Vehicles (eBay Motors fields) and Deals & demand (reference price, discounts, coupons, watchers and sold counts). The full rows, with every field below, are in the dataset download.
Every result is one flat, clean row: search-result data and (optionally) full item-page detail merged together. By default each row also keeps a copy of the raw search card under basic_info, and detailed rows also keep eBay's raw item-page modules (vls, buy_box, …), both for backward compatibility. Set includeLegacyFields: false to drop them. The facts worth keeping from them are flat fields (see Legacy fields below).
Core fields (every listing row from a search): itemId, url, title, price (display string, e.g. "$899.00"), priceValue (number), currency, condition, shipping, availability / quantity, image, marketplace, scrapedAt. Added when they apply: epid when eBay links the listing to a catalog product (often missing, and missing on every row of some searches and sites), itemLocation when eBay labels the listing (see Location labels under Filters you can paste), bidCount & timeLeft for auctions and sold & soldDate for sold/completed listings. Single /itm/ rows and rows read from eBay's web pages differ in a few fields; both are described below.
Seller & shipping (every listing row: fast, sold and detailed): sellerUsername, sellerFeedbackScore (the exact feedback count; it can be 0 or negative), sellerFeedbackPercentage (0–100, as eBay prints it); sellerHasStore, sellerStoreName and sellerAccountType (business / private) when eBay states them; and topRatedPlus: true when the listing carries eBay's Top Rated Plus badge. Shipping comes as a number as well as the display string: shippingType (free / paid / freight / local_pickup / not_specified), shippingCost (0 when free, null when eBay gives no amount), shippingCurrency, and totalPrice = priceValue + shippingCost (only when both are known and in the same currency). These fields come from data the actor already loads, so they add no requests and no cost.
Deal and demand signals (originalPrice, discount, coupons, quantitySold, watchers, productRating and more) are added whenever eBay shows them; see Price, discount & demand signals below.
Which search a row came from. Every row from a keyword search, or from a /sch/i.html, /sch/<category id>/i.html, /usr/, /str/ or plain /b/ category URL, carries searchUrl: the eBay search URL that found it, built from your keyword or taken exactly as you pasted it. When that search has a keyword, the row also carries searchQuery, the keyword as you typed it. Seller, store and category-only searches carry searchUrl only. For a /b/ page scraped through eBay's search, searchUrl is the /b/ URL you pasted, and searchQuery is the keyword actually searched, set in categoryPageMode: "keyword" (or when the /b/ URL has its own _nkw). A single /itm/ URL, and URLs read through the page path (/shop/, and, in the default exact mode, /b/ pages that are not a plain category), carry neither. The sold-price summary carries the same two fields, so searchUrl joins every listing to its search's summary. In a run that uses searchQueries, a listing two of your keywords both find is returned once under each keyword, and each copy is a row and a charge. Without searchQueries, a detailed row is returned once per run, under the search that found it first. It still counts toward maxItems of every search that finds it, so two Start URLs that share listings return fewer than twice maxItems detailed rows. Fast and sold rows are returned once per search, so a listing that two Start URLs both find (or a searchQuery and a Start URL) is a row and a charge under each. Unless titleMustMatchQuery is on, a keyword's rows include eBay's near matches ("Results matching fewer words") whenever eBay has few exact matches for it.
A single item URL (/itm/<id>) returns a row with the same fields as a search result, built from the item page itself. An item URL eBay has no listing for (the listing was removed, or the number is wrong) returns no row and is not charged; the run log names it, and a run whose inputs are all such URLs ends FAILED as an invalid URL. Next to a search, such a URL does not decide how the run ends: a monitoring run with nothing new, or a search your filters emptied, still ends SUCCEEDED, and the status message names the URL. The same goes for a listing a search found that is gone by the time its item page is read: no row, no charge. Like every row built from an item page (detailedItems: true search rows included), it reports listingStatus (ACTIVE / ENDED), startDate and endDate. On an ended listing it also reports sold (true when the listing sold, false when it expired unsold, omitted on the handful of older listings eBay no longer reports it for). It carries no epid, and no soldDate: endDate holds the timestamp instead.
Some values on a single /itm/ row differ from a search row of the same listing, because they are the item page's own:
price(the display string) is the price line of the item page. On a listing priced in another currency it shows the seller's own price, e.g."€299.00", which is also innativePriceValue/nativeCurrency.priceValueandcurrencyhold eBay's converted amount in the site's currency (334.88,"USD"). UsepriceValueandcurrencyfor numbers.conditionis the item page's wording, in the site's language:"Used"or"New"where a search row says"Pre-Owned"or"Brand New", and"Neu"on ebay.de.urlis the plain item URL, without the search's tracking parameters.itemLocationis the item page's location (see Location labels),availabilityreads"8 available"where a search row reads"8 remaining", andshippingis there only when the item page shows a shipping line.
A detailed search row keeps the search card's values for these fields.
Rows read from eBay's web pages (/b/ pages that are not scraped through eBay's search, and other URL shapes) are detailed rows built from each listing's item page, and they differ from other rows:
priceValueisnull, and there is nocurrencyand nototalPrice: eBay's web search page gives no numeric price. That page usually carries no price line, condition or location either, soprice,conditionanditemLocationare missing as well. While legacy fields are on, the rawbuy_boxmodule of the row still holds the price.shipping,shippingType,shippingCostandshippingCurrencycome from the item page.- The page is read from the site in the URL, but the item pages are requested through eBay's US site and every such row says
marketplace: "ebay.com", also for a regional URL. - There is no
searchQuery,searchUrlorepid, and no sold-price summary.
sold on completed searches means the listing actually sold. A LH_Complete=1 URL returns expired listings alongside sold ones, and those come back sold: false with no soldDate; only sold rows feed the sold-price-summary analytics, so the median and recommended price are comps, not asking prices.
With detailedItems: true (active listings), each row also includes seller (object: userId, username, feedbackScore, feedbackPercentage; the flat seller* fields on the same row carry the same numbers), itemSpecifics, images, shippingDetails, returns, quantitySold / quantityAvailable, watchers, bestOfferEnabled, couponCode (when the seller runs a coupon) and product identifiers (brand, mpn, upc, ean, gtin, isbn, model). On these rows watchers and quantitySold are the item page's exact totals, 0 included. Detailed rows always have sellerHasStore and sellerAccountType, on every marketplace, plus sellerStoreName when eBay names the store (a few store sellers come without a name). The seller's own description comes with includeDescription: true.
Every row built from an item page (detailed search rows and /itm/ rows) also carries:
startDate/endDate/listingStatuscategoryIdandcategoryPath: the leaf category and its full path, e.g."Home & Garden > Household Supplies & Cleaning > Vacuum Cleaners", in the listing site's languageconditionId: eBay's numeric condition code, e.g."1000"= New,"3000"= UsedsellerMemberSince: when the seller registered
Cross-border listings add nativeCurrency and nativePriceValue: the seller's own currency and price before eBay's conversion. nativePriceValue is set only when it is the same price as priceValue.
Auctions add startingBidValue (in currency), bidderCount (unique bidders) and hasReservePrice.
Multi-variation listings add variations, one entry per variation: variationId, sku, aspects (e.g. { "Model": "For iphone 15 Pro Max", "Colour": "Black" }), priceValue, currency, quantityAvailable, quantitySold, availabilityStatus.
Seller and shipping fields
| Field | Type | Notes |
|---|---|---|
sellerUsername | string | Every listing row. |
sellerFeedbackScore | integer | The exact count. eBay abbreviates it in places ("35.1K", truncated, not rounded), and the abbreviation is never used. On detailed rows it comes from the item page, which is read a moment after the search results, so for very active sellers it can be a few points higher than a fast row for the same listing. |
sellerFeedbackPercentage | number 0–100 | As eBay prints it. eBay shows 0 when it has no recent ratings to compute it from. That includes new sellers and established sellers with no ratings in eBay's percentage window, so look at sellerFeedbackScore before reading a 0 as a bad seller. |
sellerHasStore | boolean | true / false only when eBay says so. On ebay.de, ebay.fr, ebay.it and ebay.co.uk, among others, every fast and sold row has it. On ebay.com and ebay.com.au (ebay.ca, ebay.ch and some others behave alike) the search results name a store only for some sellers: a fast or sold row there has sellerHasStore: true when eBay shows the seller's store line on the card, and never false. A missing field there means unknown, not "no store". Detailed rows always have it. |
sellerStoreName | string | eBay's store name, e.g. example_store, when eBay names the store. Fast and sold rows have it only on the sites where sellerHasStore can also be false. A detailed row can say sellerHasStore: true without it. |
sellerAccountType | business / private | Shown by eBay on EU, Swiss and Polish search results; on every detailed row. |
topRatedPlus | true | Present only when the badge is shown. A missing field does not mean "not Top Rated". |
shippingType | string | free, paid, freight, local_pickup (collection only) or not_specified. |
shippingCost | number or null | On every listing row. 0 = free; null = not specified, freight, pickup only, or no shipping line. |
shippingCurrency | string | ISO code of shippingCost, set whenever shippingCost is a number. A row read from eBay's web pages can be the exception. |
totalPrice | number | priceValue + shippingCost in one currency: item and shipping only. Import VAT and fees that eBay lists separately ("+ CHF 9.99 VAT will apply", "Import fees due prior to delivery") are not included. For a price range it is the low end, like priceValue. On accepted Best Offers it is asking price + shipping (see priceIsAskingPrice). |
What the shipping quote is for. eBay quotes shipping to wherever the request comes from. On paid Apify plans the actor requests from inside the marketplace's own country, so ebay.de rows carry German domestic shipping, ebay.com rows US shipping, and so on. On the free plan the actor uses your proxy setting (Apify Proxy by default), which is not pinned to that country, so shipping, shippingType and totalPrice can be an international quote, with more "Shipping not specified" and "Free International Shipping". On sold rows the figure is eBay's current quote for that listing, not what the buyer paid, and calculated-shipping amounts can change between runs. Lines such as "+PLN63.24 shipping estimate" are eBay's own estimate. shipping (the display string) is also filled when eBay shows the shipping line in its delivery-time form, e.g. "Free delivery in 2-4 days" or "+$29.90 delivery in 2-4 days". Rows read from eBay's web pages (non-plain /b/ pages and other URL shapes) take shipping, shippingType, shippingCost and shippingCurrency from the listing's item page, because eBay's web search page no longer carries a shipping line. They have no totalPrice, because that path has no numeric price.
Price, discount & demand signals
These come straight from eBay's search card, at no extra cost. They are on every row from a keyword search or a /sch/i.html, /sch/<category id>/i.html, /usr/, /str/ or plain /b/ category URL (fast and detailed, active and sold), and partly on single /itm/ rows (see below). Each field appears only when eBay shows that signal on the listing, so a missing field means "not shown", never zero or false. Text fields are eBay's own wording, with whitespace normalised. The actor asks eBay for English, and discount and couponText came back in English on every site checked ("30% off", "€86.85 with coupon" on ebay.de). volumeDiscount comes in the site's language ("Bis 10% sparen mit Multi-Rabatt" on ebay.de), and so does timeLeft on search rows ("4T 8Std 21 Min" on ebay.de, "1j 22h 55m" on ebay.fr). discountPercent, couponPriceValue and volumeDiscountPercent are numbers and do not depend on the wording.
| Field | Example | Meaning |
|---|---|---|
originalPrice / originalPriceValue | "$31.00" / 31 | The reference price eBay shows next to the price (crossed out, or labelled "MSRP" / "UVP") |
originalPriceType | "list_price" | Set only when eBay says which kind it is. list_price is the manufacturer's list price; was_price is the seller's own earlier price. A search card says so only for labelled "MSRP" / "UVP" prices. eBay draws both kinds crossed out, so fast rows leave crossed-out prices unclassified. Detailed and /itm/ rows take the type from the item page (single-variation listings) |
discount / discountPercent | "15% off" / 15 | eBay's discount badge. It read "N% off" on every site checked, ebay.de, ebay.fr and ebay.it included. We never compute a discount ourselves |
couponText | "€12.91 with coupon" | The seller-coupon line |
couponPrice / couponPriceValue | "€12.91" / 12.91 | The price after the coupon, when eBay states one in the listing's currency |
couponCode | "SPARK10" | Detailed and /itm/ rows only: the code from the item page |
recentPriceDrop | true | eBay's "NEW LOW PRICE" badge. It is unrelated to monitoring mode's priceChanged, which compares with your own previous run |
volumeDiscount / volumeDiscountPercent | "Save up to 15% when you buy more" / 15 | The seller's offer line from the card, in eBay's words. It is nearly always a multi-buy offer. eBay uses the same line for spend-threshold coupons ("$15 off $50+ with coupon") and, rarely, for a flat sale ("Extra 10% off"), so read the text if you want buy-more offers only. volumeDiscountPercent is the percent in that line. Amount-off offers such as "$5 off 2+ with coupon" have no percent |
quantitySold, watchers | 336, 7 | Demand signals. A search card shows at most one of the two, and sold listings show neither |
quantitySoldIsMinimum, watchersIsMinimum | true | The count is only a floor. eBay shows "814+ sold" on listings with variations. Its search results also stop counting sales at 10,000: a listing with 52,934 sales reads "10,000 sold", so quantitySold: 10000 always carries this flag. Detailed rows replace both counts with the item page's exact totals and drop these flags |
productRating / productRatingCount | 4.5 / 88 | The catalog product's star rating, shared by every listing of that product. This is not the seller's feedback |
freeReturns | true | The listing offers free returns |
certifiedRefurbished | true | The listing carries eBay's "eBay Refurbished" programme badge |
hasVariations | true | A multi-variation listing (sizes, colours, capacities). Its price may be a range |
{ "price": "€138.99", "priceValue": 138.99, "originalPrice": "€189.21", "originalPriceValue": 189.21, "originalPriceType": "list_price", "discount": "27% off", "discountPercent": 27, "couponText": "€125.09 with coupon", "couponPrice": "€125.09", "couponPriceValue": 125.09 }
Listings priced as a range ("€160.86 to €338.91") can also carry an originalPriceValue. It belongs to one variation that eBay does not name, and it can fall inside the range. eBay shows no discount badge on these listings, so discountPercent is absent; do not compute one from priceValue.
On sold rows, these fields describe the listing as it ended. For example, originalPriceValue with discountPercent: 15 means the item sold 15% under the reference price eBay showed. On an accepted Best Offer (priceIsAskingPrice: true), the badge compares with the asking price, not the hidden sale price. Coupons are never subtracted from sold prices or from the sold-price-summary, because eBay does not say whether the buyer used one.
A single /itm/ URL row carries watchers, quantitySold, couponCode and hasVariations from the item page. Single-variation listings also get originalPriceValue, originalPriceType and discountPercent. The fields that only a search card shows are absent: originalPrice and discount (display text), couponText / couponPrice, recentPriceDrop, volumeDiscount, productRating / productRatingCount, freeReturns, certifiedRefurbished and the two …IsMinimum flags.
Rows read from eBay's web pages (/b/ pages that are not scraped through eBay's search, and any URL other than /sch/i.html, /sch/<category id>/i.html, /usr/, /str/, plain /b/ category pages and /itm/) carry the item-page signals only: watchers, quantitySold and, when the seller runs a coupon, couponCode. The fields a search card shows are absent.
Other row types and samples
Marker rows. Not every row in the dataset is a listing. Skip rows that carry _searchMeta or _analytics when you count or parse listings.
- A search that eBay confirms as empty writes one free marker row. It has no
typekey. It is written when the first page comes back with no listings at all on four attempts, each from a new connection. A keyword that eBay answers with near matches gets listing rows instead.
{ "_searchMeta": true, "url": "https://www.ebay.com/sch/i.html?_nkw=xk49q7", "searchQuery": "xk49q7", "searchUrl": "https://www.ebay.com/sch/i.html?_nkw=xk49q7", "totalResults": 0, "note": "No exact matches found — valid search, no items" }
- A
/b/category page scraped inkeywordorcategorymode writes the"type": "category-page"marker shown under Category pages (/b/ URLs). - A sold search writes the
sold-price-summaryrow (_analytics: true) shown below. A sold search for which eBay reports no exact matches writes a free"type": "no-exact-sold-matches"marker in its place: its sold rows are near matches, so no summary is made. - A search read from eBay's web pages that has no results writes
{ "totalResults": 0, "url": "…" }.
eBay Motors vehicle listings additionally get a structured vehicle object parsed from the item specifics: year, make, model, trim, mileage (number), vin, transmission, fuelType, bodyType, driveType, engine, cylinders, exteriorColor, interiorColor, vehicleTitle (title status), forSaleBy — only present when the listing is actually a vehicle:
{"itemId": "1234567890","url": "https://www.ebay.com/itm/1234567890","title": "2019 Honda Civic EX 1.5L Turbo Sedan — Clean Title, One Owner","price": "$18,995.00","priceValue": 18995,"currency": "USD","condition": "Used","itemLocation": "Phoenix, Arizona, United States","image": "https://i.ebayimg.com/images/g/.../s-l1600.jpg","marketplace": "ebay.com","vehicle": {"year": 2019,"make": "Honda","model": "Civic","trim": "EX","mileage": 45120,"vin": "2HGFC2F79KH123456","transmission": "Automatic","fuelType": "Gasoline","bodyType": "Sedan","driveType": "FWD","engine": "1.5L I4 Turbo","exteriorColor": "Aegean Blue Metallic","interiorColor": "Black","vehicleTitle": "Clean","forSaleBy": "Dealer"},"seller": { "username": "example_dealer", "feedbackScore": 1204, "feedbackPercentage": 99.2 },"sellerUsername": "example_dealer", "sellerFeedbackScore": 1204, "sellerFeedbackPercentage": 99.2, "sellerHasStore": true, "sellerStoreName": "example_store", "sellerAccountType": "business", "shippingCost": null,"itemSpecifics": { "Year": "2019", "Make": "Honda", "Model": "Civic", "…": "…" },"detailed": true,"scrapedAt": "2026-07-16T12:00:00.000Z"}
With monitoringMode, only listings not seen in previous runs are returned (state is tracked per search URL, so per keyword, in a Key-Value store; moving a keyword between searchQuery and searchQueries keeps its state as long as it is spelled exactly the same, letter case and spacing included). Add enablePriceMonitoring to also return previously-seen listings whose price changed, flagged with priceChanged: true and previousPrice. Two monitoring runs of the same search should not overlap: each reads the seen list once, when it starts on that search. A listing the platform could not record as seen is still returned, and the next run may return it once more.
Seller feedback review (feedbackProfiles set) — one flat row per buyer review:
{"seller": "example_seller","marketplace": "ebay.com","feedbackId": "1234567890123","sentiment": "positive","comment": "Order delivered on time with no issues","buyer": "a***b","buyerScore": "1550","relativeTime": "Past month","itemTitle": "Example DVD box set (2016)","itemId": "1234567890","itemUrl": "https://www.ebay.com/itm/1234567890","itemPrice": "GBP 4.67","scrapedAt": "2026-06-29T22:33:48.000Z"}
Sold listing (mode: "sold" or "both") — returned directly from the search results, no detail fetch:
{"itemId": "1234567890","title": "Apple iPhone 16 Pro 256GB Natural Titanium Unlocked","price": "$899.00","priceValue": 899,"currency": "USD","condition": "Pre-Owned","shipping": "Free shipping","sold": true,"soldDate": "Sold Jun 4, 2026","image": "https://i.ebayimg.com/images/g/.../s-l225.jpg","url": "https://www.ebay.com/itm/1234567890","marketplace": "ebay.com","searchQuery": "iphone 16 pro","searchUrl": "https://www.ebay.com/sch/i.html?_nkw=iphone+16+pro","shippingType": "free","shippingCost": 0,"shippingCurrency": "USD","totalPrice": 899,"sellerUsername": "example_seller","sellerFeedbackScore": 1520,"sellerFeedbackPercentage": 99.6}
Sold-price summary — for sold / both searches, one analytics row is appended per search (perfect for resale pricing & comps):
{"_analytics": true,"type": "sold-price-summary","query": "iphone 16 pro","searchQuery": "iphone 16 pro","searchUrl": "https://www.ebay.com/sch/i.html?_nkw=iphone+16+pro","marketplace": "ebay.com","currency": "USD","count": 40,"minPrice": 5.3,"maxPrice": 1200,"averagePrice": 605.82,"medianPrice": 575,"recommendedPrice": 575,"totalSold": 4197,"totalActive": 4723,"sellThroughRate": 0.4705,"soldPerDay": 46.63}
With searchQueries you get one summary per sold keyword, and each is a separate charged sold-summary event (includeSummary: false skips them). Summaries stop once the run's maximum cost is reached. When eBay reports no exact sold matches for a search, no summary is produced or charged, because every price would come from a near match. The dataset then holds a free marker row for that search ("_searchMeta": true, "type": "no-exact-sold-matches"), and the run's status message names the search. This applies to a single searchQuery and to a pasted sold URL as well. rowsBeyondExactMatches appears when the sample holds more rows than eBay's own exact-match count, i.e. near matches are in the prices; turn on titleMustMatchQuery to keep them out.
Summaries of /b/ category pages scraped through eBay's search also carry categoryId and categoryName, the category that was searched. Their query is set only when a keyword was actually searched (keyword mode, or a /b/ URL with its own _nkw). categoryPageApproximate: true marks a filtered page scraped in keyword or category mode; its comps describe that search, not exactly the page.
count is the number of sold listings sampled for the price stats; totalSold / totalActive are eBay's full match counts. sellThroughRate = totalSold ÷ (totalSold + totalActive) (demand strength, 0–1), and soldPerDay ≈ totalSold ÷ 90. Sell-through is computed for sold/both searches (a tiny extra request fetches the active count in sold-only mode). That request is given 15 seconds. When it fails, the summary row is still returned, without totalActive and sellThroughRate. After three such requests in a row have failed, the remaining summaries of the run come without the two fields as well.
Accepted Best Offers are kept out of the price stats. When a seller accepts an offer, eBay does not show what the item actually sold for — it shows the original asking price crossed out. Counting that as a sale price would push every median and recommended price up, since offers are accepted below asking; depending on the query, 13–30% of sold listings are accepted offers. So those rows are still returned (flagged bestOfferAccepted: true and priceIsAskingPrice: true), but they are counted in bestOfferAcceptedCount instead of being priced. count is the priced sample, and count + bestOfferAcceptedCount = soldListings.
When soldWithinDays is set, the summary carries windowDays and its count and prices come from that window only. totalSold, soldPerDay and sellThroughRate still come from eBay's own totals and describe the whole market for the query, because a run's own row count is not a reliable measure of how many sold in a window. soldPerDay ≈ totalSold ÷ 90 is accurate: eBay's sold index has a thin tail reaching back years, but the volume sits in the last ~90 days, and the formula matches the measured 7-day sold rate to within about 5%.
Detailed active listing (detailedItems: true, shown with includeLegacyFields: false; trimmed):
{"itemId": "1234567890","url": "https://www.ebay.com/itm/1234567890","title": "DYSON V15 DETECT CORDLESS STICK VACUUM CLEANER - BRAND NEW","price": "$420.00","priceValue": 420,"currency": "USD","condition": "Brand New","shipping": "+$19.99 delivery","itemLocation": "Located in United States","quantity": 1,"image": "https://i.ebayimg.com/images/g/.../s-l225.jpg","marketplace": "ebay.com","scrapedAt": "2026-10-01T10:30:00.000Z","searchQuery": "dyson v15","searchUrl": "https://www.ebay.com/sch/i.html?_nkw=dyson+v15","shippingType": "paid","shippingCost": 19.99,"shippingCurrency": "USD","totalPrice": 439.99,"sellerUsername": "example_seller","sellerFeedbackScore": 16740,"sellerFeedbackPercentage": 99.7,"sellerHasStore": false,"sellerAccountType": "business","bidCount": 5,"buyingFormat": "auction","timeLeft": "16h 9m","productRating": 4.7,"productRatingCount": 211,"seller": { "userId": "1234567", "username": "example_seller", "feedbackScore": 16740, "feedbackPercentage": 99.7 },"itemSpecifics": { "Brand": "Dyson", "Type": "Stick", "Model": "V15 DETECT", "…": "…" },"brand": "Dyson","model": "V15 DETECT","images": ["https://i.ebayimg.com/images/g/.../s-l400.jpg", "…"],"shippingDetails": { "title": "Shipping", "sections": { "…": "…" } },"returns": { "title": "Returns", "sections": { "…": "…" } },"quantityAvailable": 1,"watchers": 12,"startDate": "2026-09-25T02:35:01.000Z","endDate": "2026-10-02T02:35:01.000Z","listingStatus": "ACTIVE","categoryId": "20614","categoryPath": "Home & Garden > Household Supplies & Cleaning > Vacuum Cleaners","conditionId": "1000","sellerMemberSince": "2013-05-02T18:40:16Z","startingBidValue": 399.95,"bidderCount": 5,"hasReservePrice": false,"detailed": true}
Legacy fields (includeLegacyFields)
With includeLegacyFields: true (the default today), a detailed row also contains every raw item-page module eBay sent, under its lower-cased module name, plus basic_info (the raw search card) on every row. Measured on real listings, those keys are 90-99% of a detailed row and about 40% of a fast or sold row. basic_info keeps the card shape it had before this release: the seller, shipping and price-signal fields above are on the row only, never inside basic_info. The legacy content is already on the flat row:
| Legacy key | Use instead |
|---|---|
vls.listing.listingLifecycle, semantic_data(_v2) start/end/status | startDate, endDate, listingStatus |
vls.listing.listingClassification (leafCategories, generalCondition) | categoryId, categoryPath, conditionId |
vls.listing.seller (feedbackScore, positiveFeedbackPercentage, ebayStore, businessUser) | seller.feedbackScore, seller.feedbackPercentage and the seller fields (sellerFeedbackScore, sellerFeedbackPercentage, sellerHasStore, sellerStoreName, sellerAccountType) |
vls.listing.seller.registrationDate | sellerMemberSince |
vls.listing.tradingSummary.watchCount, conversational_signals | watchers |
vls.listing.listingProperties TOTAL_SOLD_QUANTITY | quantitySold |
buy_box (price, bid, convertedFrom*) | price, priceValue, currency, nativePriceValue, nativeCurrency, bidCount, timeLeft |
buy_box.binModel.additionalInfo, price_details, coupon | originalPrice / originalPriceValue / originalPriceType, discount, couponCode and the other price-signal fields |
vls.listing.itemVariations, msku | variations |
auction startingBidPrice, uniqueBidderCount, semantic_data_v2.hasReservePrice | startingBidValue, bidderCount, hasReservePrice |
features, about_this_item, about_this_item_min_view, condition_description | itemSpecifics (+ brand, mpn, upc, ean, gtin, isbn, model, vehicle) |
shipping_section_module / returns_section_module | shippingDetails / returns (identical content) |
listing ({id, format}) | itemId, buyingFormat |
semantic_data_v2.description, item_desc_seller | description, with includeDescription: true |
basic_info | the same fields at the top level (listingId = itemId; the search keyword is searchQuery; the struck-through / MSRP line is originalPrice) |
Not carried onto lean rows:
- eBay's recent-feedback cards (use
feedbackProfilesfor reviews) and detailed seller star ratings - PSA population counts
- the item-page price-breakdown box and payment-method boxes (eBay sends the latter empty)
- business-seller and EU responsible-person contact details (company, address, phone, email)
- item Q&A and parts-fitment messages
- the DOM-fallback
sold_dateof old HTML category cards (endDatecovers it) - page furniture (ads, placements, buttons, financing and eBay Plus banners)
Output Fields Explanation
- Identity & link:
itemId,url,title,image,epid,marketplace,scrapedAt - Search:
searchQuery(the keyword that found the row),searchUrl(the search it came from, and the key that joins a listing to its search's summary); see Which search a row came from above - Price:
price(display),priceValue(number),currency,bestOfferEnabled; sold rowsbestOfferAccepted/priceIsAskingPrice; item-page rows of cross-border listingsnativePriceValue/nativeCurrency - Format:
buyingFormat(auction/fixed_price),bidCount,timeLeft,sponsored; item-page auction rowsstartingBidValue,bidderCount,hasReservePrice - Status & dates:
sold,soldDate(sold searches);listingStatus,startDate,endDate(item-page rows) - Item:
condition,conditionId,categoryId(the listing's own leaf category),categoryPath,itemSpecifics,brand/mpn/upc/ean/gtin/isbn/model,vehicle(eBay Motors),images,description(withincludeDescription),variations(multi-variation listings) - Stock:
availability,quantity,quantityAvailable - Deals & demand:
quantitySold,watchers(exact on item-page rows;quantitySoldIsMinimum/watchersIsMinimumwhen a search card shows only a floor),originalPrice/originalPriceValue/originalPriceType,discount/discountPercent,couponText/couponPrice/couponPriceValue,couponCode(item-page rows),recentPriceDrop,volumeDiscount/volumeDiscountPercent,productRating/productRatingCount,freeReturns,certifiedRefurbished,hasVariations; see Price, discount & demand signals - Shipping & returns:
shipping(search-card line),shippingType,shippingCost,shippingCurrency,totalPrice,itemLocation,shippingDetails,returns - Seller:
seller(userId,username,feedbackScore,feedbackPercentage),sellerMemberSince; on every listing rowsellerUsername,sellerFeedbackScore,sellerFeedbackPercentage, plussellerHasStore,sellerStoreName,sellerAccountTypeandtopRatedPluswhen eBay states them; see Seller and shipping fields - Monitoring:
priceChanged,previousPrice - Diagnostics:
error(the item page could not be parsed),detailFetchError(lean rows only: eBay rejected the token mid-run, so the row holds search-card data only) - Summary rows (
_analytics: true,type: "sold-price-summary"):query,searchQuery,searchUrl,marketplace,currency,count,minPrice,maxPrice,averagePrice,medianPrice,recommendedPrice,totalSold,totalActive,sellThroughRate,soldPerDay,windowDays,bestOfferAcceptedCount,soldListings,rowsBeyondExactMatches; for/b/category pages alsocategoryId,categoryName,categoryPageApproximate.totalActiveandsellThroughRatecan be absent on asold-only search, when the active count could not be read. On summary and_searchMetarowscategoryIdis the category that was searched; on listing rows it is the listing's own leaf category. - Legacy (on by default, deprecated):
basic_infoand the raw item-page modules; see Legacy fields above.
Explore More Scrapers
If you found this eBay Scraper useful, be sure to check out our other powerful scrapers and actors at memo23's Apify profile. We offer a wide range of tools to enhance your web scraping and automation needs across various platforms and use cases.
Closest to this one: the Best Buy Scraper — prices, savings, per-ZIP availability, and ranked search results with sponsored tiles flagged.
Support
- For issues or feature requests, please use the Issues tab of this actor.
- If you need customization or have questions, feel free to contact the author:
- Author's website: https://muhamed-didovic.github.io/
- Email: muhamed.didovic@gmail.com
Additional Services
- Request customization or whole dataset: muhamed.didovic@gmail.com
- If you need anything else scraped, or this actor customized, email: muhamed.didovic@gmail.com
- For API services of this scraper (no Apify fee, just usage fee for the API), contact: muhamed.didovic@gmail.com
- Email: muhamed.didovic@gmail.com
🤖 For AI Agents & LLM Apps
Compact reference for AI agents calling this actor via the Apify MCP server or the Apify API. The same code is published as memo23/ebay-search-scraper-ppe and memo23/apify-ebay-search-cheerio; call the one whose page you are reading.
Purpose: Scrape eBay active or sold/completed listings across 17 marketplaces by keyword+filters or by pasted eBay URL, one flat row per item; its differentiator is sold-price comps (real sold prices plus a per-search sell-through-rate summary).
Minimal input:
{ "searchQuery": "iphone 16 pro", "detailedItems": false, "includeLegacyFields": false, "maxItems": 50 }
Keyword list: { "searchQueries": ["lego 42115", "lego 42143"], "mode": "sold", "detailedItems": false, "includeLegacyFields": false, "maxItems": 50, "titleMustMatchQuery": true }.
URL mode (one line): { "startUrls": [{ "url": "https://www.ebay.com/sch/i.html?_nkw=baseball+caps&LH_BIN=1" }], "detailedItems": false, "includeLegacyFields": false, "maxItems": 50 }.
Output: one row per listing: itemId, url, title, price (display string), priceValue, currency, condition, shipping, itemLocation, availability / quantity, image, marketplace, scrapedAt, searchQuery and searchUrl (the search the row came from), and epid only when eBay links the listing to a catalog product (often missing; none on some sites); plus shippingType, shippingCost (number; 0 = free, null = unknown), shippingCurrency, totalPrice (item + shipping, same currency), sellerUsername, sellerFeedbackScore, sellerFeedbackPercentage, sellerHasStore, sellerStoreName, sellerAccountType, topRatedPlus on every listing row; buyingFormat (auction / fixed_price), bestOfferEnabled, and sponsored for paid placements; bidCount & timeLeft for auctions; sold & soldDate for sold/completed listings, with bestOfferAccepted and priceIsAskingPrice on sales that were accepted offers (their price is the asking price, not the sale price); and listingStatus, startDate & endDate (plus categoryId, categoryPath, conditionId and sellerMemberSince) on rows built from an item page, which means detailed rows and single /itm/ URLs; plus deal and demand signals when eBay shows them: originalPrice/originalPriceValue, originalPriceType (list_price | was_price, only when eBay states it, mostly on detailed rows), discount/discountPercent, couponText/couponPrice/couponPriceValue (couponCode on detailed rows), recentPriceDrop, volumeDiscount/volumeDiscountPercent, quantitySold/watchers (exact totals on detailed rows; quantitySoldIsMinimum/watchersIsMinimum when a search card shows only a floor), productRating/productRatingCount, freeReturns, certifiedRefurbished and hasVariations. An absent field means "not shown", never zero. By default every row also carries the legacy basic_info (a raw copy of the search card) and detailed rows carry eBay's raw item-page modules; includeLegacyFields: false drops both and keeps every documented field. sold / both searches also append one sold-price-summary analytics row per search (searchQuery, searchUrl, averagePrice, medianPrice, recommendedPrice, sellThroughRate, soldPerDay, bestOfferAcceptedCount, soldListings, windowDays when a window is set, and rowsBeyondExactMatches when near matches are in the sample). Seller-feedback runs emit one row per review instead. Not every row is a listing: skip rows that carry _analytics or _searchMeta when you count listings. A search eBay confirms as empty writes one free { "_searchMeta": true, "url", "searchQuery", "searchUrl", "totalResults": 0, "note" } row.
Behaviors an agent should know:
- Always set
maxItems. It caps items per search, and eachsearchQuerieskeyword is its own search, so N keywords return up to N ×maxItems(2N × inbothmode), plus up to N charged sold summaries. searchQuery/searchQueries(withmarketplace,mode,condition,minPrice/maxPrice,sortBy,listingType, etc.) andstartUrlscan be combined, and each is its own search. The same search given twice for one site runs once (the log names the repeat); the same search on two sites is two searches. In modeboth, a URL that already holdsLH_Sold=1&LH_Complete=1runs once, as a sold search. The filter inputs build keyword searches only; a pasted/sch/i.htmlURL keeps its own eBay filters (LH_LocatedIn=1&_salic=<country code>, item specifics such asBrand=Nike,LH_ItemCondition=1000%7C3000,LH_BO=1,_sacatwith no keyword,_fss=1&LH_SpecificSeller=1&_saslop=1&_sasl=a%2Cb). A regional domain in a URL picks the site for that URL (an ebay.com URL followsmarketplace, except a/b/or/sch/<number>/i.htmlURL, which is always searched on its own site); setmarketplaceto that same site, because the connection country followsmarketplace. A/sch/<number>/i.htmlURL is searched as/sch/i.html?_sacat=<number>&…. Shapes other than these go through the website, wheremode,detailedItems: falseand the actor-side filters do not apply (for/b/URLs see the category-page bullet below).searchQuery,searchQueriesorsellerset next tostartUrlsadds a separate search; it does not filter the URLs. When a URL's filters match only a few listings, eBay may append near matches, which are returned and billed.- Ignored in URLs, so they return unfiltered results:
store_cat,LH_PrefLoc, distance / ZIP code, sold-date ranges (usesoldWithinDays). - Group or filter rows by
searchQuery, and join listings to theirsold-price-summaryrow bysearchUrl. WithsearchQueries, a listing several keywords share appears (and is billed) once per keyword. Without it, a detailed row appears once per run (and counts towardmaxItemsof every search that finds it), but fast and sold rows appear (and are billed) once per search, so two Start URLs that share listings return them twice. Read the run's status message: it names keywords with no matching listings, no exact matches, failed requests, or that the charge limit stopped before they ran. When searches lose pages, the message starts withPartial result, names the first three affected searches with what each one read and why, counts the rest, and says how many searches were complete; the run log lists all of them. Such a run ends FAILED only when every search lost a material part of its results to failed requests that were not an eBay rate limit (HTTP 429); with one search, when that search did. - Category page URLs (
/b/<name>/<categoryId>/bn_<id>): a plain category page is scraped through eBay's search, and sold mode and the summary work. Brand, model and curated pages are read from the page itself by default, with no summary.categoryPageMode: "keyword"searches the category plus the page-title words;"category"searches the whole category. A page scraped that way writes a free_searchMetarow. A top-level category page is searched only in"keyword"mode, and only when its title has words beyond the category name. Pages without a category number and invalid category ids are read from the page itself in every mode. Rows read from the page itself are detailed rows withpriceValue: null, nocurrencyandmarketplace: "ebay.com". detailedItems: true(default) fetches each active listing's item page (one extra request per listing) for item specifics, gallery and seller details; setfalsefor fast/cheap search-results data. Sold listings always come from search results regardless.includeDescription: trueadds the seller's description text in either mode.- Always set
includeLegacyFields: false. The default keeps a raw copy of eBay's page data on every row: ~50 KB, about 13k tokens, per detailed row, and about 40% of every fast or sold row. Lean rows carry every documented field. - Fast rows already carry the seller's name and feedback (
sellerUsername,sellerFeedbackScore,sellerFeedbackPercentage) and numeric shipping (shippingCost,totalPrice).shippingCost: nullmeans eBay gave no amount, not free shipping, andtotalPriceleaves out import VAT and fees.sellerHasStoreandsellerAccountTypeare on every detailed row. Fast and sold rows havesellerAccountTypeonly on EU, Swiss and Polish sites. They havesellerHasStoreon every row on sites such as ebay.de and ebay.co.uk; on ebay.com it is only evertrue, on some rows, so read a missing value as unknown. - Deal and demand fields (
originalPriceValue,discountPercent,couponPriceValue,watchers, …) appear only when eBay shows them, so read a missing field as unknown, not as zero or false.productRatingis the catalog product's rating, not the seller's feedback. mode:active(default),sold(real sold prices for comps, mostly the last ~90 days;soldWithinDaysfor an exact window), orboth.monitoringMode: truereturns only listings not seen in previous runs (state per search URL, so per keyword, in a Key-Value store); addenablePriceMonitoringto also return seen listings whose price changed (priceChanged: true,previousPrice). Do not overlap two monitoring runs of the same search. A listing that could not be recorded as seen is still returned and may come back once in the next run.- Pay-per-event billing: see the Pricing tab on the actor page. With a maximum cost per run set, only rows whose charge fits are delivered and the run then stops; a run that cannot afford one row ends SUCCEEDED with 0 rows and a status message that says so.
⚠️ Disclaimer
This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by eBay Inc. or any of its subsidiaries. All trademarks mentioned are the property of their respective owners.
The scraper reads only publicly available eBay listing, search and seller-feedback data. It does not log in to any eBay account and does not reach paid features or content behind the eBay.com login wall. Searches and item pages are read through eBay's mobile app interface with an app (guest) access token, not a user account; seller descriptions and feedback come from eBay's public pages. Users are responsible for ensuring their use complies with eBay.com's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization.
SEO Keywords
eBay scraper, scrape eBay, eBay.com scraper, eBay API, Apify eBay, eBay listings scraper, sold listings scraper, sold price comps data, product price tracking, eBay analytics data, sell-through rate data, price monitoring scraper, product research export, reseller pricing intelligence, ecommerce market data, auction data scraper, marketplace listings scraper, competitor price tracking, product sourcing data