# Whatnot All-in-One API (`romy/whatnot-all-in-one-api`) Actor

Unofficial always-on REST API for live Whatnot data: live streams, listing search with 16 verified filters, listing detail, sellers, reviews and categories. No account, app or device needed. Runs in Apify Standby.

- **URL**: https://apify.com/romy/whatnot-all-in-one-api.md
- **Developed by:** [Romy](https://apify.com/romy) (community)
- **Categories:** E-commerce, Developer tools
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.01 / 1,000 listing returneds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 All-in-One API

**Whatnot All-in-One API** is an unofficial, always-on REST API for live [Whatnot](https://www.whatnot.com) data: live streams, marketplace listings with 16 verified filters (graded cards, PSA/CGC/Beckett, set, rarity, price, condition, ...), listing detail, seller profiles, seller reviews and inventory, and the category/tag catalogue. It calls the same GraphQL API the Whatnot mobile app uses for a signed-out user, so no account, app or device is needed. Because this Actor runs in [Standby mode](https://docs.apify.com/platform/actors/development/programming-interface/standby) on the Apify platform, you call it like any REST API and get clean JSON back in about a second, with Apify handling authentication, scaling and monitoring for you.

### Why use Whatnot All-in-One API?

- **Collectibles market research** — track what is listed for a card, set or grade: prices, formats (buy-it-now vs live auction), seller countries and how many listings match.
- **Live-commerce monitoring** — see which shows are live in a category, their viewers, sellers and what they are selling right now.
- **Seller intelligence** — rating breakdown (shipping, packaging, accuracy), sold count, followers and written reviews for any seller.
- **Lead generation and sourcing** — find sellers by name, list their current inventory, and filter by price, format or category.

### How to use Whatnot All-in-One API

1. Click **Try for free** and start this Actor (Standby mode starts it once and keeps it warm).
2. Copy the Actor's Standby URL from the **Standby** tab.
3. Call any endpoint below, e.g. `GET {standby-url}/listings/search?q=psa%2010%20charizard&graded=true&gradingService=PSA&limit=20`.
4. Authenticate the call with your Apify token (`Authorization: Bearer <token>` or `?token=`).

No Whatnot login or API key is needed: this is the same public data the app shows to a signed-out user.

### Input

This Actor takes **no run-input configuration**: it starts immediately in Standby mode. Every real parameter is passed per request as an HTTP query parameter. See **Endpoints** below or the Actor's *API* tab for the full OpenAPI schema.

### Pagination

Every list endpoint returns `items` plus `pageInfo: { hasNextPage, nextCursor }` and is paged with `limit` (up to 50 per request) and `cursor` (the previous response's `nextCursor`). Notes verified against the live API:

- Live-stream feeds are **re-ranked on every request**, so a stream can repeat between pages: de-duplicate by `id`. Category/tag live feeds never report the end of the list; stop when a page brings no new ids.
- Listing search reaches about **1,000 results per query** (a hard server-side depth). Results after the strict matches (Whatnot's broader "results matching fewer words" backfill) are cut off and the response says so in `note`.
- `total` (where offered) is the server-side match count and is capped at 10,000.

### Endpoints

#### Live streams

##### `GET /livestreams`

Live streams currently on air: title, viewers, start time, tags, categories, seller and thumbnail. Without `category`/`tag` this is the logged-out "For You" feed. The feed is re-ranked on every request, so pages can repeat a stream (de-duplicate by `id`); category/tag feeds never report an end, so stop when a page brings no new ids.

| Param      | Required | Description                                                                               |
| ---------- | -------- | ----------------------------------------------------------------------------------------- |
| `category` | no       | Category id from GET /categories (numeric or global id), e.g. `149` = Trading Card Games. |
| `tag`      | no       | Tag id from GET /tags (numeric or global id). Ignored when `category` is set.             |
| `limit`    | no       | Items per page, 1-50 (default 20).                                                        |
| `cursor`   | no       | Opaque cursor: pass the previous response's `pageInfo.nextCursor` to get the next page.   |

Billed per item returned (`livestream` event); an empty result is free.

##### `GET /livestreams/search`

Full-text search over live and upcoming shows. Ended shows are not searchable.

| Param    | Required | Description                                                                             |
| -------- | -------- | --------------------------------------------------------------------------------------- |
| `q`      | yes      | Search text.                                                                            |
| `status` | no       | `PLAYING` = live now, `CREATED` = scheduled. (one of `PLAYING`, `CREATED`)              |
| `sort`   | no       | Order by current viewers. Omit for best match. (one of `viewers_desc`, `viewers_asc`)   |
| `limit`  | no       | Items per page, 1-50 (default 20).                                                      |
| `cursor` | no       | Opaque cursor: pass the previous response's `pageInfo.nextCursor` to get the next page. |

Billed per item returned (`livestream` event); an empty result is free.

##### `GET /livestreams/:id`

One show: title, status (`PLAYING`, `ENDED`, ...), viewers, start time, `endTime` (ended shows), tags, categories and seller.

| Param | Required | Description                              |
| ----- | -------- | ---------------------------------------- |
| `id`  | yes      | Live stream id (uuid) from /livestreams. |

Billed once per successful request (`livestream-detail` event).

##### `GET /livestreams/:id/listings`

The show's shop: buy-it-now items and queued/running auctions with price, title, quantity, images and seller. `total` is the full shop size. Ended shows have an empty shop.

| Param    | Required | Description                                                                             |
| -------- | -------- | --------------------------------------------------------------------------------------- |
| `id`     | yes      | Live stream id (uuid).                                                                  |
| `limit`  | no       | Items per page, 1-50 (default 20).                                                      |
| `cursor` | no       | Opaque cursor: pass the previous response's `pageInfo.nextCursor` to get the next page. |

Billed per item returned (`listing` event); an empty result is free.

#### Listings

##### `GET /listings/search`

Product search over currently listed items with 16 verified filters (category, buying format, seller rating, price range, graded/autographed, condition, language, set, rarity, grade, grading service, card number, year, ...). Values inside one filter are OR, different filters are AND. Sold listings are not searchable. Up to ~1000 results are reachable per query; results after the strict matches (broader "fewer words" backfill) are cut off. Whatnot ignores unknown non-attribute filter names, but an attribute that does not exist for the category (e.g. `year` on Pokémon cards) returns no results, so use the exact parameters below.

| Param             | Required | Description                                                                                                        |
| ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
| `q`               | yes      | Search text, e.g. `psa 10 charizard`.                                                                              |
| `category`        | no       | Category key(s) from GET /listings/filters, e.g. `pokemon_cards`. Comma-separated values are OR. (comma-separated) |
| `buyingFormat`    | no       | Fixed-price listings or live auctions only. (one of `BUY_IT_NOW`, `LIVESTREAM_AUCTION`)                            |
| `minSellerRating` | no       | Minimum seller rating. (one of `5.0`, `4.5`, `4.0`)                                                                |
| `premierShop`     | no       | Only Premier Shop sellers.                                                                                         |
| `sellerCountry`   | no       | Seller ship-from country code(s), e.g. `US,GB`. (comma-separated)                                                  |
| `minPrice`        | no       | Minimum price in major units (e.g. dollars); the server compares on a currency-normalised price.                   |
| `maxPrice`        | no       | Maximum price in major units.                                                                                      |
| `graded`          | no       | Only graded items (trading cards).                                                                                 |
| `autographed`     | no       | Only autographed items.                                                                                            |
| `condition`       | no       | Item condition(s), e.g. `Near Mint`. (comma-separated)                                                             |
| `language`        | no       | Language(s), e.g. `English,Japanese`. (comma-separated)                                                            |
| `productType`     | no       | Product type(s), e.g. `Card`, `Booster Box`. (comma-separated)                                                     |
| `set`             | no       | Set name(s), e.g. `Base Set`. (comma-separated)                                                                    |
| `rarity`          | no       | Rarity value(s), e.g. `Rare`. (comma-separated)                                                                    |
| `grade`           | no       | Grade(s), e.g. `10`, `9.5`. (comma-separated)                                                                      |
| `gradingService`  | no       | Grading company: `PSA`, `CGC`, `BECKETT`, `TAG`, `SGC`, ... (comma-separated)                                      |
| `cardNumber`      | no       | Card number(s). (comma-separated)                                                                                  |
| `year`            | no       | Year(s), sports cards (e.g. `2023`, `1997`). Pokémon cards have no Year attribute. (comma-separated)               |
| `sort`            | no       | Result order. Omit for best match. (one of `price_asc`, `price_desc`, `newest`, `oldest`)                          |
| `includeTotal`    | no       | Also return `total` (server-side match count, capped at 10000). Costs one extra upstream call.                     |
| `limit`           | no       | Items per page, 1-50 (default 20).                                                                                 |
| `cursor`          | no       | Opaque cursor: pass the previous response's `pageInfo.nextCursor` to get the next page.                            |

Billed per item returned (`listing` event); an empty result is free.

##### `GET /listings/filters`

The filters and sorts available for a search text, with their valid values (categories, sets, rarities, grades, grading services, ...) and the total number of matches.

| Param | Required | Description  |
| ----- | -------- | ------------ |
| `q`   | yes      | Search text. |

Billed once per successful request (`listing-filters` event).

##### `GET /listings/:id`

One listing: title, description, price, status, transaction type, category, attributes (condition, set, grade, ...), images, seller, views and product. Sold listings keep their metadata but their sale price and bids are redacted by Whatnot.

| Param | Required | Description                                                                      |
| ----- | -------- | -------------------------------------------------------------------------------- |
| `id`  | yes      | Listing id: numeric (`2319377156`) or the global id returned by other endpoints. |

Billed once per successful request (`listing-detail` event).

#### Sellers

##### `GET /sellers/search`

Find sellers by name: username, rating, sold count, followers and verification.

| Param    | Required | Description                                                                             |
| -------- | -------- | --------------------------------------------------------------------------------------- |
| `q`      | yes      | Seller name text.                                                                       |
| `limit`  | no       | Items per page, 1-50 (default 10).                                                      |
| `cursor` | no       | Opaque cursor: pass the previous response's `pageInfo.nextCursor` to get the next page. |

Billed per item returned (`seller` event); an empty result is free.

##### `GET /sellers/:username`

Rating (overall/shipping/packaging/accuracy and review count), sold count, followers, verification, Premier Shop status, ship-from country and whether the seller is live. Bio, display name and images are personal data and only returned with `includeProfileDetails=true`.

| Param                   | Required | Description                                             |
| ----------------------- | -------- | ------------------------------------------------------- |
| `username`              | yes      | Seller username (case-insensitive).                     |
| `includeProfileDetails` | no       | Also return bio, display name and profile/store images. |

Billed once per successful request (`seller-profile` event).

##### `GET /sellers/:username/reviews`

Written reviews, newest first: rating, text, date, seller response and per-topic ratings (overall, shipping, packaging, accuracy). `total` counts every rating of the seller, including ratings without text. Reviewer identities are personal data and only returned with `includeReviewers=true`.

| Param              | Required | Description                                                                             |
| ------------------ | -------- | --------------------------------------------------------------------------------------- |
| `username`         | yes      | Seller username (case-insensitive).                                                     |
| `minRating`        | no       | Only reviews with an overall rating of at least this many stars.                        |
| `includeReviewers` | no       | Also return reviewer username, id and photo.                                            |
| `limit`            | no       | Items per page, 1-100 (default 20).                                                     |
| `cursor`           | no       | Opaque cursor: pass the previous response's `pageInfo.nextCursor` to get the next page. |

Billed per item returned (`review` event); an empty result is free.

##### `GET /sellers/:username/listings`

A seller's current marketplace inventory (fixed-price and upcoming auctions). Sellers who only sell live have an empty inventory. Sold listings are not exposed.

| Param          | Required | Description                                                                             |
| -------------- | -------- | --------------------------------------------------------------------------------------- |
| `username`     | yes      | Seller username (case-insensitive).                                                     |
| `q`            | no       | Only listings matching this text.                                                       |
| `buyingFormat` | no       | Fixed-price or auction only. (one of `BUY_IT_NOW`, `LIVESTREAM_AUCTION`)                |
| `minPrice`     | no       | Minimum price in major units.                                                           |
| `maxPrice`     | no       | Maximum price in major units.                                                           |
| `sort`         | no       | Result order. (one of `price_asc`, `price_desc`, `newest`, `oldest`)                    |
| `limit`        | no       | Items per page, 1-50 (default 20).                                                      |
| `cursor`       | no       | Opaque cursor: pass the previous response's `pageInfo.nextCursor` to get the next page. |

Billed per item returned (`listing` event); an empty result is free.

##### `GET /sellers/:username/livestreams`

The seller's shows that are live now or scheduled. Past shows are not exposed.

| Param      | Required | Description                                                                             |
| ---------- | -------- | --------------------------------------------------------------------------------------- |
| `username` | yes      | Seller username (case-insensitive).                                                     |
| `limit`    | no       | Items per page, 1-50 (default 10).                                                      |
| `cursor`   | no       | Opaque cursor: pass the previous response's `pageInfo.nextCursor` to get the next page. |

Billed per item returned (`livestream` event); an empty result is free.

#### Taxonomy

##### `GET /categories`

The category tree (two levels): top-level categories, or the children of `parent`. Use the `numericId` as `category` in /livestreams.

| Param    | Required | Description                                                                 |
| -------- | -------- | --------------------------------------------------------------------------- |
| `parent` | no       | Parent category id (numeric or global id) to list its children, e.g. `149`. |

Billed once per successful request (`categories` event).

##### `GET /tags`

The tag catalogue (brands, fandoms, product types, set releases, ...), about 1,800 tags, paginated. Use the `numericId` as `tag` in /livestreams.

| Param    | Required | Description                                                                                                                                                                |
| -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`   | no       | Only tags of this type. (one of `BRAND`, `FANDOM`, `PRODUCT_TYPE`, `SET_RELEASE`, `FASHION_STYLE`, `EVENT`, `GENRE`, `ITEM_CONDITION`, `SHOW_STYLE`, `SEASONAL`, `SIZING`) |
| `limit`  | no       | Items per page, 1-50 (default 20).                                                                                                                                         |
| `cursor` | no       | Opaque cursor: pass the previous response's `pageInfo.nextCursor` to get the next page.                                                                                    |

Billed once per successful request (`tags` event).

##### `GET /autocomplete`

Search-as-you-type suggestions: matching queries, sellers and tags, with result counts.

| Param | Required | Description        |
| ----- | -------- | ------------------ |
| `q`   | yes      | Text typed so far. |

Billed once per successful request (`autocomplete` event).

### Output

Every response is plain JSON. List endpoints:

```json
{
    "success": true,
    "items": [
        {
            "id": "TGlzdGluZ05vZGU6MjMxOTM3NzE1Ng==",
            "numericId": 2319377156,
            "title": "Slab: Pokemon: Charizard ex: SAR: Shiny Treasure ex: PSA 10",
            "price": { "amountMinor": 44000, "currency": "USD" },
            "transactionType": "BUY_IT_NOW",
            "listingStatus": "active",
            "user": { "username": "example_seller" }
        }
    ],
    "pageInfo": { "hasNextPage": true, "nextCursor": "YXJyYXljb25uZWN0aW9uOjQ=" },
    "total": 215
}
```

Single-item endpoints return `{ "success": true, "data": { ... } }`. Errors return `{ "success": false, "error": "..." }` with HTTP 400 (bad parameters), 404 (not found) or 502 (Whatnot error).

#### Data notes

- **Money** is `{ amountMinor, currency }` in the currency's minor units (44000 USD = $440.00), always in the seller's own currency. Whatnot also localizes prices to the viewer's IP; those fields are dropped so results do not depend on which IP served the request.
- **Ids**: nodes carry Whatnot's global `id` (base64) and a `numericId`; live streams use uuids. Listing, category and tag ids also accept the plain numeric form.
- **Personal data**: reviewer identities, seller bio, display name and profile photos are off by default and only returned with `includeReviewers=true` / `includeProfileDetails=true`.

### What is not available

Whatnot only serves the following to logged-in users or redacts it for everyone, so this Actor does not offer it:

- **Sold prices and bid history.** Sold listings can be read but their sale price and bids are redacted by Whatnot; the search index only contains active listings.
- **Followers/following lists, seller leaderboards and personalized feeds** (Following, marketplace "For You").
- **Past shows** (only live and scheduled shows are exposed).

### Pricing / Cost estimation

This Actor is billed **pay-per-event**:

- **List endpoints are billed per item returned** (live streams, listings, reviews, sellers): a page of 50 listings is 50 `listing` events, and an empty result is free. That is the same unit other Whatnot scrapers use, priced below the market leaders.
- **Single-object endpoints** (listing detail, seller profile, live stream detail, filter options) and **taxonomy endpoints** (categories, tags, autocomplete) are billed once per successful request.

The per-event price is shown on the Actor's page and gets cheaper on higher Apify plans. There is no per-minute compute charge because Standby keeps the Actor warm between calls, and failed requests are not billed.

### Tips

- Use `GET /listings/filters?q=...` first to see the exact category, set, rarity and grading values for a search, then pass them to `/listings/search`.
- Filters are AND across fields and OR inside one field. Whatnot silently ignores unknown *non-attribute* filter names, but an attribute that does not exist for a category (e.g. `year` on Pokémon cards) returns **zero** results; use the parameter names in this README.
- `minPrice`/`maxPrice` are in major units (dollars) and compared on a currency-normalised price.

### FAQ, disclaimers, and support

This is an **unofficial** Actor, not affiliated with or endorsed by Whatnot Inc. It reads only data that Whatnot shows to signed-out users in its own app; no account credentials, private data or bypassed authentication are involved. Use responsibly and in line with Whatnot's Terms of Service and applicable law; do not use it to enumerate ids or to collect personal data.

Found an issue or need a custom endpoint? Use the **Issues** tab on this Actor's page.

# Actor input Schema

## Actor input object example

```json
{}
```

# Actor output Schema

## `api` (type: `string`):

This Actor does not write to a dataset: every response is returned directly over HTTP by its Standby web server. See the README / web server OpenAPI schema (webServerSchema) for the endpoint list and response shapes.

# 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("romy/whatnot-all-in-one-api").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("romy/whatnot-all-in-one-api").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 romy/whatnot-all-in-one-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,romy/whatnot-all-in-one-api"
        }
    }
}
```

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/S5eVizW7bEddlAl6f/builds/KkBEZrwnmDwnVPEE0/openapi.json
