Reverb Music Gear and Sold Price Guide Scraper avatar

Reverb Music Gear and Sold Price Guide Scraper

Pricing

from $1.20 / 1,000 results

Go to Apify Store
Reverb Music Gear and Sold Price Guide Scraper

Reverb Music Gear and Sold Price Guide Scraper

Scrape reverb.com music gear: guitars, amps, synths, pedals, drums and pro audio. Search live listings by brand, category, condition, price, year, region and shipping, or paste links. Uniquely returns the sold Price Guide per gear model: median, low, high and quartile realised prices.

Pricing

from $1.20 / 1,000 results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

0

Monthly active users

14 days ago

Last modified

Categories

Features

Limited permissions

Share

Pull music gear from Reverb (reverb.com), the marketplace for new, used and vintage guitars, amps, synthesizers, pedals, drums and pro audio. Search live listings with the marketplace's own brand, category, condition, price, year, region, shipping and seller filters, or paste links and let the actor route them. Alongside every listing you also get the Price Guide: what that exact gear model has actually sold for, as a median, a low and high, quartiles, a breakdown per condition, the gap between asking and realised price, the individual recent sales, and a period by period history. Export the dataset as JSON, CSV or Excel, or pull it straight into your app through the API.

Why This Scraper?

  • Realised sale prices, not just asking prices. An asking price tells you what a seller hopes for. This returns what buyers actually paid: median, low, high, 25th and 75th percentile, per condition, with the individual sales behind the numbers and their dates.
  • A deal rating on every live listing. Each listing is positioned against its own model's sold history and labelled below-market, at-market or above-market, with the exact percentage above or below the sold median.
  • Over 60 fields per listing including view and watcher counts, days on market, price drops, seller feedback and rating, seller location, per region shipping rates, return policy, and the canonical model id.
  • Three modes, one actor. Keyword search across live listings, Price Guide lookup by gear model, and paste anything: item links, price guide links, product links, shop links, brand links, marketplace search links, or bare listing ids.
  • Built for recurring monitoring. Incremental mode returns only what changed since the last run, so a daily watch on "1960s Stratocasters under $8,000" returns the new listings and the price drops instead of the same catalogue every day.
  • Filters that actually narrow. Category and price are re-checked against each listing's own data after the search, because the marketplace's own filters can otherwise let off-category or out-of-window rows through.

Use Cases

  • Gear buyers and collectors: check whether an asking price sits below, at, or above what the exact model has actually sold for before making an offer.
  • Dealers and resellers: source stock across brands and categories, and price it against realised sale history instead of sticker prices.
  • Vintage gear researchers: track price trends by condition, year and category over time using the period by period sale history.
  • Marketplace monitoring tools: watch a saved search or a shop and get only new listings, price drops and Price Guide changes on a schedule.
  • Price comparison and alert apps: feed live asking prices plus realised sold prices into your own app, bot or spreadsheet.
  • Market analysts: build datasets of completed sales, ask to sold spreads and per condition pricing for a category of instruments.

Data You Get

Sample shape: values are illustrative placeholders, not from a live listing.

FieldExample
recordType"listing" (also "priceGuide" in Price Guide mode)
listingId"12345678"
title"Sample Vintage-Style Solidbody Guitar"
make / model / year / finish"Sample Brand" / "Model X" / "1965" / "Sunburst"
condition / conditionSlug"Very Good" / "very-good"
price / currency / priceDisplay1200.0 / "USD" / "$1,200"
originalPrice / priceDropPercent1400.0 / 14
categories / rootCategory["Electric Guitars / Solid Body"] / "electric-guitars"
state / inventory / offersEnabled / isAuction"live" / 1 / true / false
shopName / shopSlug / preferredSeller"Sample Music Shop" / "sample-music-shop" / true
sellerLocation / sellerCountryCode"Springfield, United States" / "US"
views / watchers / daysOnMarket240 / 12 / 30 (views and watchers need the item page read on)
freeShipping / shippingRatestrue / [{"regionCode": "US", "price": 0.0}]
photo / photos / photoCountimage URL / list of image URLs / 4
urllink to the listing, model or price guide page
publishedAt / scrapedAt"2026-01-01T00:00:00Z"
guideMedianPrice / priceVsGuidePercent / dealRating1350.0 / -11.11 / "below-market" (needs the sold Price Guide on)
soldPriceMedian / soldPriceLow / soldPriceHigh1350.0 / 900.0 / 2200.0 (inside priceGuide on listings)
byCondition / recentSales / priceHistoryper-condition breakdown / individual sales / monthly averages, as arrays
changeType / firstSeenAt / lastSeenAt"NEW" / "2026-01-01T00:00:00Z" / "2026-01-01T00:00:00Z" (incremental mode only)

Price Guide mode records (recordType priceGuide) are a gear MODEL rather than one listing: productId, soldSalesTotal, soldSampleSize, soldPriceP25, soldPriceP75, soldPriceAverage, askPriceAverage, askToSoldDiscountPercent, firstSaleDate, lastSaleDate, usedListings, newListings, usedLowPrice, newLowPrice, productRating and productReviewCount, plus a nested reviews list (reviewId, title, body, rating, reviewer, date, verified, helpfulVotes when the source provides it). Reviews are read for Price Guide records only, never as separate dataset items; Max reviews per Price Guide record (maxReviewsPerProduct, default 20, at most 1000, 0 turns reviews off) bounds them. The Reviews view in the Console unwinds the list into one row per review.

Reviews add no charge of their own: a Price Guide record is billed exactly as before, whether it carries 0, 20 or 1000 reviews. The maxReviewsPerProduct limit only bounds how many are read and attached.

soldPriceMedian is the number to compare an asking price against, and soldPriceP25 / soldPriceP75 bracket the normal trading range that dealRating is judged from. A model with fewer than five recorded sales gets its live-market snapshot (usedListings, newListings, usedLowPrice, newLowPrice) but no dealRating, left empty rather than guessed on a thin sample. A sale recorded in a currency other than the reported one is excluded from the statistics rather than mixed in, and the count of excluded sales is reported as mixedCurrencySalesSkipped.

How to Use

  1. Pick a mode: search (keyword search across live listings, with filters), price-guide (look up gear models and their realised sold-price statistics), or url (paste links).
  2. Add keywords or links, and for search and Price Guide modes narrow with the brand, category, condition, price, year, region and shipping filters (URL mode ignores them, the link carries its own).
  3. Turn on the sold Price Guide and, if you also want each listing's own item page (views, watchers, seller location, policies and videos), turn that on too. Each is a per-result surcharge, so a lean run can leave both off.
  4. Set Max results, click Start, then read the dataset as JSON, CSV or Excel, through the API, or via the MCP connector.

Search live listings with filters:

{
"mode": "search",
"queries": ["Stratocaster"],
"category": "electric-guitars",
"conditions": ["excellent", "very-good"],
"minPrice": 500,
"maxPrice": 3000,
"includeSoldPriceGuide": true,
"maxItems": 20
}

Look up what gear models actually sell for:

{
"mode": "price-guide",
"queries": ["Moog Subsequent 37", "Shure SM57"],
"includeSoldPriceGuide": true,
"maxItems": 20
}

Paste links of any supported kind:

{
"mode": "url",
"urls": [
"https://reverb.com/item/00000001-sample-listing",
"https://reverb.com/price-guide/sample-brand-model",
"https://reverb.com/shop/sample-music-shop",
"https://reverb.com/marketplace?query=Gibson%20Les%20Paul&condition=used"
],
"includeSoldPriceGuide": true,
"maxItems": 100
}

Watch a search daily and get only the changes:

{
"mode": "search",
"queries": ["1960s Stratocaster"],
"maxPrice": 8000,
"incrementalMode": true,
"stateKey": "vintage-strat-watch",
"maxItems": 0
}

In URL mode the urls field now ships with one working example per shape below (previously it was empty unless you typed links). Clear the list and paste your own to run only those.

ShapeExampleWhat you get
Marketplace search (keyword + filters)reverb.com/marketplace?query=Gibson%20Les%20Paul&condition=usedMatching listings
Paginated search...listings?query=stratocaster&page=2Listings from that page forward (partial scope: nothing is marked EXPIRED)
Brand pagereverb.com/brand/fenderListings of that brand
Shop pagereverb.com/shop/<shop-slug>Listings of that shop; an unknown shop logs a warning
Itemreverb.com/item/103425668 or 103425668One listing
Price Guide search...api/csps?query=stratocasterGear models with sold-price statistics
Price Guide productreverb.com/price-guide/<slug> or ...comparison_shopping_pages/126164One gear model
Price Guide sales...comparison_shopping_pages/126164/transactionsThe same model record with its sold history (the same target as the plain product link, so only one of the two is pre-filled)

A link that is not one of these is reported and skipped.

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/reverb-scraper").call(run_input={
"mode": "search",
"queries": ["Stratocaster"],
"maxItems": 20,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["title"], item.get("price"), item.get("dealRating"))

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/reverb-scraper').call({
mode: 'search',
queries: ['Stratocaster'],
maxItems: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Filters that narrow twice

Category and price are applied both upstream (so the walk itself stays narrow) and again against each returned listing's own category and its own US dollar price, because the marketplace's own matching can otherwise let off-category or out-of-window rows through, sometimes a large share of a page. The walk for a keyword stops reading new pages once it has read enough candidate listings to fill that keyword's share of maxItems, and the re-check runs after that. So a heavily filtered run can return fewer rows than maxItems asks for even when later pages still hold matching listings. Raising maxItems makes the walk read further.

In search and Price Guide modes each keyword gets its own share of maxItems, split evenly, so the first keyword of a multi-keyword run cannot silently use up the whole cap. A share a keyword does not fill (because it has fewer matches) is not handed on to the other keywords. In URL mode the pasted item and model links are read first, then each pasted search, shop or brand link in order takes whatever is left of maxItems, so an early search link can use up the rest of the cap on its own.

Results are read 50 at a time (one page), so the walk for one keyword can read up to a full page of candidates before trimming to that keyword's own share. A listing read past the share is already counted as seen for duplicate detection even though it was never returned. When two keywords in the same run overlap (close synonyms, or one a substring of the other), a later keyword skips those listings, so it can return fewer matches than it would alone, or none at all, and the run can finish below maxItems. Run overlapping keywords as separate runs if you need every match from each one.

Resume and recurring updates

  • Resume (resumeFromRunId) continues one interrupted run: paste its run or dataset id and the actor skips everything already collected there, so you don't pay twice.
  • Incremental mode (incrementalMode) is for running this same search again and again (for example daily) and getting only what changed. Each result is classified NEW, UPDATED (with changedFields), UNCHANGED (suppressed and not billed unless emitUnchanged is on), REAPPEARED, or EXPIRED (only after a run that scanned the whole tracked search, and only with emitExpired). stateKey names or shares the stored state; leave it empty to let the actor derive one from the mode, keywords, links and filters.
  • What is compared. Every field of the record: asking price, currency, condition, listing state and inventory, title, description, seller, shipping, photos and the Price Guide statistics for Price Guide records. Never compared: the scrape time, days on market, the views, watchers and offer-count counters (they tick on their own), and the reviews list of a Price Guide record (a review read can come back short or be limited by maxReviewsPerProduct, which would otherwise create an UPDATED row for data that did not change); all of these stay in every row. Photo links are compared by the image file, not by the CDN's per-link signature. Timestamps are compared as the instant they name (the source shows the same moment in a different time-zone offset from one fetch to the next), the order of the recent-sales list does not matter, and the sold statistics of a Price Guide record (averages, median, quartiles, the per-condition table) count as changed only when the model's total sale count or its latest sale date moved too, because the sampled sales at the edge of the window shift between fetches.
  • Ignore fields when detecting changes (ignoreFieldsForChanges, incremental mode only) lists extra field names that must never create an UPDATED row, for example photos. A dotted name such as shippingRates.rate ignores that key inside a nested field. Ignored fields still appear in the rows, and changing the list does not re-bill your saved baseline.
  • Price and availability only (changeScope = priceAndStock) compares only the prices, currency, listing state, live flag and inventory and each shipping rate by region (shippingRates: amount, currency and whether it is flat or carrier-calculated; a region appearing or disappearing counts too) (for Price Guide records, the sold median and average, ask average, low prices and listing counts). Titles, descriptions, photos and seller details never create an UPDATED row. Default is all fields.
  • Compact update rows (compactUpdates) make UPDATED and EXPIRED rows short: ids, link, title, current price and availability, plus priceChanges with the old and new value of each moved field and variantChanges with the old and new rate of each shipping-rate region (regionCode) that was added, removed or changed. NEW rows stay complete. A compact row carries no item-page or Price Guide data, so the detail-enrichment charge is not applied to it.
  • Expire after N missed scans (expireAfterMissedScans, default 1) marks a result EXPIRED only after it was missing from that many complete scans in a row. EXPIRED means the listing was not found again; it does not prove it sold or was withdrawn, so use the state and inventory fields for availability.
  • Partial scans never expire anything. A link that starts at ?page=2 or later, a run stopped by Max results, or a Resume run is an incomplete scan and never produces EXPIRED rows.
  • EXPIRED rows are not limited by Max results. They are computed from whatever is left in the tracked baseline once a complete scan proves it is gone, and Max results only governs the live collection in that same run. A state key tracking a large catalogue that mostly disappeared between runs (for example after narrowing the filters) can return far more EXPIRED rows in one run than Max results was set to. If you need a hard ceiling on a single run's total output, keep emitExpired off, or use a narrower, more stable tracked search.
  • Incremental mode with a Max results cap counts unchanged listings while walking. The walk for a keyword stops reading new pages once it has read that keyword's share of maxItems in listings not already seen this run, whether or not they turn out to be unchanged. If the first page is all unchanged, the run can stop there and report nothing changed even though new listings sit on a later page. For scheduled monitoring, set maxItems to 0 (as in the example above), or at least sort by newest so new listings come first.
  • Seeding incremental state from a resumed run is a one-off with a catch. Combining resumeFromRunId with incrementalMode on a state key with no saved state records every result of the resumed run as already known, but without its details. The next incremental run therefore returns each of those results once as UPDATED (and bills it), with every field listed in changedFields. From the run after that they are classified normally.
  • A run that the platform restarts part way through (for example when it moves the run to another server) picks up again at the keyword or link it was working on. That keyword or link starts from its first page again, so rows it had already returned can be returned (and billed) a second time, and the run's total can go over maxItems. In incremental mode, rows returned before the restart for earlier keywords are not recorded in the saved state, so the next run reports them as NEW again.

Send results into your apps (MCP connectors)

Optionally pipe results into Notion, Linear, Airtable or Apify via MCP connectors, using the Export to your apps (MCP connectors, optional) section of the input. Authorize a connector under Apify, Settings, API and Integrations, then select it here.

  • mcpConnectors selects the connectors this run exports into.
  • notionParentPageUrl is the Notion page under which one page per item is created. It is required for the Notion export and ignored by every other connector.
  • maxNotifyListings caps how many items are written to each connector.

Each connector receives a condensed, human readable summary per item: a title plus the key fields flattened to plain text, with nested objects collapsed to their main value and long lists trimmed. The complete record, including the whole priceGuide block, always stays in the Apify dataset. The export is a side channel: it never changes the dataset output, and a connector error is logged as a warning while the run still succeeds.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch, price-guide, or url.
queriesarray["Fender Stratocaster"]Keywords, read in search and Price Guide modes. Each is searched separately and gets its own share of the item cap.
urlsarraysampleReverb links or bare listing ids, read in URL mode. Filters below are ignored in this mode.
makestring(none)Brand, matched against the marketplace's own brand list (capitalisation does not matter); a brand that does not exist stops the run with a message instead of searching everything. Applies to search and Price Guide modes.
categorystring(any)A top-level category (such as electric-guitars) or the name of a sub-category such as Solid Body or Electric Guitars / Solid Body, matched against the marketplace's own category list; a name shared by several categories (for example 12-String) needs its full path. A category that does not exist stops the run with a message instead of searching everything. Applies to search and Price Guide modes.
minYearinteger(none)Earliest year. Applies to search and Price Guide modes.
maxYearinteger(none)Latest year. Applies to search and Price Guide modes.
conditionsarray[]One or more of new, b-stock, used, mint, excellent, very-good, good, fair, poor, non-functioning. Search mode only.
minPriceinteger(none)Minimum price in US dollars. Search mode only.
maxPriceinteger(none)Maximum price in US dollars. Search mode only.
itemRegionstring(any)Seller country. Search mode only.
shipsTostring(anywhere)Country the seller ships to. Search mode only.
shopSlugstring(none)One seller, given as the handle in the shop address. Search mode only.
handmadeOnlybooleanfalseHandmade or custom built gear only. Search mode only.
freeShippingOnlybooleanfalseOnly listings that ship free. Search mode only.
preferredSellersOnlybooleanfalsePreferred sellers only. Search mode only.
sortBystringrelevancerelevance, price-asc, price-desc, or newest. Search mode only.
includeSoldPriceGuidebooleantrueAttach the realised sale statistics, and score each live listing against them.
fetchDetailsbooleanfalseRead each listing's own item page for views, watchers, seller location, policies and videos.
maxReviewsPerProductinteger20Price Guide records: how many owner reviews to attach as a nested reviews list, newest first. 0 turns reviews off, at most 1000. Reviews add no charge. In incremental mode the reviews list never decides UPDATED.
maxItemsinteger20Maximum number of results returned across the whole run. 0 for unlimited.
maxPagesinteger0Maximum result pages walked per keyword or link, at 50 results a page. 0 for no page limit.
resumeFromRunIdstring(none)Continue one interrupted run without returning, or charging for, results already collected there.
incrementalModebooleanfalseTurn this on for daily or recurring monitoring: return only what changed since the last run of this search.
changeScopestringallIncremental mode: priceAndStock returns an UPDATED row only for price or availability changes.
compactUpdatesbooleanfalseIncremental mode: short UPDATED and EXPIRED rows with priceChanges and variantChanges.
expireAfterMissedScansinteger1Incremental mode: mark EXPIRED only after this many consecutive complete scans missed the result.
ignoreFieldsForChangesarray[]Incremental mode: field names (or dotted paths) that never create an UPDATED row.
stateKeystring(none)Name a monitoring campaign, or share state across differently configured runs. Derived automatically when empty.
emitUnchangedbooleanfalseAlso return (and bill) results that have not changed since the last run.
emitExpiredbooleanfalseAlso return (and bill) results that were present before and are no longer found.
proxyobjectApify ProxyConnection settings. Leave the default selected unless a run reports refused requests.
mcpConnectorsarray(none)Optional: send a summary of each result to apps you authorized under Integrations.
notionParentPageUrlstring(none)Notion connector only: page under which item pages are created.
maxNotifyListingsinteger50Cap on items written to each connector per run. Does not affect the dataset.
searchQueriesarray(none)Hidden alias of queries.
conditionstring(none)Hidden alias of conditions (a single value).
maxListingsinteger(none)Hidden alias of maxItems.
scrapeDetailsboolean(none)Hidden alias of fetchDetails.
proxyConfigurationobject(none)Hidden alias of proxy.

Input aliases

Inputs written for other Reverb scrapers keep working. These hidden aliases are accepted and map onto the fields above: searchQueries (Search queries), condition (one value for Conditions), maxListings (Max items), scrapeDetails (Fetch details) and proxyConfiguration (Proxy). When both the alias and the main field are given, the main field wins, unless it is still at its default value, in which case the alias value is used.

Output Example

Sample shape: values are illustrative placeholders, not from a live listing.

{
"recordType": "listing",
"listingId": "00000001",
"sku": "REF-0001",
"slug": "sample-brand-model-1965-sunburst",
"url": "https://reverb.com/item/00000001-sample-brand-model-1965-sunburst",
"comparisonShoppingPageId": "000000",
"title": "Sample Brand Model 1965 Sunburst",
"make": "Sample Brand",
"brandSlug": "sample-brand",
"model": "Model X",
"year": "1965",
"finish": "Sunburst",
"rootCategory": "electric-guitars",
"categories": ["Electric Guitars / Solid Body"],
"condition": "Very Good",
"conditionSlug": "very-good",
"price": 1200.0,
"currency": "USD",
"priceDisplay": "$1,200",
"originalPrice": 1400.0,
"priceDropPercent": 14,
"state": "live",
"inventory": 1,
"offersEnabled": true,
"offerCount": 0,
"isAuction": false,
"freeShipping": true,
"freeExpeditedShipping": false,
"shippingRates": [{ "regionCode": "US", "price": 0.0, "currency": "USD" }],
"shopName": "Sample Music Shop",
"shopSlug": "sample-music-shop",
"preferredSeller": true,
"sellerFeedbackCount": 120,
"sellerRatingPercentage": 100.0,
"sellerLocation": "Springfield, United States",
"sellerCountryCode": "US",
"views": 240,
"watchers": 12,
"daysOnMarket": 30,
"publishedAt": "2026-01-01T00:00:00Z",
"scrapedAt": "2026-01-01T00:00:00Z",
"guideMedianPrice": 1350.0,
"priceVsGuidePercent": -11.11,
"dealRating": "below-market",
"priceGuide": {
"soldSalesTotal": 140,
"soldSampleSize": 60,
"currency": "USD",
"soldPriceLow": 900.0,
"soldPriceP25": 1100.0,
"soldPriceMedian": 1350.0,
"soldPriceP75": 1600.0,
"soldPriceHigh": 2200.0,
"soldPriceAverage": 1380.0,
"askPriceAverage": 1490.0,
"askToSoldDiscountPercent": 7.4,
"firstSaleDate": "2024-03-01",
"lastSaleDate": "2026-01-01",
"byCondition": [
{ "condition": "Excellent", "salesCount": 22, "lowPrice": 1200.0, "medianPrice": 1450.0, "highPrice": 1700.0 }
],
"recentSales": [
{ "date": "2026-01-01", "condition": "Excellent", "askPrice": 1500.0, "soldPrice": 1425.0, "currency": "USD" }
],
"priceHistory": [
{ "periodStart": "2025-12-01", "averageAskPrice": 1490.0, "averageSoldPrice": 1380.0 }
],
"liveMarket": { "usedListings": 34, "newListings": 6, "usedLowPrice": 900.0, "newLowPrice": 1899.0 },
"mixedCurrencySalesSkipped": 0
}
}

Plan Requirement

Reverb's public data interface answers normal requests, and the actor reads that interface rather than the website pages. The default Apify Proxy connection is tried first. Whether a free plan's default connection is enough has not been measured for this release, so no "works with no action" promise is made here. What the actor does, as it now reads in the code:

  • If the residential connection is refused for the account (Apify free plans do not include residential proxies), the run logs: "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable." and then "Served over the backup connection (the default connection was unavailable)." when a request is served that way.
  • If the account has no proxy access at all, the run stops with: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required". If you entered your own proxy URLs, check their credentials.
  • If residential is unavailable and the backup connection could not load the pages, the run stops with: "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Reverb pages."
  • If the requests simply fail, the run stops with: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search." Run it again later.

Residential traffic is billed by your Apify plan, so keep the default connection selected unless a run reports refused requests. You can also supply your own proxy URLs.

FAQ

How much does it cost?

You pay per result returned, with the sold Price Guide and each listing's own item page billed only when you switch them on, once per result they actually add data to. The Pricing tab shows the current rates. Use Max results to cap the cost of any run.

This actor collects only publicly available marketplace data. You are responsible for how you use it: follow Reverb's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Listing content, photos and seller information may carry rights belonging to the seller or the marketplace.

Can I get only new or changed listings on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and reappeared results by default, and unchanged ones are not billed unless you turn emitUnchanged on. Leave Max results at 0 for monitoring runs so the walk is not cut short by unchanged listings.

Why did I get fewer results than Max results asked for?

A few reasons, all described under How to Use above. The category and price filters are re-checked against each listing's own data after the walk has already stopped reading pages, so a heavily filtered run can return fewer than maxItems even when later pages hold more matches. Each keyword only gets its own share of the cap, and an unused share is not passed on. Keywords that overlap in one run can take matches away from each other. In incremental mode, unchanged listings are suppressed but still count toward the walk's stop point. Raise maxItems, broaden the filters, or run overlapping keywords separately.

Why did incremental mode return more EXPIRED rows than Max results?

emitExpired rows come from comparing the whole tracked baseline against what a complete scan found this run, and that comparison is not capped by maxItems, only the live collection is. A state key watching a large catalogue that shrank a lot since the last run (for example after narrowing the filters) can return many more EXPIRED rows in one run than maxItems was set to. Keep emitExpired off if you need a hard ceiling on a single run's output.

Why did my run fail instead of returning an empty dataset?

If every request was refused, the run stops with a clear message so "nothing matched" is never confused with "nothing could be read". Run it again in a few minutes, or switch the connection if it keeps happening.

What is the difference between Resume and Incremental mode?

Resume (resumeFromRunId) continues one specific interrupted run using its run or dataset id. Incremental mode remembers state itself, keyed on the search, and is for running the same search again and again on a schedule. They can be combined once, to seed a brand-new monitoring campaign's baseline from an existing run, but not against a state key that already has saved state. After such a seed, the next incremental run returns every seeded result once as UPDATED (billed), because the seed records which results exist but not their details.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

๐Ÿ”— Want more e-commerce data?

Pair this actor with these related scrapers from the same team:

๐Ÿ›’ Depop Scraper
Scrape Depop search results, listings, shops, and reviews to JSON, CSV, or Excel. Extract...
โšฝ Whatnot Scraper
Scrape Whatnot live and upcoming shows, queued items and lots, and seller profiles...
๐Ÿท๏ธ Vinted.fr
Scrape Vinted.fr, France's C2C second-hand fashion marketplace: search with...
๐Ÿท๏ธ Chrono24 Scraper
Scrape Chrono24 luxury watch listings by keyword, filters or URL. Extract 50+ fields...
๐Ÿ›’ OfferUp Scraper
Scrape OfferUp listings by keyword, location and radius. Returns 40+ fields per item...
๐Ÿ›’ Mercari Japan Scraper
Scrape Mercari Japan listings, sellers and reviews at scale. Extract names, prices...

๐Ÿ‘‰ Browse all abotapi scrapers

๐Ÿ’ฌ Support

  • ๐Ÿž Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • ๐Ÿ› ๏ธ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • โญ Enjoying it? A quick review on the actor page helps other users find it.