# 888lots Scraper — Wholesale Items, Lots & Manifests (`crawloop/888lots-scraper`) Actor

Scrape 888lots wholesale items and fixed-price pallet lots with Amazon ASIN/BSR, Walmart metadata, MOQ, pricing, and full SKU manifests. Auction pages with linked items. Listings or details mode — fast curl_cffi, residential proxy ready.

- **URL**: https://apify.com/crawloop/888lots-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** E-commerce, Other
- **Features:** Limited permissions
- **Stats:** 3 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 detail results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## 888lots Scraper — Wholesale Items, Pallet Lots & Auction Manifests

> **Disclaimer:** Unofficial tool — not affiliated with, sponsored by, or endorsed by 888lots or its affiliates. Data is read from publicly accessible pages only. No login. You are responsible for complying with applicable law (including GDPR where personal data appears) and the site’s terms. No warranty on accuracy or availability. Provided for informational and research use.

Scrape **wholesale items**, **fixed-price pallet lots** (with full **SKU manifests**), and **liquidation auctions** into clean JSON. Detail rows include **Amazon ASIN / BSR**, **Walmart pricing**, MOQ, condition, warehouse ZIP, and image galleries — built for **resale arbitrage**, **liquidation sourcing**, and **inventory valuation**.

**Best for:** wholesale buyers, liquidators, and data teams who need structured lot manifests and ASIN-linked comps for Sheets, Airtable, databases, and custom pipelines.

> **Crawloop Marketplace & E-commerce Suite** — marketplace search and pricing intelligence for product discovery workflows.

| Amazon Search Scraper | eBay Active Listings Scraper | eBay Sold Listings Scraper | **888lots Scraper** ◄── *you are here* |
| :---: | :---: | :---: | :---: |
| [Amazon Search Scraper](https://apify.com/crawloop/amazon-search-scraper) | [eBay Active Listings Scraper](https://apify.com/crawloop/ebay-active-listings-scraper) | [eBay Sold Listings Scraper](https://apify.com/crawloop/ebay-sold-listings-scraper) | Wholesale items, pallet manifests, auctions |

### When to use this Actor

- **Wholesale catalog extraction** — unit prices, MOQ, stock qty, condition codes
- **Pallet / lot sourcing** — boxes, units, price-per-unit, estimated Amazon sell-through, **line-item manifests**
- **Amazon / Walmart comps** — ASIN, BSR, Walmart price/offers alongside wholesale cost
- **Auction watchlists** — auction pages with linked wholesale items
- **Category / brand slices** — filter catalog crawls by category or brand slug

### When not to use this Actor

- **Amazon keyword SERP only** — use [Amazon Search Scraper](https://apify.com/crawloop/amazon-search-scraper)
- **eBay live or sold comps only** — use [eBay Active](https://apify.com/crawloop/ebay-active-listings-scraper) / [eBay Sold](https://apify.com/crawloop/ebay-sold-listings-scraper)
- **Industrial machinery auctions** — use the Used Machinery suite (Troostwijk, Surplex, NetBid)

### Key Features

- **Listings or details** — fast card fields vs deep JSON enrichment
- **Lot manifests** — per-SKU ASIN, UPC, qty, MSRP, unit price, est. Amazon price
- **Lightweight & fast** — `curl_cffi` Chrome TLS impersonation, no browser automation
- **Catalog filters** — category + brand query params; optional client-side keyword filter
- **Sort** — newest, price, discount, quantity, or views (monitor runs stay on newest)
- **Resale margin** — Amazon and Walmart profit per unit and ROI on cost, plus MOQ cost, before marketplace fees and shipping
- **Deal filters** — optional min/max price, discount, and Amazon ROI; non-matching rows are not opened or charged
- **Monitor mode** — schedule a run and save only new, repriced, or restocked rows
- **Start URLs** — mix item, lot, auction, and list pages in one run
- **Proxy-ready** — Apify Residential recommended (US)

### Input Parameters

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `mode` | String | `items` | `items`, `fixed_price_lots`, `auctions`, `start_urls` |
| `scrapeMode` | String | `details` | `listings` (cards) or `details` (JSON + manifests) |
| `startUrls` | Array | `[]` | Item / lot / auction / list URLs (`start_urls` mode) |
| `category` | String | — | Category slug filter |
| `brand` | String | — | Brand slug filter |
| `searchQuery` | String | — | AND keyword filter on title/SKU/ASIN/brand |
| `sort` | String | `date:desc` | Catalog order: Newest, Oldest, Recent price drop, price, discount, quantity, Most viewed |
| `minPrice` | Number | `0` | Minimum unit/lot price in USD (`0` = off) |
| `maxPrice` | Number | `0` | Maximum unit/lot price in USD (`0` = off) |
| `minDiscountPct` | Number | `0` | Minimum `msrpOff` percent (`0` = off) |
| `minProfitPct` | Number | `0` | Minimum Amazon ROI (`azProfitPct`). Rows with no Amazon price are excluded. `0` = off |
| `maxItems` | Integer | `100` | Max dataset rows (`0` = unlimited). Filtered rows do not count. In monitor mode, rows scanned per run |
| `maxPages` | Integer | `0` | Max list pages (`0` = unlimited). With a deal filter and `0`, the scan stops at 20 pages |
| `maxAuctions` | Integer | `0` | Max auction pages in `auctions` mode |
| `concurrency` | Integer | `4` | Parallel detail fetches (1–10) |
| `monitorMode` | Boolean | `false` | Emit only new, repriced, or quantity-changed rows. `maxItems` is the scan window |
| `monitorStateName` | String | — | Optional named key-value store for monitor state |
| `resetMonitorState` | Boolean | `false` | Clear monitor state and seed again |
| `proxyConfiguration` | Object | Residential | Apify Proxy settings |

#### Input Example

```json
{
  "mode": "fixed_price_lots",
  "scrapeMode": "details",
  "maxItems": 20,
  "concurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

```json
{
  "mode": "start_urls",
  "scrapeMode": "details",
  "startUrls": [
    { "url": "https://888lots.com/item/example-slug" },
    { "url": "https://888lots.com/lot/example-lot-slug" },
    { "url": "https://888lots.com/auction/show/37-auction-2026-06-04" }
  ],
  "maxItems": 50
}
```

### Monitor new & repriced deals

Turn on `monitorMode` and schedule the same input every 6 hours. Each run scans one window of the catalog (newest first) and writes only rows that are new or whose wholesale **price** or **quantity** changed. Unchanged rows are not opened in details mode, not saved, and not charged.

`maxItems` is how many matching catalog rows are **scanned**, not how many rows are written. The first run is a seed: it emits the whole window with `changeType: "new"` and stores `price`, `qty`, and timestamps in a named key-value store (never the run's default store). Later runs add `changeType` (`new`, `price_changed`, or `qty_changed`), `previousPrice`, `previousQty`, and `firstSeenAt`.

When `maxItems` is `0`, the window follows `maxPages`. When that is also `0`, the scan stops after 20 pages so a scheduled run cannot walk the full catalog. State keeps keys seen in the last 60 days.

```json
{
  "mode": "items",
  "scrapeMode": "details",
  "monitorMode": true,
  "sort": "date:desc",
  "maxItems": 120,
  "maxPages": 2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### Resale margin

Item and lot rows include `azProfitPerUnit` and `azProfitPct` when both the Amazon price and the wholesale price are greater than zero. `azProfitPct` is ROI on cost: `(Amazon price − price) / price × 100`. Detail rows also include `wmProfitPerUnit` and `wmProfitPct` from the Walmart price. `moqCost` is `price × moq` when MOQ is at least 1. Profit is before marketplace fees and shipping.

Schedule this input every 6 hours when you want a fresh margin sheet for the newest wholesale items.

```json
{
  "mode": "items",
  "scrapeMode": "details",
  "sort": "date:desc",
  "maxItems": 50,
  "maxPages": 1,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### Deal filters

`minPrice`, `maxPrice`, `minDiscountPct`, and `minProfitPct` are optional. `0` or empty turns a filter off. Filters run on the catalog row **before** a detail request and **before** a charge. A row with no Amazon profit is excluded while `minProfitPct` is set. Details mode checks `minProfitPct` again after enrichment; a row that fails is not saved and not charged. Filtered rows do not count toward `maxItems`. If `maxPages` is `0` and any filter is set, the crawl stops after 20 pages.

Schedule this input every 6 hours to keep a filtered deal list current.

```json
{
  "mode": "items",
  "scrapeMode": "listings",
  "minPrice": 15,
  "maxPrice": 200,
  "minDiscountPct": 40,
  "minProfitPct": 25,
  "maxItems": 100,
  "maxPages": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### Output Format

Each dataset row has `type`: `item` | `lot` | `auction`.

**Item (details):** `asin`, `upc`, `price`, `msrp`, `moq`, `qty`, `salesRank`, `azLink`, `wmPrice`, `azProfitPerUnit`, `azProfitPct`, `wmProfitPerUnit`, `wmProfitPct`, `moqCost`, dimensions, `images`, `condition`, `zip`, … Profit is before marketplace fees and shipping.

**Monitor rows** add `changeType`, `previousPrice`, `previousQty`, and `firstSeenAt`.

**Lot (details):** `units`, `boxesCount`, `pricePerUnit`, `estAzSell`, **`manifest`** (array of SKU lines), …

**Auction:** `title`, `itemCount`, `itemUrls` (plus linked item detail rows when `scrapeMode=details`).

#### Output Example (lot)

```json
{
  "type": "lot",
  "id": 52057,
  "title": "Boxes Damaged - 3 Boxes Lot",
  "url": "https://888lots.com/lot/boxes-damaged-3-boxes-lot-52057",
  "price": 189.0,
  "units": 48,
  "boxesCount": 3,
  "pricePerUnit": 3.94,
  "estAzSell": 420.0,
  "manifestCount": 18,
  "manifest": [
    {
      "asin": "B0EXAMPLE",
      "upc": "012345678905",
      "description": "Example SKU",
      "qty": 2,
      "msrp": 29.99,
      "unitPrice": 4.5,
      "estAzPrice": 18.0
    }
  ],
  "scrapedAt": "2026-07-24T12:00:00Z"
}
```

### Typical Workflow

1. Run **listings** mode to discover candidates (category/brand filters).
2. Re-run **details** on interesting lots for full manifests.
3. Join ASINs with [Amazon Search Scraper](https://apify.com/crawloop/amazon-search-scraper) or [eBay Sold Listings Scraper](https://apify.com/crawloop/ebay-sold-listings-scraper) for arbitrage spreadsheets.

### Integration examples

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawloop/888lots-scraper').call({ mode: 'items', scrapeMode: 'listings', maxItems: 20, maxPages: 1 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.slice(0, 5));
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient(token)
run = client.actor("crawloop/888lots-scraper").call(
    run_input={"mode": "items", "scrapeMode": "listings", "maxItems": 20, "maxPages": 1}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("title"), item.get("asin"), item.get("price"))
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/crawloop~888lots-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"items","scrapeMode":"listings","maxItems":20,"maxPages":1}'
```

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp). Connect your Apify account, then call `crawloop/888lots-scraper`.

Example prompts:

- "Run 888lots Scraper in items listings mode, max 20, return title, asin, price, msrp"
- "Scrape 888lots pallet lots with manifests and summarize ASIN coverage"
- "Chain 888lots then Amazon Search Scraper to validate ASIN SERP prices"

### Suite next step

Validate ASINs with [Amazon Search Scraper](https://apify.com/crawloop/amazon-search-scraper). For ZIP-local Walmart comps, use [Walmart Scraper](https://apify.com/crawloop/walmart-scraper). For sold comps, use [eBay Sold Listings Scraper](https://apify.com/crawloop/ebay-sold-listings-scraper).

### Related Actors

| Actor | Use case |
| :--- | :--- |
| [Amazon Search Scraper](https://apify.com/crawloop/amazon-search-scraper) | Amazon SERP / ASIN discovery |
| [Walmart Scraper](https://apify.com/crawloop/walmart-scraper) | ZIP-local Walmart prices and stock |
| [eBay Active Listings Scraper](https://apify.com/crawloop/ebay-active-listings-scraper) | Live eBay comps |
| [eBay Sold Listings Scraper](https://apify.com/crawloop/ebay-sold-listings-scraper) | Sold price comps |

# Actor input Schema

## `mode` (type: `string`):

What to scrape: wholesale items catalog, fixed-price lots/pallets, auctions, or specific start URLs.

## `scrapeMode` (type: `string`):

listings — fast card-level fields from catalog HTML. details — full /json payloads including Amazon/Walmart metadata and lot manifests.

## `startUrls` (type: `array`):

Used when mode is start_urls. Accepts item, lot, auction show, or catalog list URLs.

## `category` (type: `string`):

Optional category filter slug for catalog modes, e.g. clothing-fashion-and-accessories or mobile-devices.

## `brand` (type: `string`):

Optional brand filter slug for catalog modes, e.g. apple or nike.

## `searchQuery` (type: `string`):

Client-side keyword filter over title/SKU/ASIN/brand (AND tokens). Applied after each list page is fetched.

## `sort` (type: `string`):

Catalog order for item and fixed-price lot lists. Start URLs that already include a sort parameter are left unchanged. Monitor mode always uses Newest (date:desc).

## `minPrice` (type: `number`):

Minimum wholesale unit or lot price. 0 or empty turns the filter off. Rows below the minimum are not saved, not charged, and are not opened in details mode. Filtered rows do not count toward Max Total Items.

## `maxPrice` (type: `number`):

Maximum wholesale unit or lot price. 0 or empty turns the filter off. Rows above the maximum are not saved or charged.

## `minDiscountPct` (type: `number`):

Minimum discount versus MSRP (msrpOff). 0 or empty turns the filter off. Rows with no discount value are excluded while this is set.

## `minProfitPct` (type: `number`):

Minimum Amazon ROI on cost, (Amazon price − price) / price × 100. 0 or empty turns the filter off. Rows with no positive Amazon price are excluded. Details mode checks again after enrichment and does not save or charge a row that fails. Profit is before marketplace fees and shipping.

## `maxItems` (type: `integer`):

Maximum dataset rows to output. 0 = unlimited. Rows rejected by deal filters do not count. In monitor mode this is how many matching catalog rows to scan each run (the watch window), not how many rows are written. Unchanged rows count toward the window. When monitor mode is on and this is 0, the scan uses Max List Pages, or 20 pages when that is also 0.

## `maxPages` (type: `integer`):

Maximum catalog pages to crawl (60 items/page typical). 0 = unlimited. If this is 0 and any deal filter is set, the run stops after 20 pages so a tight filter cannot walk the full catalog.

## `maxAuctions` (type: `integer`):

Maximum auction show pages to process in auctions mode. 0 = unlimited.

## `concurrency` (type: `integer`):

Parallel detail /json fetches.

## `monitorMode` (type: `boolean`):

Save only new listings, price changes, and quantity changes versus the last run with the same filters. Comparison uses the catalog row, so unchanged rows are not opened, saved, or charged. maxItems is the number of matching rows scanned each run (the same watch window as the first seed run), not the number of rows written. If maxItems is 0, the scan follows maxPages, or 20 pages when maxPages is also 0. Sort is forced to Newest. Schedule the same input every 6 hours. The first run seeds state and emits the full window.

## `monitorStateName` (type: `string`):

Optional name of the key-value store that keeps monitor state between runs. Leave empty to derive a name from mode, output detail level, category, brand, search, sort, filters, and start URLs. Listings and details monitors use separate stores. State is never written to the default store.

## `resetMonitorState` (type: `boolean`):

Clear saved monitor state for this input and treat the run as a new seed.

## `proxyConfiguration` (type: `object`):

Apify proxy configuration. Residential US proxies recommended.

## Actor input object example

```json
{
  "mode": "items",
  "scrapeMode": "details",
  "startUrls": [],
  "category": "",
  "brand": "",
  "searchQuery": "",
  "sort": "date:desc",
  "minPrice": 0,
  "maxPrice": 0,
  "minDiscountPct": 0,
  "minProfitPct": 0,
  "maxItems": 100,
  "maxPages": 0,
  "maxAuctions": 0,
  "concurrency": 4,
  "monitorMode": false,
  "resetMonitorState": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Default dataset items (type: item | lot | auction).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/888lots-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/888lots-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call crawloop/888lots-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawloop/888lots-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/W95o1lem9QDfV6V3H/builds/wsiuPlWxLfCF9aOgW/openapi.json
