BidSpotter Auction Scraper — Industrial & Machinery Lots avatar

BidSpotter Auction Scraper — Industrial & Machinery Lots

Pricing

$3.00 / 1,000 per lot returneds

Go to Apify Store
BidSpotter Auction Scraper — Industrial & Machinery Lots

BidSpotter Auction Scraper — Industrial & Machinery Lots

Paste any BidSpotter URL — catalogue, category, search or lot — for one row per lot: lot title, lot number, current bid, opening price, currency, bid count, watchers, category, brand, lot location, venue address, exact closing time, auction title, auctioneer and lot URL. No login, no browser.

Pricing

$3.00 / 1,000 per lot returneds

Rating

0.0

(0)

Developer

Scrapers Delight

Scrapers Delight

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Scrape BidSpotter — the biggest industrial and commercial online auction marketplace in North America — into a clean lot feed. One row per lot, carrying lotTitle, lotNumber, currentBid, openingPrice, currency, bidCount, watchers, category, brand, itemType, lotLocation, venueAddress, closingAt, auctionTitle, auctioneer and lotUrl.

Paste any BidSpotter URL you can copy out of the address bar — an auction catalogue, a category, a keyword search, or a single lot — or pick a category / keyword in the input form. No login. No API key. No headless browser. No CAPTCHA solving.

Scope, measured on 2026-08-12: BidSpotter's own sitemap listed 2,217 live auction catalogues; the metalworking category alone listed 12,679 live lots across 212 pages. Both counts were read off the live site, not quoted from a marketing page.

{
"startUrls": ["https://www.bidspotter.com/en-us/for-sale/metalworking"],
"maxLots": 50,
"includeLotDetails": true
}

Click Try for free and hit Start — that is the input this Actor ships prefilled. Three verification runs of exactly that input each returned 50 lots, 0 duplicates and 0 lot-detail misses. Wall-clock varied — 48 s, 69 s and 120 s — because BidSpotter's WAF blocks a share of requests and the Actor retries them. Retried pages are not billed; the row count does not move.


The wedge: real lot rows with the live bid

The only competing BidSpotter Actor with an honest, hand-written store page says this about itself, in its own README:

"Individual lot detail pages (per-item current bid / estimate) sit behind a JavaScript anti-bot challenge. This Actor works at the auction catalogue level."

Its output is catalogueId / title / auctionHouse / categories-with-counts. There is no per-lot bid in it, because it returns auctions, not lots. This Actor returns lots, with the bid, on plain datacenter proxy — because BidSpotter's AWS WAF matches the raw request path while the origin normalises it, so the equivalent normalised form of the same public page is served in full. Measured on 20 contiguous catalogue URLs from BidSpotter's own sitemap: the literal URL returned 3/20 = 15% and 5/20 = 25% across two tests; the route this Actor uses returned 20/20 = 100% and 19/20 = 95%, and lot detail pages 20/20 = 100%.

How it compares

Competitor prices below were read from the Apify Store API on 2026-08-12; capability claims come from each Actor's own published README and output field table.

This Actorlulzasaur/bidspotter-scrapergetdataforme/bidspotter-auctions-scraper
One row isa lotan auction cataloguean auction/lot (its README's sample record is placeholder data, not a real BidSpotter row)
Live currentBidyes, on catalogue URLsno field at allclaimed, no measurement published
bidCount / watchersyes, 100% fillednono
Lot-level category + locationyesnono
Exact per-lot closing timeyes (closingScope: "lot")auction dates onlyauction end only (its closingTime is documented as "auction end")
Proxy neededdatacenter (measured 20/20)RESIDENTIAL defaultRESIDENTIAL + US default
Price$0.003 / lot, no start fee$0.005 / result + $0.00005 start$0.009 / result + $0.05 start
Measured evidence on the pagetransport ladder, fill table, dupe rateone honest limitation paragraphnone

Neither competitor is dishonest about being an auction-level tool — lulzasaur says so plainly, and that is a real product for someone building a calendar of upcoming sales. If a calendar is what you want, that Actor is smaller and cheaper. This one is for people who need the lots.


Read this before you buy rows

  1. currentBid only exists on catalogue URLs. BidSpotter renders the live bid into the HTML of auction catalogue pages and never into category or keyword-search landing pages, which load bids over a websocket after the page paints. Measured directly:

    Page typeLot cardsCards with a bid rendered
    Auction catalogue (bscma10159)6052
    Category landing (heavy-construction-equipment)530
    Search landing (forklift)580

    Category and search runs are for discovery; bidCount (100% filled) still tells you exactly which lots have action, and you re-run the interesting auctionUrl values to get the amounts. The Actor logs a warning saying so rather than leaving a null column looking like a bug.

  2. Even on catalogue URLs, bid fill swings hard by catalogue. A platform run over 6 catalogues returned 207 of 400 lots (51.8%) with a live bid; a single actively bidding catalogue (bscpau10398, 366 open lots) was 37%, range $20–$850; a 3-catalogue run on 2026-08-12 returned only 10 of 90 (11.1%), because 48 of those 90 lots belonged to a live webcast sale that had not opened bidding yet; and 90 lots from one timed catalogue (bsctho10731) came back 27 with a bid (30%). The rest genuinely had no bid. Plan on the catalogue's state, not on an average.

  3. Estimates are effectively never published on BidSpotter. Across 39 lot pages sampled from 38 different auctions, exactly 0 published an estimate — BidSpotter's own data writes 0.00 for both bounds, which this Actor returns as null, not 0. The fields exist and will populate if an auctioneer ever fills them in. Plan on currentBid / openingPrice.

  4. closingScope tells you what closingAt means. "lot" = an exact per-lot close (timed auctions). "auction" = the sale's end date, because live/webcast auctions sell lots sequentially on the day and no per-lot time exists. In the 90-lot run above, 42 rows were "lot" and 48 were "auction".

  5. lotLocation and city are different places. lotLocation is where the item is; city / venueAddress is where the sale is held. They frequently differ on multi-site liquidations, which is why both are returned.


What you get — one row per lot

FieldWhat it is
lotId, lotNumber, lotTitle, descriptionThe lot itself (description is BidSpotter's card summary, truncated by the site)
currentBid, openingPrice, minimumBid, buyItNowPrice, currencyLive money fields as numbers in the lot's own currency, as shown at fetch time
estimateLow, estimateHighAuctioneer's published estimate — see gotcha 3 above
category, primaryCategory, brand, itemTypeBidSpotter's own taxonomy for the lot
lotLocation, venueAddress, city, countryWhere the item is, and where the sale is held
closingAt, closingScopeWhen bidding closes, and whether that time is per-lot or per-auction
bidCount, watchers, lotStatus, isClosedCompetition signals
auctionTitle, auctionRef, auctioneer, auctioneerUrl, auctionUrl, auctionType, auctionStatus, auctionStartsAt, auctionEndsAtThe auction the lot sits in
imageUrl, lotUrl, scrapedAtLinks and run stamp

All dates are ISO-8601 UTC. All money fields are numbers, never strings, and null means "BidSpotter published nothing" — never 0. Every run also writes a RUN_STATS record to the key-value store (linked from the run's Output tab) with its own duplicate rate, first-try page success rate and WAF block rate.


Field fill — measured on 180 lots across 27 auctions

Sample: a live run with metalworking as the category and includeLotDetails: true.

100% filledPartly filledEffectively never filled
lotId, lotNumber, lotTitle, description, currency, bidCount, watchers, lotStatus, isClosed, category, primaryCategory, lotLocation, closingAt, closingScope, auctionTitle, auctionRef, auctioneer, auctioneerUrl, auctionUrl, auctionType, auctionStatus, auctionStartsAt, auctionEndsAt, city, country, imageUrl, lotUrlitemType 92%, venueAddress 82%, brand 76%, openingPrice 41%estimateLow / estimateHigh 0%, buyItNowPrice 0%

The zero-edit default run on 2026-08-12 (50 lots, same category, same toggles) reproduced it: itemType 96%, venueAddress 98%, brand 84%, openingPrice 52%, and every field in the first column at 100%.

The headline that could mislead you: on a category or search run this is not a live-bid product. currentBid was 0% on both of those 50-lot and 180-lot runs, by design of the site (gotcha 1). Every run prints its own counts in the log and in RUN_STATS.


How to run it

Paste a URL (the fast path)

Go to BidSpotter, apply whatever filters you want, copy the URL out of the address bar, paste it in. Start URLs beats every other field in this form — clear it to use the selector instead.

{ "startUrls": ["https://www.bidspotter.com/en-us/auction-catalogues/bscpau/catalogue-id-bscpau10398"], "maxLots": 0 }

A catalogue URL gives you live bids. A category URL (/en-us/for-sale/metalworking) or a search URL (/en-us/search-forklift) gives you discovery without bids. A single lot URL is trimmed back to its catalogue and the whole catalogue is scraped. A URL that is not on bidspotter.com stops the run with an error listing the accepted shapes, rather than quietly returning nothing.

Watch a category

{ "source": "category", "categories": ["metalworking"], "maxLots": 200 }

Hunt a keyword across every live lot

{ "source": "search", "searchTerms": ["forklift", "cnc lathe"], "maxLots": 500 }

Sweep the whole marketplace

{ "source": "allAuctions", "maxAuctions": 50, "maxLots": 5000 }

2,217 catalogues were live in the sitemap on 2026-08-12; maxAuctions decides how many of them are walked and maxLots remains the real cost cap.

Speed vs depth

includeLotDetails is on by default: it opens every lot's page to add category, lot-level location, venue address, exact per-lot closing time, bid count, watchers, brand and item type. That is one extra request per lot — roughly 6x slower (180 lots in ~136s with it, versus ~22s for 40 lots without it). Turn it off for a fast sweep when you only need lot title, lot number, current bid, opening price, currency, auction title, auctioneer, auction dates and the lot URL. The price per lot is identical either way — this only saves time.

includeClosedLots is off by default, and closed lots are dropped before they are pushed, so you only pay for lots you can still bid on.


Sample rows

Two real rows from a run on 2026-08-12, unedited.

Fields people misread:

  • currentBid: null means no bid has been placed, or the page you scraped does not render bids (gotcha 1). It never means 0. Same for every money field.
  • bidCount: 0 means "nobody has bid"; bidCount: null means the lot page was not opened (includeLotDetails: false).
  • auctionEndsAt on a live/webcast sale is the catalogue's end date and can read earlier in the day than auctionStartsAt — that is BidSpotter's own data, and it is why closingScope exists.
  • brand and itemType are the auctioneer's own tagging, not a normalised manufacturer list ("Ford-RKI", "Mallet-Hammer").

Input

FieldTypeDefaultWhat it does
startUrlsstring list["https://www.bidspotter.com/en-us/for-sale/metalworking"] (prefill)Paste any bidspotter.com URL — catalogue, category, search, or a single lot. Wins over everything below. A catalogue URL is what gets you live bids.
sourceselectcategoryUsed only when startUrls is empty. category / search / allAuctions / auctionUrls (the last one reads startUrls).
categoriesstring list["metalworking"]One or more of the 14 primary category slugs. An unknown slug logs a warning listing the valid 14.
searchTermsstring list["forklift"] (prefill)Keywords as typed into BidSpotter's search box. De-duplicated by lot ID across terms, so overlapping keywords never bill twice.
includeLotDetailscheckboxtrueOpens each lot page for category, location, venue, per-lot closing time, bid count, watchers, brand, item type. ~6x slower, one extra request per lot. Same price either way.
resolveAuctionInfocheckboxtrueOn category/search runs, looks each auction up once (cached, from the ~175 KB terms page, not the ~1.2 MB catalogue) so every row carries the auction header. One request per auction, not per lot.
includeClosedLotscheckboxfalseClosed lots are dropped before pushing, so you do not pay for them. Turn on to build sold comps — but see Honest limits.
maxLotsnumber200 (prefill 50)Hard cap on lots returned. Also your cost cap: 50 = $0.15, 200 = $0.60, 5,000 = $15. 0 = no cap.
maxAuctionsnumber25 (prefill 10)Only for source: allAuctions. How many of the ~2,217 sitemap catalogues to walk.
proxyConfigurationproxyApify proxy, datacenterDatacenter is enough — see the transport ladder. Residential is not needed and costs you bandwidth.
requestConcurrencynumber4Parallel detail/header fetches. Clamped to 5. Raising it does not lower your bill; you pay per lot, not per request.

The 14 primary category slugs

agricultural-equipment · automotive-and-vehicles · computers-and-electronics · drilling-mining-and-forestry · food-and-beverage-equipment · heavy-construction-equipment · industrial-and-commercial · laboratory-and-pharmaceutical-equipment · metalworking · other-industries · plastics-and-rubber-machinery · printing-equipment · real-estate · woodworking


Pricing

$0.003 per lot returned — $3 per 1,000 lots. Charged on the lot-scraped event. There is no actor-start fee, no monthly rental and no platform fee from this Actor.

RunLotsCost
Prefilled smoke test50$0.15
A category watch200$0.60
A big keyword sweep5,000$15.00
Every live lot in metalworking12,679$38.04

You are charged for lots delivered. You are not charged for a closed lot that includeClosedLots filtered out, not for the same lot twice (duplicates are dropped by lot ID before anything is billed), not for the auction-header lookups, not for a retried page, and not for the Actor's proxy budget. A run that fetches 95 pages to deliver 90 lots bills 90 lots.

Rows are charged and pushed in the same call (Actor.pushData(items, 'lot-scraped')), so if you hit a platform spend cap mid-run you get whole rows and stop — never a half-billed dataset.

maxLots is your hard cost dial.


Honest limits

  • On category and search runs, currentBid is empty for every row — 0%. That is BidSpotter, not this Actor: bids are pushed to those pages over a websocket after paint and are never in the HTML. Measured 0 of 53 cards on a category landing page and 0 of 58 on a search landing page. What to do instead: discover with a category/search run, then paste the auctionUrl values you care about into Start URLs for the amounts.
  • estimateLow / estimateHigh are 0% filled across 39 lot pages from 38 auctions. BidSpotter is a liquidation marketplace, not a fine-art house. Nobody can sell you BidSpotter estimates; the site does not publish them.
  • buyItNowPrice is 0% filled on the same sample. The field exists because the markup does.
  • openingPrice is 41–52% filled (41% on 180 lots, 52% on 50 lots). Many auctioneers do not set one.
  • Closed lots often carry no price at all. Many BidSpotter auctioneers opt out of publishing results, so includeClosedLots: true gives you a sold-lot inventory, not a reliable sold-price history. If you need realised prices, this is not the source.
  • brand is 76–84% and venueAddress 82–98% filled. Both are auctioneer-entered, and a blank one means the auctioneer left it blank.
  • BidSpotter's WAF blocks roughly 1 request in 5 through Apify's proxy, so runs are slower than the row count suggests. Measured 17.8%, 23.7% and 8.8% blocked responses across three platform runs. The retry ladder recovered every one — 0 rows lost, 0 detail misses in all three — but the same prefilled 50-lot input took 48 s once and 120 s another time. Retries are not billed to you.
  • BidSpotter is global. A keyword search returns UK and EU lots alongside US ones. currency and country tell you which; city / lotLocation let you filter. There is no country input filter, because BidSpotter's own category and search pages do not expose one.
  • There is no monitor / new-lot alert mode. Each run is a full snapshot. Schedule it and diff on lotId yourself, or use a sibling below that has monitoring built in.
  • No login, no API key, no headless browser, no CAPTCHA-solving service. It reads public pages only, and it never touches login, account, bidding or checkout routes.

How it works, and the measured transport ladder

BidSpotter runs on CloudFront with AWS WAF in front of it, and the WAF fires a challenge (HTTP 202) or captcha (HTTP 405) action against auction-catalogue URLs. This is not IP reputation — it was measured identically from a home IP, from Apify datacenter proxy and from Apify residential proxy with fresh sessions.

The WAF matches the raw request path while the origin (IIS / ASP.NET) normalises it, so the Actor requests the equivalent normalised form of each public page. Same public page, same bytes, served 200 by BidSpotter's own origin. Every request is retried up to five times with a fresh proxy session, so residual challenges cost you nothing.

Two independent sustained-load tests, each 20 contiguous auction catalogue URLs taken from BidSpotter's own sitemap, run through the Apify proxy:

RouteTest 1Test 2
Literal catalogue URL3 / 20 = 15%5 / 20 = 25%
Route this Actor uses20 / 20 = 100%19 / 20 = 95%
Lot detail pages20 / 20 = 100%

The practical result: plain Apify datacenter proxy is enough. No residential bandwidth, no headless browser, no CAPTCHA solver, no login.

The WAF still blocks a meaningful share of individual requests, and the retry ladder — not a cleaner route — is what turns that into complete data. Measured across six runs on the Apify platform:

RunPages requestedFirst-try OKWAF-blocked responsesRows lostDetail misses
Three verification runs, 560 lots14687.7%00
Prefilled 50-lot run5983.1%13 of 73 calls = 17.8%00
Prefilled 50-lot run, repeat5981.4%18 of 76 calls = 23.7%00
90 lots from one catalogue9291.3%9 of 102 calls = 8.8%00

Read that honestly: roughly one request in five to ten is challenged, and it costs you wall-clock time, never rows. You are billed per lot delivered, so retries are free to you. The same input run from a home IP rather than through the Apify proxy measures far cleaner (98.3% and 96.7% first-try) — plan on the platform numbers above, not the home-IP ones. Every run writes its own firstTrySuccessRatePct and wafBlockRatePct to RUN_STATS, so you can audit this yourself.

Data comes from the pages' own server-rendered HTML plus the Google-Tag dataLayer blob that BidSpotter embeds on every lot and catalogue page.

Pagination integrity and duplicates

Verified on 21 contiguous listing pages (two full catalogues, 1,162 lot cards) and again on the Apify platform (400 lots across 6 catalogues, 9 contiguous pages): 0 duplicate lot IDs — a 0.00% in-run duplicate rate. The two runs on 2026-08-12 (50 lots over 1 category walk; 90 lots over 3 catalogues) also returned 0 duplicates. Sparse offsets prove nothing, so all of these were contiguous walks.

Lots are de-duplicated on lotId, before the lot page is fetched and before anything is billed — so the dataset never holds the same lot twice and you are never charged twice for it. The Actor also stops if the server ever repeats page 1, and it writes the measured duplicate rate to RUN_STATS on every run. Across separate runs there is no cross-run dedupe; diff on lotId yourself.


When a run fails

  • Zero lots throws. A green-but-empty run is the canonical broken-actor review, so it does not happen here: the Actor exits with an error naming the scope and the HTTP and WAF-block counts.
  • A non-BidSpotter Start URL throws with the four accepted URL shapes listed, instead of crawling nothing.
  • An unknown category slug logs a warning that lists the valid 14, so you can see the typo.
  • A listing shell is retried, not reported as empty. BidSpotter occasionally serves an HTTP 200 page carrying its pager and item count but no lot cards — measured once in 16 page-1 fetches. Page 1 is refetched up to three more times before the Actor will accept a zero.
  • A repeated page 1 stops pagination rather than looping and billing you for duplicates.
  • A run that cannot get past the WAF at all throws with the message that the path-normalisation route has been closed, rather than shipping a partial catalogue silently.

Who buys this

  • Used-equipment dealers and machinery brokersbrand + itemType + lotLocation + closingAt is a buy-side pipeline of what is coming to market within driving distance.
  • Fleet and construction buyers — the heavy-construction-equipment and automotive-and-vehicles categories with bidCount and watchers show which lots are already contested before you commit a bidder's time.
  • Resale arbitrage sellersopeningPrice versus your own eBay/Facebook comps, filtered to lots closing this week via closingAt and closingScope.
  • Asset-recovery and liquidation lendersauctioneer + auctionTitle + venueAddress across the whole sitemap is a map of who is liquidating what, and where.
  • Auctioneers doing competitive researchauctioneer, auctionType and lot counts per catalogue show which houses are winning which categories.
  • Equipment-marketplace and valuation startups — a structured lot feed with ISO timestamps and numeric money fields, at $3 per 1,000 rows, to seed a supply-side index.

Sibling Actors

Same row discipline, other auction sites. All are separate Actors: one site, one schema.

ActorWhat it isWhy you would use it instead
Proxibid ScraperAuction lots, prices and new-lot alertsProxibid's industrial and firearms catalogues — and it has the monitor mode this one does not
Equip-Bid Auction ScraperMidwest equipment auction lots + new-auction alertsRegional Midwest liquidations BidSpotter does not carry
K-BID Auction ScraperMinnesota-centric online auction lotsLocal surplus and business liquidations
GSA Auctions ScraperUS federal surplus lots, bids and alertsGovernment-owned equipment, not commercial liquidation
PublicSurplus ScraperState, county and school-district surplusPublic-sector sellers with different closing rules
Municibid ScraperMunicipal surplus auctions and alertsTown and county fleet vehicles and equipment
HiBid Auction ScraperHiBid lots, bids and prices, USA and CanadaThe widest general-auction aggregator
Multi Auction SearchOne keyword across storage, surplus and estate sitesWhen you do not know which site has the item

BidSpotter is where you go for industrial and machinery lots with a live bid and a lot-level category. HiBid is where you go for breadth. GSA and PublicSurplus are where you go when the seller is a government.


FAQ

Does this need a BidSpotter account or login?

No. It reads public pages only. There is no login, no API key, no cookie jar and no CAPTCHA-solving service anywhere in it.

Why is currentBid empty on my category or keyword run?

Because BidSpotter does not put bids in the HTML of category or search pages — it loads them over a websocket after the page paints. Measured: 0 of 53 cards on a category page, 0 of 58 on a search page, versus 52 of 60 on an auction catalogue page. Paste the catalogue URL into Start URLs and re-run to get the amounts.

Can I just paste a URL from my browser?

Yes, and that is the intended path. Catalogue, category, search, or a single lot URL all work — a lot URL is trimmed back to its catalogue. Start URLs overrides the source selector.

Does it return auctioneer estimates?

The fields are there but BidSpotter publishes none: 0 of 39 lot pages across 38 auctions carried one. Anyone selling you "BidSpotter estimates" is generating them somewhere else.

What does a 200-lot run cost?

$0.60. The rate is $0.003 per lot returned, $3 per 1,000, with no start fee. maxLots caps it.

Do I get charged for lots that get filtered out?

No. Closed lots removed by includeClosedLots: false and duplicates removed by lot ID are both dropped before billing.

Two runs — will I get duplicates?

Within a run, no: 0.00% duplicate rate measured over 1,162 contiguous lot cards, and dedupe happens on lotId before billing. Across runs there is no dedupe — diff on lotId yourself.

Can I schedule it?

Yes, with Apify Schedules like any Actor. There is no built-in monitor or alert mode, so a scheduled run gives you a fresh full snapshot to diff, not a "what's new" digest.

Does it need a residential proxy?

No. Datacenter is the default and the measured route returned 20/20 and 19/20 on 20 contiguous catalogue URLs. Residential costs you bandwidth for no measured gain.

Can I get every lot on BidSpotter in one run?

Set source: "allAuctions", raise maxAuctions past the sitemap size (2,217 live catalogues on 2026-08-12) and set maxLots: 0. Budget before you do — that is a long run and an unbounded bill unless maxLots caps it.

Something looks wrong — how do I debug it?

Open the run's Output tab and read RUN_STATS: it carries the lot cards seen, lots emitted, lots with a live bid, duplicate rate, closed lots skipped, lot-detail misses, HTTP call count, first-try page success rate and WAF block rate for that exact run.

Will a run ever succeed with zero rows?

No. Zero lots throws an error naming the scope and the HTTP counts, so a broken run never looks like an empty market.

Is the data personal?

No. Rows describe items and the auction houses selling them. There are no bidder identities and nothing behind authentication.


This Actor reads publicly visible BidSpotter listing pages. It does not log in, does not solve CAPTCHAs, does not collect anything behind authentication, and never requests login, account, bidding or checkout routes. It keeps concurrency at 4, hard-capped at 5.

Rows contain business information (auctioneer names, venue addresses, lot descriptions) rather than personal data, but auctioneer contact details are business contact details and are regulated as such — if you use them for outreach, GDPR, CCPA and CAN-SPAM apply to you.

You are responsible for complying with BidSpotter's Terms of Service and with how you use the data. BidSpotter® is a trademark of Auction Technology Group; this Actor is not affiliated with, endorsed by, or sponsored by them.


Found a missing field or want a new filter? Open an issue on the Issues tab.