# 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
- **Features:** Limited permissions
- **Stats:** 4 total users, 1 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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?

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

## Whatnot Scraper: Live Shows, Items & Seller Data

Whatnot is the largest live-shopping marketplace for collectibles: trading cards, sports cards, sneakers, comics, coins and toys, sold by sellers running scheduled live shows. This actor turns that into structured data: live shows playing now and scheduled for later, the items and lots sellers have listed (including the ones queued into an upcoming show), and seller profiles with ratings, followers and sold counts. Search by keyword or paste links, filter by category, format and seller quality, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.

### Why This Scraper?

- **Two ways in.** Search by keyword, or paste a show, item, seller, category or search link and it is routed automatically to the right walk.
- **Pre-sale detail on every item.** Price, buying format, stock, condition and, for items queued into an upcoming show, the start time of that show, so you know what is coming before it sells.
- **Seller quality on every row.** Username, rating, review count, followers, sold count, verified and Premier Shop flags travel with every show and item, not just seller profiles, so you can rank by seller quality without an extra read.
- **The site's own filters, all in one run.** Category, show status and format, buying format, condition, graded and autographed only, minimum seller rating, Premier Shop only, seller country and a price range.
- **Filters that actually work.** Category handles are checked against the site's live category list before the run starts, and the price range is enforced here because the site's own price filter silently returns items below the floor anyway.
- **Built for monitoring.** Incremental mode returns only new and changed results on a recurring schedule, and Resume continues one interrupted run without paying for what it already collected.
- **Honest about a real limit.** Realised (sold) prices for finished shows are not published anywhere on the site, so this actor does not invent them, and a run that could not read the site fails loudly instead of returning an empty dataset.

### Use Cases

- **Collectors and resellers:** track a category or seller for newly scheduled shows, fresh stock and price changes before a show starts.
- **Sourcing and arbitrage:** watch Buy It Now listings for a card, shoe or set across many sellers, filtered by condition and price range.
- **Seller research and scouting:** rank sellers by rating, followers, items sold and Premier Shop status before deciding who to watch or buy from.
- **Market monitoring:** run a scheduled incremental scan of a category to see new supply and pricing show up over time, without re-downloading what you already have.
- **Community and fan tools:** build a dashboard of live and upcoming shows in a category with viewer counts, start times and seller info.

### Data You Get

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

| Field | Example |
| --- | --- |
| `recordType` | `"show"` (also `"lot"`, `"seller"`, `"category"`, `"rankedSeller"`) |
| `title` | `"Sample vintage card break night"` |
| `url` | Whatnot link to the show, item or seller |
| `status` | `"PLAYING"` (also `"CREATED"`) |
| `startTime` / `endTime` | show start and end time, UTC ISO 8601 |
| `activeViewers` / `watchlistUsers` | live viewer count and watchlist size (shows) |
| `price` / `currency` | listed price and its currency, in major units (items) |
| `transactionType` | `"BUY_IT_NOW"` (also `"LIVESTREAM_AUCTION"`) |
| `currentBid` / `currentBidCount` | live auction state (items) |
| `listingStatus` | `"ACTIVE"` (items) |
| `categories` / `categoryLabel` | category names on a show or item |
| `tags` | show tags, for example `"Vintage"`, `"Graded Cards"` |
| `scheduledShowStartTime` | the start time of the show a lot is queued into |
| `sellerUsername` / `sellerUrl` | the seller behind every show, item and profile |
| `sellerRating` / `sellerReviewCount` | seller rating out of 5 and review count |
| `sellerFollowerCount` / `sellerSoldCount` | seller audience size and lifetime sales |
| `sellerIsVerified` / `sellerIsPremierShop` | verified and Premier Shop flags |
| `changeType` / `changedFields` | `NEW`, `UPDATED`, `UNCHANGED`, `REAPPEARED` or `EXPIRED` (incremental mode) |
| `firstSeenAt` / `lastSeenAt` | first and most recent time this result was seen (incremental mode) |
| `rank` / `categoryView` | position in the category list or trending ranking (category rows) |
| `viewerCount` / `livestreamCount` / `deeplink` | live viewers, live shows and site path of a category (category rows) |
| `rank` / `interval` / `rankingType` | position, window (`CURRENT_DAY`, `CURRENT_WEEK`, `LIVE`) and kind of a seller ranking (ranked seller rows) |
| `categoryId` / `categoryLabel` | the category a ranking belongs to, with its display label from the site's category list (ranked seller rows) |
| `currentActiveLivestream` | the show a ranked seller is streaming right now, when any |
| `scrapedAt` | when this row was read, UTC ISO 8601 |

Item and lot records also carry the subtitle, description, quantity, image URLs, break details (format, total spots, spots filled, spots sold), variants and a catalogue product match with its price range. Seller records also carry the display name, bio, following count, average shipping days, store banner, live and can-go-live flags, and, with "Read each seller's full profile" on, their most recent reviews (rating, text, the seller's reply and the date).

**Output views.** The dataset has eight views: Results (everything), Live shows, Items and lots, Sellers, Categories, Seller leaderboards, Seller reviews (one row per attached review) and Changes (incremental mode: new, updated, reappeared and expired rows). Each run also stores a run summary under the `OUTPUT` key of the key-value store, counting rows by record type.

### How to Use

1. Pick a **mode**: `search` (by keyword), `url` (paste links), `seller` (usernames), `categories` (category list and trending) or `leaderboard` (seller rankings per category).
2. In search mode, add one or more keywords and a **Result type** (live shows, items and lots, sellers, or the platform's mixed feed). In URL mode, paste show, item, seller, category or search links (see the link table below).
3. Narrow with the filters that apply to your Result type: category, show status and format, buying format, condition, graded or autographed only, minimum seller rating, Premier Shop only, seller country, and a price range.
4. Set **Max results** to control run size and cost, then click **Start**.

#### Link shapes in URL mode

Left untouched, the **Whatnot links** field scrapes one example of each of the shapes below, so a URL-mode run with the field unchanged returns a sample of every kind of record: **Max results** is shared fairly across the links (each link gets its share of what is left, a link pasted twice is read once), so the first large link cannot use up the whole cap. Clear the list or paste your own links to scrape only those.

| Link shape | Example | Returns |
|---|---|---|
| Category page | `whatnot.com/tag/pokemon_cards` | Shows in that category |
| Legacy category page | `whatnot.com/category/pokemon_cards` | Same as the category page |
| Locale-prefixed category | `whatnot.com/en-GB/tag/pokemon_cards` | Same as the category page |
| Host without www | `whatnot.com/tag/pokemon_cards` | Same as the category page |
| Seller profile | `whatnot.com/user/spacenarwhalz` | The seller, their scheduled shows and their shop |
| Seller shop | `whatnot.com/user/spacenarwhalz/shop` | Only that seller's shop lots |
| Seller reviews | `whatnot.com/user/spacenarwhalz/reviews` | The seller row with their recent reviews attached |
| Keyword search | `whatnot.com/search?query=charizard` | Search results; `type=shows`, `type=items` or `type=sellers` picks the result kind. Other filters in the link are not applied: the run logs a warning and you use the Filters inputs |
| Live show | `whatnot.com/live/<show id>` | That one show |
| Item | `whatnot.com/listing/<item id>` | That one item |

Category names such as "Pokemon Cards" are accepted wherever a category is asked for and are matched against the site's live category list; a name that matches nothing stops the run and lists the closest matches.

**Search for items by keyword:**

```json
{
  "mode": "search",
  "queries": ["charizard"],
  "resultType": "lots",
  "maxItems": 20
}
```

**Every live show in a category right now:**

```json
{
  "mode": "search",
  "resultType": "shows",
  "categories": ["pokemon_cards"],
  "showStatus": ["PLAYING"],
  "maxItems": 20
}
```

**Filtered Buy It Now items in a price range, from well-rated sellers:**

```json
{
  "mode": "search",
  "queries": ["vintage lego"],
  "resultType": "lots",
  "buyingFormat": ["BUY_IT_NOW"],
  "minSellerRating": "4.5",
  "minPrice": 10,
  "maxPrice": 200,
  "maxItems": 50
}
```

**Paste links (category and search):**

```json
{
  "mode": "url",
  "urls": [
    "https://www.whatnot.com/tag/pokemon_cards",
    "https://www.whatnot.com/search?query=charizard"
  ]
}
```

A seller link (`whatnot.com/user/<username>`) returns that seller's profile plus their scheduled shows and their shop.

#### Categories and seller leaderboards

- **Categories** (`mode` = `categories`): `categoryView` `list` returns the site's top-level categories in the site's own order; `trending` returns every category that has viewers right now, ranked by live viewer count (50 rows when Max results is unset). Each row has the live viewer count, the live show count, the site path and an image. The site does not publish a sub-category tree to anonymous visitors (no tag has a parent), so sub-category listings are not available; a category's shows are still reachable with a `/tag/<category>` link.
- **Seller leaderboards** (`mode` = `leaderboard`): the overall seller ranking inside each category you list in **Categories** (none listed means every top-level category), for the interval you pick: today, this week, live right now, or all three. Each row has the rank, the interval, the seller and the show they are streaming now. Rankings are regional: the country of the proxy exit changes who is listed, so keep the proxy country fixed between scheduled runs if you compare them. Max results is shared across the categories and intervals.

Category and ranked seller rows are returned results like any other row, and incremental mode works on them (a ranked seller is tracked per category, interval and seller).

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/whatnot-scraper").call(run_input={"mode": "search", "queries": ["charizard"], "resultType": "lots"})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["price"], item["currency"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/whatnot-scraper').call({ mode: 'search', queries: ['charizard'], resultType: 'lots' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

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

#### Max results and page limits

**Max results** (`maxItems`) is the run's overall cap; `0` means no limit. In search mode, each keyword gets its own share of the cap, so one popular keyword cannot swallow the whole run. **Max pages per keyword or link** (`maxPages`) bounds how many result pages (24 results each) a single keyword or link is walked before moving on; `0` means no page limit, so the run stops only at Max results or when the site runs out of results.

#### Resume and recurring updates

- **Resume from a previous run** (`resumeFromRunId`) continues one interrupted run: paste its run or dataset id and this actor skips everything already collected there, so you don't pay twice.
- **Incremental mode** (`incrementalMode`) is for scheduled monitoring of the same search. The first run returns everything as `NEW`. Later runs return only `NEW`, `UPDATED` and `REAPPEARED` by default, so you catch a newly scheduled show, a show going live, a price change or a fresh lot in a category you watch. Audience counters (viewers, watchlist, followers, sold count, reviews; for category rows the live viewer and show counts, for seller leaderboard rows the viewers of the show the seller is streaming) are deliberately ignored when deciding what changed, because they drift constantly; they stay in the output, only the comparison skips them. The `rank` of category and leaderboard rows is ignored too, since a position only moves when those counters do; a seller entering or leaving a leaderboard still shows up as a `NEW` or `EXPIRED` row. A result is `UPDATED` when any other field changes (status, start time, price, listing status, current bid and bid count, title, variant quantity). `ignoreFieldsForChanges` lets you exclude more fields from that comparison, as a top-level name or a nested path such as `sellerReviews[].text`. `stateKey` names or shares the stored state; leave it empty and the actor derives one from the mode, Result type, keywords, links and filters, so two different searches never mix by default. `emitUnchanged` and `emitExpired` also return (and bill) unchanged and expired rows; `EXPIRED` is only produced once a run has fully scanned the tracked search, never after a capped, resumed or empty run.

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

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step **after** the scrape: the Apify dataset is never changed.

1. Authorize a connector once under **Apify → Settings → Integrations** (Notion, Linear, Airtable, or Apify).
2. Select it in the **"Pipe results into your apps"** input field (`mcpConnectors`). Notion gets a rich page per result and needs `notionParentPageUrl` set to the page items should be created under; the other connectors get a best-effort write or digest.
3. `maxNotifyListings` caps how many results are written to each connector per run.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave `mcpConnectors` empty to skip it entirely.

### Input Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | string | `search` | `search` (keyword search), `url` (scrape pasted links), `seller` (read sellers by username), `categories` (category list or trending) or `leaderboard` (seller rankings per category). |
| `resultType` | string | `shows` | What a search (or a pasted search/category link) returns: `shows`, `lots`, `sellers`, or `mixed`. A pasted show, item or seller link always returns its own kind. |
| `queries` | array | `["charizard"]` | Search keywords (search mode). Each keyword gets its own share of Max results. |
| `urls` | array | one example of each link shape | Whatnot links to scrape (url mode): show, item, seller (profile, shop or reviews), category or search links. |
| `sellers` | array | (none) | Seller mode: usernames (a leading @ or a pasted profile link works). Each returns the profile row, scheduled shows and shop items. At least one valid username is required, otherwise the run stops before reading anything; an invalid entry is skipped with a warning naming it. |
| `shopQuery` | string | (none) | Narrows each seller's shop items to titles matching this text (seller mode and pasted seller links). |
| `categories` | array | (none) | Only return results in these categories, by name or handle (prefilled with `pokemon_cards` in the Console). Checked against the site's live category list at the start of the run. |
| `showStatus` | array | (none) | Only return shows in these states: `PLAYING` or `CREATED`. Applies to Result type `shows` or `mixed`. |
| `showFormat` | array | (none) | Only return shows run in these formats (auction, breaks, buy it now, graded, singles, surprise sets). Applies to Result type `shows` or `mixed`. |
| `buyingFormat` | array | (none) | Only return items sold this way: `BUY_IT_NOW` or `LIVESTREAM_AUCTION`. Applies to Result type `lots` or `mixed`. |
| `conditions` | array | (none) | Only return items marked with these free-text conditions, for example "Near Mint" or "Graded". |
| `gradedOnly` | boolean | `false` | Only return items marked as professionally graded. |
| `autographedOnly` | boolean | `false` | Only return items marked as autographed. |
| `minSellerRating` | string | `any` | Minimum seller rating: `any`, `4.0`, `4.5`, or `5.0`. |
| `premierShopOnly` | boolean | `false` | Only return results from sellers marked as Premier Shops. |
| `sellerCountries` | array | (none) | Only return results from sellers in these countries. |
| `minPrice` | integer | (none) | Only return items priced at or above this amount. Enforced by this actor on each record's own price. |
| `maxPrice` | integer | (none) | Only return items priced at or below this amount. Enforced by this actor on each record's own price. |
| `sortBy` | string | (none) | Ordering asked of the site: `recommended`, `viewers-desc`, `viewers-asc` for shows; `best-match`, `price-asc`, `price-desc`, `newest` for items and sellers. |
| `fetchSellerDetails` | boolean | `false` | Read each seller's full public profile and attach it to every result (adds the Seller profile attached event for each result that carries it; cached within a run). |
| `categoryView` | string | `list` | Categories mode: `list` (top-level categories) or `trending` (ranked by live viewers). |
| `leaderboardInterval` | string | `CURRENT_WEEK` | Leaderboard mode: `CURRENT_WEEK`, `CURRENT_DAY`, `LIVE` or `ALL`. |
| `maxSellerReviews` | integer | `20` | How many of each seller's most recent reviews to attach, when `fetchSellerDetails` is on or a seller link is pasted. `0` attaches none everywhere, including on a pasted `/user/<name>/reviews` link (that link then returns the seller row without reviews). Maximum 50. Each review carries its overall rating plus shipping, packaging and accuracy sub-scores. |
| `maxItems` | integer | `20` | Maximum number of results returned across the whole run. `0` for unlimited. |
| `maxPages` | integer | `0` | Maximum result pages walked per keyword or link, at 24 results a page. `0` for no page limit. |
| `resumeFromRunId` | string | (none) | Continue one interrupted run from a previous run or dataset id, without re-collecting what it already gathered. |
| `incrementalMode` | boolean | `false` | Return only new and changed results on scheduled runs against the same search. |
| `ignoreFieldsForChanges` | array | `[]` | Field names (or nested paths like `variants.quantity`) to leave out when deciding whether a result changed. Incremental mode only. |
| `stateKey` | string | (none) | Name or share an incremental-mode state. Leave empty to derive one from the search scope. |
| `emitUnchanged` | boolean | `false` | Also return (and bill) results unchanged since the last run, marked `UNCHANGED`. |
| `emitExpired` | boolean | `false` | Also return (and bill) results no longer found after a complete scan, marked `EXPIRED`. |
| `proxy` | object | Apify Proxy | Connection settings. |
| `mcpConnectors` | array | (none) | Optional: send results to apps you authorized under Integrations. |
| `notionParentPageUrl` | string | (none) | Notion connector only: page under which result pages are created. |
| `maxNotifyListings` | integer | `50` | Cap on results written to each connector per run. |

### Output Example

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

```json
{
  "recordType": "show",
  "id": "00000000-0000-0000-0000-000000000000",
  "showId": "00000000-0000-0000-0000-000000000000",
  "url": "https://www.whatnot.com/live/00000000-0000-0000-0000-000000000000",
  "title": "Sample vintage card break night",
  "description": "Mixed vintage breaks, sample spots to start.",
  "status": "PLAYING",
  "isLiveNow": true,
  "isScheduled": false,
  "startTime": "2026-01-01T18:00:00Z",
  "endTime": null,
  "activeViewers": 250,
  "watchlistUsers": 80,
  "categories": ["Sample Category"],
  "categorySlugs": ["sample_category"],
  "tags": ["Sample Tag"],
  "isFreeShippingEnabled": true,
  "buyerMaxShippingCost": 5.0,
  "currency": "USD",
  "thumbnailUrl": "https://images.whatnot.com/sample-thumbnail.jpg",
  "sellerUsername": "example_seller",
  "sellerUrl": "https://www.whatnot.com/user/example_seller",
  "sellerRating": 4.8,
  "sellerReviewCount": 500,
  "sellerFollowerCount": 10000,
  "sellerSoldCount": 8000,
  "sellerIsVerified": true,
  "sellerIsPremierShop": false,
  "changeType": "NEW",
  "changedFields": [],
  "firstSeenAt": "2026-01-01T18:00:00Z",
  "lastSeenAt": "2026-01-01T18:00:00Z",
  "scrapedAt": "2026-01-01T18:05:00Z"
}
```

### Plan Requirement

The default proxy setting works out of the box. If a run reports that requests were refused, or for large or frequent runs, the residential proxy group gives more headroom; pick it under Connection. Residential and the other non-default options are billed by traffic and cost more, so switch only when you need to.

### FAQ

#### How much does it cost?

You pay per result returned, plus a start charge per run. Reading each seller's full profile is opt-in and adds the **Seller profile attached** event (the registered `seller-enrichment` event shown on the **Pricing** tab): one event per returned result that carries the seller's full profile, charged as each such result is saved, and never for a result that was filtered out, skipped as unchanged or failed to read. Category and ranked seller rows are billed as ordinary results. Attached reviews are included in that profile read and are capped by `maxSellerReviews` (default 20, maximum 50) so a run's cost stays bounded. The **Pricing** tab shows the current rates. Use **Max results** to cap the cost of any run.

#### Is it legal to scrape Whatnot?

This actor collects only publicly available marketplace data. You are responsible for how you use it: follow Whatnot's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution.

#### Can I get only new or changed results 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, and unchanged ones are not billed unless you turn `emitUnchanged` on.

#### Why doesn't this actor return sold or final auction prices?

Realised (sold) prices for finished shows are not published by the site: its own show-status filter has no "ended" value, a show carries no connection to what it sold, and a seller's show list returns only future shows. This actor returns the pre-sale picture instead: which shows are running and scheduled, which lots are queued into them, and at what starting price.

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

If the site refuses every request, 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 enable Apify Proxy in the Connection section. If the site changed its data format, the run names that cause directly; no keyword, filter or proxy change will help.

#### 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 sports data?

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

<table>
<tr><td>🏷️ <a href="https://apify.com/abotapi/vinted-fr-scraper"><b>Vinted.fr</b></a><br>Scrape Vinted.fr, France's C2C second-hand fashion marketplace: search with...</td><td>🏷️ <a href="https://apify.com/abotapi/poshmark-scraper"><b>Poshmark Scraper</b></a><br>Scrape Poshmark fashion-resale listings: keyword search, brand and category browse, sold...</td></tr>
<tr><td>🥦 <a href="https://apify.com/abotapi/elcorteingles-es-scraper"><b>El Corte Inglés Scraper</b></a><br>Scrape El Corte Inglés elcorteingles.es products across fashion, electronics, home...</td><td>🥦 <a href="https://apify.com/abotapi/lidl-es-scraper"><b>Lidl.es Products, Weekly Offers, Prices &amp; Reviews Scraper</b></a><br>Scrape Lidl.es grocery and non-food products across weekly offers, tools, home, garden...</td></tr>
<tr><td>🏷️ <a href="https://apify.com/abotapi/vinted-marketplace-scraper"><b>Vinted Multi-Country Scraper</b></a><br>Scrape Vinted across 27 country marketplaces: keyword search with brand, price and...</td><td>👗 <a href="https://apify.com/abotapi/stockx-market-data-scraper"><b>StockX Scraper</b></a><br>Scrape StockX market data by keyword, category or URL. Every row carries lowest ask...</td></tr>
</table>

👉 [Browse all abotapi scrapers](https://apify.com/abotapi)

### 💬 Support

- 🐞 **Found a bug or a missing field?** Open a ticket on the [Issues tab](https://apify.com/abotapi/whatnot-scraper/issues/open). 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.

# Actor input Schema

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

Choose 'search' for keyword search across live shows, items or sellers, 'url' to scrape pasted links, 'seller' to read sellers by username (profile, scheduled shows and shop items), 'categories' to list the site's categories with their live audience, or 'leaderboard' to rank sellers inside a category.

## `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), seller shop links (/user/<username>/shop, shop lots only), seller reviews links (/user/<username>/reviews, the seller row with reviews attached), category links (whatnot.com/tag/<category> or the older /category/<category>) or search links (whatnot.com/search?query=..., where type=shows|items|sellers is applied). A locale prefix such as /en-GB/ and the bare whatnot.com host are accepted. Left untouched, this field scrapes one example of each of these link shapes; Max results is shared fairly across the links so each shape is reached.

## `sellers` (type: `array`):

Used in 'seller' mode. Whatnot usernames (a leading @ or a pasted profile link is accepted). Each seller returns the profile row, their scheduled shows and their shop items. At least one valid username is required, otherwise the run stops before reading anything; an invalid entry is skipped with a warning.

## `shopQuery` (type: `string`):

Used with seller links and 'seller' mode. Narrows each seller's shop items to titles matching this text. Leave empty for the whole shop.

## `categoryView` (type: `string`):

Used when mode is 'categories'. 'List' returns the site's top-level categories in the site's own order. 'Trending' returns every category that has viewers right now, ranked by live viewer count (Max results caps the rows, 50 when unset). Sub-category trees are not published to anonymous visitors, so only top-level lists and the flat tag ranking are available.

## `leaderboardInterval` (type: `string`):

Used when mode is 'leaderboard'. Which ranking window to read: today, this week, or the sellers live right now. 'All three' reads each window as its own set of rows. Rankings are regional: the country of the proxy exit changes who is listed.

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

Only return results in these categories, given as a category name (for example 'Pokemon Cards') or as the 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; this also applies to a pasted /user/<username>/reviews link, which then returns the seller row without reviews. 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.

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

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

## `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. A result counts as UPDATED when any of its fields changes, for example a show going live or being rescheduled (status, startTime), a price, a listing status, a current bid or bid count, a title or stock quantity. These are deliberately NOT compared, because they drift constantly and would mark every result as changed on every run: viewers watching (including the live viewers and show counts of a category and the viewers of a ranked seller's current show), watchlist counts, the position (rank) of category and leaderboard rows, and the seller's follower, sold, review count and rating figures (they stay in the output). The scrape timestamp is never compared either. Use Ignore fields below to exclude more. State is kept separately for each mode, result type, keyword set, seller list and filter setup, so two different searches never mix; changing Ignore fields keeps your saved state.

## `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.

## `ignoreFieldsForChanges` (type: `array`):

Optional. Field names to leave out when deciding whether a result changed, in addition to the built-in handling (viewers, watchlist, category audience counts, ranking positions and the seller counters never trigger UPDATED). Use a top-level name such as thumbnailUrl, or a nested path such as sellerReviews\[].text or variants.quantity. Ignored fields still appear in the output; they just never make a result UPDATED or show up in changedFields.

## `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",
    "https://www.whatnot.com/search?query=charizard",
    "https://www.whatnot.com/live/29169035-c0ed-494e-a5b6-bcb133286d4c",
    "https://www.whatnot.com/listing/TGlzdGluZ05vZGU6MjQwNzY2NTg3NA==",
    "https://www.whatnot.com/user/spacenarwhalz/shop",
    "https://www.whatnot.com/user/spacenarwhalz/reviews",
    "https://www.whatnot.com/en-GB/tag/pokemon_cards",
    "https://www.whatnot.com/category/pokemon_cards",
    "https://whatnot.com/tag/pokemon_cards"
  ],
  "sellers": [],
  "categoryView": "list",
  "leaderboardInterval": "CURRENT_WEEK",
  "categories": [
    "pokemon_cards"
  ],
  "gradedOnly": false,
  "autographedOnly": false,
  "minSellerRating": "any",
  "premierShopOnly": false,
  "fetchSellerDetails": false,
  "maxSellerReviews": 20,
  "maxItems": 20,
  "maxPages": 0,
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": [],
  "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

## `categories` (type: `string`):

No description

## `leaderboards` (type: `string`):

No description

## `reviews` (type: `string`):

No description

## `changes` (type: `string`):

No description

## `summary` (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",
        "https://www.whatnot.com/search?query=charizard",
        "https://www.whatnot.com/live/29169035-c0ed-494e-a5b6-bcb133286d4c",
        "https://www.whatnot.com/listing/TGlzdGluZ05vZGU6MjQwNzY2NTg3NA==",
        "https://www.whatnot.com/user/spacenarwhalz/shop",
        "https://www.whatnot.com/user/spacenarwhalz/reviews",
        "https://www.whatnot.com/en-GB/tag/pokemon_cards",
        "https://www.whatnot.com/category/pokemon_cards",
        "https://whatnot.com/tag/pokemon_cards"
    ],
    "sellers": [],
    "categoryView": "list",
    "leaderboardInterval": "CURRENT_WEEK",
    "categories": [
        "pokemon_cards"
    ],
    "proxy": {
        "useApifyProxy": true
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "ignoreFieldsForChanges": []
};

// 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",
        "https://www.whatnot.com/search?query=charizard",
        "https://www.whatnot.com/live/29169035-c0ed-494e-a5b6-bcb133286d4c",
        "https://www.whatnot.com/listing/TGlzdGluZ05vZGU6MjQwNzY2NTg3NA==",
        "https://www.whatnot.com/user/spacenarwhalz/shop",
        "https://www.whatnot.com/user/spacenarwhalz/reviews",
        "https://www.whatnot.com/en-GB/tag/pokemon_cards",
        "https://www.whatnot.com/category/pokemon_cards",
        "https://whatnot.com/tag/pokemon_cards",
    ],
    "sellers": [],
    "categoryView": "list",
    "leaderboardInterval": "CURRENT_WEEK",
    "categories": ["pokemon_cards"],
    "proxy": { "useApifyProxy": True },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "ignoreFieldsForChanges": [],
}

# 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",
    "https://www.whatnot.com/search?query=charizard",
    "https://www.whatnot.com/live/29169035-c0ed-494e-a5b6-bcb133286d4c",
    "https://www.whatnot.com/listing/TGlzdGluZ05vZGU6MjQwNzY2NTg3NA==",
    "https://www.whatnot.com/user/spacenarwhalz/shop",
    "https://www.whatnot.com/user/spacenarwhalz/reviews",
    "https://www.whatnot.com/en-GB/tag/pokemon_cards",
    "https://www.whatnot.com/category/pokemon_cards",
    "https://whatnot.com/tag/pokemon_cards"
  ],
  "sellers": [],
  "categoryView": "list",
  "leaderboardInterval": "CURRENT_WEEK",
  "categories": [
    "pokemon_cards"
  ],
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": []
}' |
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/kVesyFTUrZRdqAdkO/openapi.json
