# Whatnot Scraper - Live Shows, Lots & Sellers (`abotapi/whatnot-scraper`) Actor

Scrape Whatnot live and upcoming shows, queued items and lots, and seller profiles. Search by keyword or URL, then filter by category, format, seller rating, and country. Extract ratings, followers, sold counts, and more.

- **URL**: https://apify.com/abotapi/whatnot-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Whatnot Live Shopping Scraper

Whatnot is the largest live-shopping marketplace for collectibles: trading cards, sports cards, sneakers, comics, coins, toys and more. Sellers run scheduled live shows and auction or sell items inside them.

This actor turns that into structured data. It returns **live shows** (playing now and scheduled for later), the **items and lots** sellers have listed, and **seller profiles**, with the site's own category, format, seller-rating and country filters, plus resume and incremental change tracking for scheduled runs.

### What is not available, stated up front

**Realised (sold) prices for finished shows are not published by the site, so this actor does not return them.** This is measured, not assumed:

- The site's own filter for a show's time-of-show offers exactly two values, "Playing now" and "Scheduled". There is no ended or completed value, so finished shows are not in the public index at all.
- A show carries no items connection, so there is no path from a show to what it sold.
- A seller's own show list returns only future shows.
- The catalogue product type declares a last-sale price field, and it came back empty on every one of 24 distinct products sampled.

If you need realised auction prices, this actor cannot give them to you and neither can any other public read of this site. What it does give you is the **pre-sale picture**: which shows are running and scheduled, who is running them, how big their audience is, and exactly which lots are queued into which upcoming show at what starting price. That is the data you use to decide what to watch, what to bid on, and which sellers to track.

### What you get

**Live shows** - title, description, status (playing now or scheduled), start time, current viewer count, watchlist size, categories, tags, free-shipping policy, the maximum shipping the buyer pays, thumbnail, trailer, and the full seller block.

**Items and lots** - title, subtitle, description, price and currency, buying format (Buy It Now or live auction), current bid and bid count, quantity, listing status, photos, condition-bearing category, catalogue product and its price range, break details (format, total spots, spots filled, spots sold), variants, listing and update timestamps, and **the start time of the show the lot is queued into**.

**Sellers** - username, display name, bio, rating and review count, followers, following, items sold, average shipping days, verified flag, Premier Shop flag, live flag, store banner, and optionally their most recent reviews with rating, text, seller reply and date.

Every show and every item also carries its seller's username, rating, review count, follower count, sold count, verified flag and Premier Shop flag, so you can rank by seller quality without turning anything extra on.

### Modes

**Search** - one or more keywords. Pick what each search returns with Result type: live shows, items and lots, sellers, or the platform's own mixed feed. Each keyword gets its own share of the result cap, so one popular keyword cannot swallow the run.

**URL** - paste links and each is routed automatically:

| Link | What you get |
|---|---|
| `whatnot.com/live/<id>` | that one show |
| `whatnot.com/listing/<id>` | that one item |
| `whatnot.com/user/<username>` | the seller, plus their scheduled shows and their shop |
| `whatnot.com/tag/<category>` | shows in that category |
| `whatnot.com/search?query=...` | that search |

A locale prefix such as `/en-GB/` is accepted. A link that is not one of these is reported and skipped rather than guessed at.

### Filters

Categories, show status, show format, buying format, condition, graded only, autographed only, minimum seller rating, Premier Shop only, seller country, and a price range. They apply in both search mode and URL mode.

Two honest notes:

- **Categories are checked against the site's own live category list** at the start of the run. A handle that does not exist stops the run and names the closest matches, instead of quietly returning everything. The site's category vocabulary is large and changes, so this is a free-text field rather than a frozen dropdown that would go stale.
- **The price range is applied by this actor, not sent upstream.** The site accepts a price filter and then returns items below the floor anyway, in every encoding its own field name suggests. Rather than ship a control that silently does nothing, the bound is enforced here against each record's own reported price, before any extra request is made for that record, so a row you do not receive never costs you anything.

### Resume and recurring updates

**Resume from a previous run** continues one interrupted crawl from a run or dataset id, without returning or charging for what that run already collected.

**Incremental mode** is for scheduled monitoring. The first run returns everything as `NEW`; later runs return only `NEW`, `UPDATED` and `REAPPEARED`, so you see a newly scheduled show, a show going live, a price change or a fresh lot in a category you watch. Optionally also `UNCHANGED` and `EXPIRED` rows, both off by default because they return and bill extra rows.

Audience counters and seller follower counts are deliberately ignored when deciding what changed. They drift constantly, and counting them would mark every result changed on every run and bill the whole feed daily for nothing.

`EXPIRED` is only produced after a run has fully scanned the tracked search. A run stopped by the result cap, a resumed run, or a run that scanned nothing never marks anything expired.

### Cost

You are charged for each result returned, plus a start charge per run. Reading each seller's full profile is opt-in and adds a small surcharge on each result that comes back carrying those extra fields, disclosed in the section caption above the toggle. Several results from the same seller share one profile read, so a run focused on a few sellers costs very little extra.

Leave the default connection selected. The other connection options are billed by traffic and cost far more.

### Send results into your apps (MCP connectors)

Optionally pipe results straight into the tools you already use, over Model Context Protocol. Authorize a connector under Apify, Settings, API and Integrations, then select it in `mcpConnectors`. Notion gets a rich page per result and needs `notionParentPageUrl`; the other connectors get a best-effort write or a digest. `maxNotifyListings` caps how many results are written per connector per run.

This never changes the dataset. Leave `mcpConnectors` empty to skip it entirely.

### Output

Four dataset views: **Results** (everything), **Live shows**, **Items and lots** and **Sellers**. One example row, with placeholder values:

```json
{
  "recordType": "show",
  "showId": "00000000-0000-0000-0000-000000000000",
  "url": "https://www.whatnot.com/live/00000000-0000-0000-0000-000000000000",
  "title": "Vintage slab breaks, $1 starts",
  "status": "PLAYING",
  "isLiveNow": true,
  "startTime": "2026-09-05T00:43:25Z",
  "activeViewers": 339,
  "watchlistUsers": 113,
  "categories": ["Pokemon Cards"],
  "categorySlugs": ["pokemon_cards"],
  "tags": ["$1 Starts", "Vintage", "Graded Cards"],
  "sellerUsername": "example_seller",
  "sellerUrl": "https://www.whatnot.com/user/example_seller",
  "sellerRating": 4.9,
  "sellerReviewCount": 24451,
  "sellerFollowerCount": 180746,
  "sellerSoldCount": 160261,
  "sellerIsPremierShop": false,
  "scrapedAt": "2026-09-05T10:11:07Z"
}
```

Prices are returned in major units (dollars, not cents) and timestamps in UTC ISO-8601, on every record kind.

### Reliability

Requests stop after five attempts rather than grinding, and a run that returns no rows tells you **which** of three different things happened, because each one has a different answer:

| What happened | How the run ends | What to do |
|---|---|---|
| Nothing matched your search | **Succeeds**, with "No results matched" | Widen the keyword or relax the filters |
| Nothing could be read | **Fails** | Enable Apify Proxy, or try again later |
| The site changed its data format | **Fails**, naming that cause | Report the run; no keyword, filter or proxy change will help |

A run that could read nothing never reports itself as an empty search, and a page that comes back in an unexpected shape is counted as a refused read rather than as the end of the results. If seller enrichment starts failing systematically it is switched off for the rest of the run, and the results you still get are not charged the surcharge.

# Actor input Schema

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

Choose 'search' for keyword search across live shows, items or sellers, or 'url' to scrape pasted links.

## `resultType` (type: `string`):

What each search returns. 'Live shows' returns shows playing now and shows scheduled for later, with seller, category, tags, start time and audience size. 'Items and lots' returns the individual items sellers have listed, including the ones queued into an upcoming show. 'Sellers' returns seller profiles. 'Mixed' uses the platform's own blended ranking and returns all three kinds in one feed. In URL mode this only decides what a pasted SEARCH link returns; a pasted show, item or seller link always returns its own kind.

## `queries` (type: `array`):

One or more keywords. Examples: 'charizard', 'psa 10 rookie', 'vintage lego', 'jordan 1'. Each keyword gets its own share of Max results, so one popular keyword cannot swallow the whole run.

## `urls` (type: `array`):

Mix freely: show links (whatnot.com/live/<id>), item links (whatnot.com/listing/<id>), seller links (whatnot.com/user/<username>, which returns the seller plus their scheduled shows and their shop), category links (whatnot.com/tag/<category>) or search links (whatnot.com/search?query=...). A locale prefix such as /en-GB/ is accepted.

## `categories` (type: `array`):

Only return results in these categories, given as the category handle in its address, for example 'pokemon\_cards' from whatnot.com/tag/pokemon\_cards. Try 'sports\_cards', 'sneakers\_streetwear', 'comics', 'coins\_and\_money', 'toys' or 'video\_games\_and\_movies'. The list is checked against the site's own category list at the start of the run, so a handle that does not exist stops the run and names the closest matches instead of quietly returning everything.

## `showStatus` (type: `array`):

Only return shows in these states. 'Playing now' is a show streaming at this moment; 'Scheduled' is a show announced for later. Applies when Result type is 'Live shows' or 'Mixed'. Note that ENDED shows are not published by the site at all and cannot be returned by any value here.

## `showFormat` (type: `array`):

Only return shows the seller runs in these formats. Applies when Result type is 'Live shows' or 'Mixed'.

## `buyingFormat` (type: `array`):

Only return items sold this way. 'Buy It Now' is a fixed price; 'Live auction' is a lot that will be auctioned during a show. Applies when Result type is 'Items and lots' or 'Mixed'.

## `conditions` (type: `array`):

Only return items the seller marked with these conditions, for example 'Near Mint', 'Graded', 'Brand New', 'Used' or 'Light Played'. The site publishes a long, category-specific condition vocabulary, so this is free text rather than a fixed list. A value the site does not use returns no results rather than everything.

## `gradedOnly` (type: `boolean`):

Only return items the seller has marked as professionally graded. Applies when Result type is 'Items and lots' or 'Mixed'.

## `autographedOnly` (type: `boolean`):

Only return items the seller has marked as autographed. Applies when Result type is 'Items and lots' or 'Mixed'.

## `minSellerRating` (type: `string`):

Only return results from sellers rated at or above this score out of 5.

## `premierShopOnly` (type: `boolean`):

Only return results from sellers the platform has marked as Premier Shops.

## `sellerCountries` (type: `array`):

Only return results from sellers in these countries.

## `minPrice` (type: `integer`):

Only return items priced at or above this amount, in the currency the item is listed in. Applied by this actor to each record's own reported price, not sent upstream: the site accepts a price filter and then returns items below the floor anyway (measured, in every encoding its own field name suggests), so the bound is kept here where it can actually be honoured. Records with no price of their own, such as seller profiles, are never dropped by a price bound.

## `maxPrice` (type: `integer`):

Only return items priced at or below this amount, in the currency the item is listed in. Applied by this actor to each record's own reported price, for the same reason as the minimum above.

## `sortBy` (type: `string`):

Ordering asked of the site. The valid values differ by Result type, because the site offers different orderings for shows and for items: shows accept 'recommended', 'viewers-desc' and 'viewers-asc'; items and sellers accept 'best-match', 'price-asc', 'price-desc' and 'newest'. A value that does not belong to the current Result type stops the run rather than silently returning the default order.

## `fetchSellerDetails` (type: `boolean`):

Adds the seller's display name, bio, following count, average shipping days, store banner and, optionally, their recent reviews to every result. Off by default because every result already carries the seller's username, rating, review count, follower count, sold count, verified flag and Premier Shop flag. Profiles are cached within a run, so ten shows from one seller cost one extra request.

## `maxSellerReviews` (type: `integer`):

How many of each seller's most recent reviews to attach, when 'Read each seller's full profile' is on. Set 0 to attach none and skip the extra request. Reviews carry the rating, the text, the seller's reply and the date.

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

Maximum number of results returned across the whole run. This is the run's cap. Use 0 for unlimited.

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

Maximum result pages walked per keyword or link, at 24 results a page. 0 means no page limit: the run then stops only at Max results, or when the site runs out of results.

## `resumeFromRunId` (type: `string`):

Paste a previous run id or dataset id to continue a large crawl without returning, or charging for, results already collected there. Use this after an interrupted run. For recurring daily monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns everything matching as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED results, which is how you catch a newly scheduled show, a show going live, a price change or a fresh lot in a category you watch. Audience counters and seller follower counts are deliberately ignored when deciding what changed, because they drift constantly and would otherwise mark every result as changed on every run. State is kept separately for each mode, result type, keyword set and filter setup, so two different searches never mix.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to let the actor derive a key from the mode, result type, keywords, links and filters.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return results that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return results that were present in a previous run but are no longer found, marked EXPIRED, which is how a show finishing or a lot selling shows up. Only produced once a run has fully scanned the tracked search, never when Max results capped it or Resume was used. This returns, and bills, extra rows.

## `proxy` (type: `object`):

Apify Proxy is recommended. Leave the default selected unless a run reports that requests were refused.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API and Integrations, then select it here. Notion gets a rich page per item; other connectors get a best-effort write or digest. Leave empty to skip; this never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "resultType": "shows",
  "queries": [
    "charizard"
  ],
  "urls": [
    "https://www.whatnot.com/tag/pokemon_cards",
    "https://www.whatnot.com/user/spacenarwhalz"
  ],
  "categories": [
    "pokemon_cards"
  ],
  "gradedOnly": false,
  "autographedOnly": false,
  "minSellerRating": "any",
  "premierShopOnly": false,
  "fetchSellerDetails": false,
  "maxSellerReviews": 20,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true
  },
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `shows` (type: `string`):

No description

## `lots` (type: `string`):

No description

## `sellers` (type: `string`):

No description

# 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 = {
    "mode": "search",
    "resultType": "shows",
    "queries": [
        "charizard"
    ],
    "urls": [
        "https://www.whatnot.com/tag/pokemon_cards",
        "https://www.whatnot.com/user/spacenarwhalz"
    ],
    "categories": [
        "pokemon_cards"
    ],
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/whatnot-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 = {
    "mode": "search",
    "resultType": "shows",
    "queries": ["charizard"],
    "urls": [
        "https://www.whatnot.com/tag/pokemon_cards",
        "https://www.whatnot.com/user/spacenarwhalz",
    ],
    "categories": ["pokemon_cards"],
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/whatnot-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 '{
  "mode": "search",
  "resultType": "shows",
  "queries": [
    "charizard"
  ],
  "urls": [
    "https://www.whatnot.com/tag/pokemon_cards",
    "https://www.whatnot.com/user/spacenarwhalz"
  ],
  "categories": [
    "pokemon_cards"
  ],
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call abotapi/whatnot-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/whatnot-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/VkVPXRYJtwaSMJoPY/builds/qNSG8FwFtGdBQIeua/openapi.json
