# Invaluable Scraper (`normdata/invaluable-scraper`) Actor

Scrape Invaluable prices realized and upcoming lots: price, estimates, bids, watchers, artist, auction house, location, category, description and photo. 100M+ past lots with every filter and no result cap. Fast: 1,000 lots in seconds.

- **URL**: https://apify.com/normdata/invaluable-scraper.md
- **Developed by:** [Norm Data](https://apify.com/normdata) (community)
- **Categories:** E-commerce, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $12.00 / 1,000 lots

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

![Norm Data](https://raw.githubusercontent.com/FabriAV/normdata/refs/heads/main/assets/banner_norm2.png)

## 🔨 Invaluable Scraper

Extract auction lots from **Invaluable**, the marketplace where thousands of auction houses (Sotheby's, Freeman's | Hindman, Leonard Joel and many more) sell art, jewelry, watches, antiques, coins, furniture, wine and collectibles. Get **prices realized** from **100M+ past lots** going back to 1997, or **upcoming and live lots** with their current bids, in one clean table.

Each lot comes with:

- **Price realized**, low and high **estimate**, and how the price compared to the estimate in %.
- Current bid, **number of bids** and **watchers**.
- Auction date (UTC and local), lot closing time, listing date, auction type (live, timed, view only).
- **Category**, subcategory and the house's own category.
- **Artist or maker** with a link to the artist page.
- **Auction house** name, ID and link, the auction catalog and its link.
- Location, state, country and map coordinates.
- Full catalog **description**, condition notes, the photo and the link to the lot.

### 🎯 Who uses it?

#### 🧑‍⚖️ Appraisers, insurers and estate planners

Pull every comparable sale of an artist, maker, model or category with prices and estimates, filtered by date and price, for valuations you can back up.

#### 💎 Dealers, resellers and flippers

See what Rolex Daytonas, Tiffany lamps or Banksy prints really sell for, then find upcoming lots with no bids and bid below the market.

#### 📊 Market researchers and collectors

Track an artist, a brand or a category year by year. Compare estimates with prices realized to spot what sells above or below expectations.

#### 🏛️ Auction houses

Benchmark competitors: what they sell, how many lots, and how their lots perform against estimate.

### ✨ What it does

- **Three modes.** Prices realized (sold lots), all past lots (sold or not) or upcoming and live lots.
- **Search the way you think:**
  - Search terms ("rolex daytona", "tiffany lamp", "banksy"), several per run.
  - **108 categories and subcategories**, from Jewelry > Men's Watches to Fine Art > Paintings and Wines & Spirits > Whiskeys.
  - **Artists or makers** ("Andy Warhol", "Rene Lalique"), matched to Invaluable's own artist list, aliases included.
  - **Auction houses** by name or ID.
- **Or paste Invaluable links:** a lot, a **whole auction catalog**, an artist page, an auction house page, a category page or a search. With links the filters are ignored.
- **Every useful filter:**
  - **Auction date range**: exact dates, or periods like "30 days" (ago for past lots, ahead for upcoming lots).
  - **Price realized**, **estimate**, **current bid** and **bid count** ranges.
  - Auction house **country**, and for upcoming lots the **state or region** and the **auction type**.
  - Words that must not appear in the title or description.
  - 8 sort orders: most recent or soonest, oldest, highest and lowest price, most bids, newly listed, lot number, best match.
- **New lots only.** For scheduled runs: saves only lots the same search has not saved before.

### 🏆 Why this scraper

- **No result cap.** Invaluable's search lists only a few thousand lots of a big search. This scraper splits big searches into auction date windows (and lot number bands for huge sales), so you get **every** lot: tested at 23,268 "tiffany lamp" sales in 81 seconds, in date order and with no duplicates.
- **Fast.** About 1,000 lots in 6 seconds.
- **Description included.** The full catalog text and condition notes come with every lot, at no extra cost.
- **Prices you can analyse.** Prices, estimates, price vs estimate %, bids and watchers are numbers. Dates are ISO. Photo URLs are ready to download.
- **Private data stays private.** Who watched, bid on or won a lot is never collected, only the counts.
- **No proxy needed.** Nothing extra to set up or pay for.

### 📦 What data you get

| Field | Description |
| --- | --- |
| `lotRef`, `url` | Invaluable lot ID and the lot page. |
| `lotNumber`, `title` | The lot as listed in the catalog. |
| `status` | `Sold`, `Unsold or not reported`, `Upcoming`, `Live` or `Closed`. |
| `priceRealized`, `currency`, `currencySymbol` | What the lot sold for, as the house reported it, in the lot's currency. |
| `lowEstimate`, `highEstimate`, `priceVsEstimatePct` | The house's estimate, and how far the price landed above or below the middle of it (0 = right on estimate, 50 = 50% above). |
| `currentBid`, `bidCount`, `watchers` | Bidding data. For past lots `currentBid` is the last online bid. |
| `saleType`, `auctionDate`, `auctionDateLocal`, `lotClosesAt`, `listedAt` | Live, timed or view only; auction start in UTC and house local time; when a timed lot closes; when it was listed. |
| `category`, `subcategory`, `subSubcategory`, `houseCategory` | Invaluable's categories and the house's own one. |
| `artist`, `artistRef`, `artistUrl` | Artist or maker, when the house set one. |
| `auctionHouse`, `houseRef`, `houseUrl` | Who sells it. |
| `auctionRef`, `auctionUrl` | The auction catalog the lot belongs to. |
| `location`, `state`, `country`, `latitude`, `longitude` | Where the house or sale is. |
| `onlineOnly`, `featured` | Online-only sale; featured lot. |
| `description`, `conditionNotes` | Full catalog text and condition notes. |
| `image` | Main photo. |
| `searchedFor` | Which of your searches or links found it. |
| `scrapedAt` | When the row was collected (UTC). |

#### Example row (trimmed)

```json
{
  "lotRef": "C6AB47CC42",
  "lotNumber": "2287",
  "title": "Cosmograph Daytona “The King”, Reference 6270 | A highly important yellow gold, diamond and sapphire-set chronograph wristwatch with bracelet, Circa 1985",
  "status": "Sold",
  "priceRealized": 40635000,
  "currency": "HKD",
  "lowEstimate": 16000000,
  "highEstimate": 32000000,
  "priceVsEstimatePct": 69.3,
  "saleType": "View Only",
  "auctionDate": "2025-10-21T03:00:00.000Z",
  "auctionDateLocal": "2025-10-21 11:00:00",
  "category": "Jewelry",
  "subcategory": "Watches, Men's",
  "auctionHouse": "Sotheby's",
  "houseUrl": "https://www.invaluable.com/auction-house/sothebys-4wsxvotis6",
  "auctionUrl": "https://www.invaluable.com/catalog/vlyzf82nkz",
  "location": "Hong Kong, HK",
  "country": "Hong Kong",
  "description": "Rolex Cosmograph Daytona “The King”, Reference 6270 A highly important yellow gold, diamond and sapphire-set chronograph wristwatch...",
  "image": "https://image.invaluable.com/housePhotos/sothebys/74/802074/H0046-L419824081.jpg",
  "url": "https://www.invaluable.com/auction-lot/cosmograph-daytona-the-king-reference-6270-a-high-2287-c-c6ab47cc42",
  "searchedFor": "\"rolex daytona\"",
  "scrapedAt": "2026-10-07T20:26:27.072Z"
}
```

### 💡 Use cases

#### 📈 Every Rolex Daytona sold in the last 3 years

```json
{ "searchTerms": ["rolex daytona"], "dateFrom": "3 years", "maxItems": null }
```

#### 🏺 Chinese art that sold for $1,000 to $10,000 in the US

```json
{ "categories": ["KEDZ10Y647"], "countries": ["United States of America"], "minPrice": 1000, "maxPrice": 10000, "maxItems": null }
```

#### 🎨 Andy Warhol, highest price first

```json
{ "artists": ["Andy Warhol"], "sortBy": "price_high", "maxItems": 500 }
```

#### 🔔 New upcoming whiskey lots with no bids, every morning

```json
{ "mode": "upcoming", "categories": ["B244HNR1T1"], "maxBids": 0, "onlyNew": true, "maxItems": null }
```

#### 📚 A whole auction catalog

```json
{ "urls": ["https://www.invaluable.com/catalog/vlyzf82nkz"], "mode": "past", "maxItems": null }
```

### ⚙️ How the input is organised

| Section | What it's for |
| --- | --- |
| **Maximum lots** and **What to scrape** | Always first: caps the whole run (shared across your searches; empty means no limit), and the mode. |
| **Search with filters** | Search terms, categories, artists, auction houses. |
| **When and where** | Auction date range, country, state or region. |
| **Prices and bids** | Price realized, estimate, current bid and bid count ranges, auction type, words to exclude. |
| **Or search with links** | Invaluable links. When links are given, the filters above are ignored. |
| **Order and monitoring** | Sort order, new lots only, monitor name. |

Search terms, categories and artists combine: each term is searched in each category, for each artist. The other filters narrow every search. **Links and filters are not mixed:** with links, the filters are ignored and the log says which ones.

### 💰 Pricing

Pay-per-event: a one-time **$0.003** when the run starts, plus a price per lot saved to your dataset that drops with your Apify plan.

| Your Apify plan | Per lot | 1,000 lots |
| --- | --- | --- |
| Free | $0.018 | $18.00 |
| Bronze | $0.016 | $16.00 |
| Silver | $0.014 | $14.00 |
| Gold / Platinum / Diamond | $0.012 | $12.00 |

Lots dropped by your filters are not charged. There are no proxy costs. New Apify accounts start with $5 in free credit. On the Free plan a run saves up to 10 lots.

**Speed:** about 1,000 lots in 6 seconds.

### 🚀 Run it

1. Create a free Apify account with $5 in credit.
2. Open the Invaluable Scraper.
3. Type a search term (or keep the prefilled one), pick the mode and your filters, then click **Start**.
4. Export the results as CSV, Excel, JSON, or XML from the Dataset tab.

You can also:

- Run it programmatically through the Apify API (`run-sync-get-dataset-items`) or the ApifyClient for JavaScript and Python.
- Schedule it with Apify's built-in Scheduler, with **New lots only** on, to catch new lots every day.

### 🤖 Use with AI agents (MCP)

Give an AI agent live access to auction prices through the Model Context Protocol:

```
claude mcp add --transport http apify "https://mcp.apify.com?tools=normdata/invaluable-scraper"
```

Then prompt it in plain language, for example "what did Rene Lalique vases sell for this year?".

### 🔧 Troubleshooting

**The log says "Big search ... split into auction date windows".**
That's normal. Invaluable lists only part of a big search at once, so bigger searches are collected window by window. Rows still come in the order you asked: the first ones in your sort, the rest by date.

**An artist was searched as keywords.**
The name is not in Invaluable's artist list, so it was added to the search words instead. Results are still relevant, just less strict.

**Prices are in different currencies.**
Each lot keeps its house's currency (`currency`). Price filters apply in that currency.

**Some sold lots have no price.**
Not every house reports its results. Use **All past lots** to include them, or **Prices realized** to keep only lots with a price.

**A filter was ignored.**
Some filters only fit one mode (state and auction type are for upcoming lots, price realized for past lots), and links ignore all filters. The log names each ignored filter.

**A scheduled "New lots only" run saved nothing.**
Nothing new matched since the last run. Changing terms, links or filters starts a fresh memory; set a **Monitor name** to keep it.

### ❓ FAQ

| Question | Answer |
| --- | --- |
| Do I need an Invaluable account? | No. Only public lot data is read. |
| Does the price include the buyer's premium? | It's the price the house reported to Invaluable, which often includes the premium. Check the house's terms when it matters. |
| How far back do past lots go? | To the late 1990s. Use the date range to pick a period. |
| Is there a result limit? | No. Leave the maximum empty to get the whole search. |
| Does it need a proxy? | No. There is an optional proxy setting if Invaluable ever slows down your runs. |
| Can I track new lots? | Yes. Turn on **New lots only** and schedule the run. |

### 🛡️ Limits & responsible use

This Actor reads only public lot data shown on Invaluable. It never signs in, never bids and never contacts auction houses. Who watched, bid on or won a lot is not collected. Use the data in line with Invaluable's terms.

### 📧 Contact

Need a scraper for a different site, or found something wrong with this one? norm.data.scrapers@gmail.com

### 🧪 Local development

```powershell
bun install
bun run typecheck
bun test/qa.mjs
apify run
```

Local results are stored in `storage/datasets/default`.

# Actor input Schema

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

Stop after this many lots in total. Leave empty for no limit (every matching lot, even when a search has hundreds of thousands). The Apify Free plan is always capped at 10.

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

Prices realized are past lots that sold, with the price. All past lots adds the ones that did not sell or have no price reported. Upcoming lots are open for bidding now or in future auctions, with the current bid.

## `searchTerms` (type: `array`):

One search per line, e.g. "rolex submariner", "tiffany lamp", "banksy". Leave empty to browse a whole category, artist or auction house.

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

Pick one or more of 108 Invaluable categories and subcategories. Each one is searched separately and combined with the search terms.

## `artists` (type: `array`):

Invaluable artist names, e.g. "Andy Warhol", "Rene Lalique", "Salvador Dali". Each one is searched separately. A name Invaluable does not list as an artist is searched as keywords.

## `auctionHouses` (type: `array`):

Keep only lots from these houses, e.g. "Leonard Joel", "Freeman's | Hindman". A name matches every house holding all its words. A 10 character house ID works too.

## `dateFrom` (type: `string`):

Past lots: sold on or after this date. Upcoming lots: auction on or after it. A date like "2024-01-01", or a period like "30 days" (ago for past lots, from now for upcoming lots).

## `dateTo` (type: `string`):

Same format as "Auction date from", e.g. "2024-12-31" or "7 days".

## `countries` (type: `array`):

Keep only lots sold by houses in ANY of these countries.

## `states` (type: `array`):

Upcoming lots only. Keep only houses in ANY of these states or regions, written in full, e.g. "Florida", "New York", "New South Wales", "Greater London".

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

Past lots only. Lots that sold for at least this much.

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

Past lots only. Lots that sold for at most this much.

## `minEstimate` (type: `integer`):

Lots whose estimate range reaches at least this amount.

## `maxEstimate` (type: `integer`):

Lots whose estimate range starts at or below this amount.

## `minCurrentBid` (type: `integer`):

Upcoming lots only.

## `maxCurrentBid` (type: `integer`):

Upcoming lots only.

## `minBids` (type: `integer`):

Lots with at least this many bids.

## `maxBids` (type: `integer`):

Lots with at most this many bids. 0 finds lots nobody has bid on yet.

## `saleTypes` (type: `array`):

Upcoming lots only. Keep only ANY of these.

## `titleExcludes` (type: `array`):

Drop lots whose title or description contains any of these words, e.g. "reproduction", "style of", "after". Not case sensitive.

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

Lot pages (/auction-lot/...), auctions (/catalog/...: every lot in the sale), artist pages (/artist/...), auction house pages (/auction-house/...), category pages (/paintings/cc-...) or searches (/search?keyword=...). "What to scrape" and "Sort by" still apply.

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

Order of the results. Matters most when you set a Maximum.

## `onlyNew` (type: `boolean`):

For scheduled runs: save only lots this same search has not saved before. The first run saves everything; later runs save just what is new. Kept per search (terms, links and filters).

## `monitorName` (type: `string`):

Optional. Give "New lots only" a fixed name to keep its memory even after you change the filters.

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

Optional, off by default. Invaluable works without one. Turn it on only if runs fail to connect. Proxy traffic is billed to your Apify account.

## Actor input object example

```json
{
  "maxItems": 10,
  "mode": "sold",
  "searchTerms": [
    "rolex submariner"
  ],
  "sortBy": "recent",
  "onlyNew": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `lots` (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 = {
    "maxItems": 10,
    "searchTerms": [
        "rolex submariner"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("normdata/invaluable-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 = {
    "maxItems": 10,
    "searchTerms": ["rolex submariner"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("normdata/invaluable-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 '{
  "maxItems": 10,
  "searchTerms": [
    "rolex submariner"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call normdata/invaluable-scraper --silent --output-dataset

```

## MCP server setup

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