# Invaluable Scraper: Auction Lots, Prices Realized & Houses (`oswaldocarabano/invaluable-auctions-scraper`) Actor

Scrape Invaluable auction results: sold lots with the price realized next to the estimate, or upcoming lots with current bid, bids and watchers. Plus auction houses and artists. Art, antiques, jewelry, watches, coins. Pay per lot; bidder IDs are never included.

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

## Pricing

from $4.70 / 1,000 auction lots

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

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

## What's an Apify Actor?

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

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

## How to integrate an Actor?

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

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

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

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

# README

## Invaluable Scraper: Auction Results, Prices Realized & Auction Houses

**Export auction results from [Invaluable.com](https://www.invaluable.com), one of the
largest online marketplaces for fine art, antiques, jewelry, watches, coins and
collectibles.** Get **sold lots with the price realized (hammer price) next to the
estimate**, or **upcoming lots with the current bid, bid count and watchers**, plus
the directories of **auction houses** and **artists**.

- **Sold prices database:** about 9.6 million sold lots with a price realized.
- **Live auctions:** about 250,000 lots open for bidding right now.
- **No browser, no login, no cookies.** 1,000 lots in about 4 seconds.
- **$4.70 per 1,000 lots.** You never pay for an error, a duplicate or a failed page.

***

### What people use it for

| If you are… | You get |
|---|---|
| An **appraiser, dealer or collector** pricing an object | sold comparables: price realized vs. low/high estimate, sale date, auction house, full description |
| Building an **art, watch or coin price index** | prices realized in their original currency, by category, artist, house and country |
| **Sourcing** before the hammer falls | upcoming lots filtered by keyword, category, estimate, country or auction house, sorted by ending soonest or most bids |
| Watching **demand** for a maker or category | bid counts, bidders, watchers and favorites on every upcoming lot |
| Doing **lead generation** for auction services | every auction house on Invaluable, its country and how many lots it has open for bidding |
| Researching **artists** | aliases, genres, total / upcoming / past lot counts and followers |

***

### Two lot datasets in one actor

| `searchMode` | What you get | Size (1 Oct 2026, the site's counter is approximate) |
|---|---|---|
| `past` *(default)* | **Sold lots with prices realized**, newest first | about **9.6 million** |
| `upcoming` | Lots open for bidding, with live bid data | about **250,000** |

Only lots that are actually listed on invaluable.com are returned (the same
visibility rules the site's own search applies), so every `lot_url` opens a real lot
page. Searches larger than one query can reach are **split by date automatically**,
so `maxItems` really is the number of rows you get (up to 100,000 per run).

***

### What actually arrives in a row

A lot row has **92 fields**. Every rate below was **measured on the Apify platform on
1 Oct 2026** on a stratified sample: 16 searches (painting, ring, chair, coin, vase,
print, silver, sculpture, rug, clock, porcelain, bronze, book, watch, lamp, poster) in
each mode, **n = 1,020 sold and 1,020 upcoming lots from 138 auction houses in 12
countries**. We do not promise a field we have not measured.

#### Always there: 100% in both modes

`lot_id` · `lot_ref` · `lot_number` · `lot_url` · `title` · `description` ·
`status` · `sale_type` (Live / Timed) · `auction_date` (ISO, UTC) ·
`auction_date_local` · `currency` · `current_bid` · `bid_count` · `watcher_count` ·
`supercategory` · `category` · `house_name` · `house_ref` · `catalog_ref` ·
`location` · `country` · `image_url`

#### Sold lots (`past`)

| Field | Fill rate |
|---|---:|
| **`price_realized`** (hammer price) | **100%** |
| `estimate_low` / `estimate_high` | 91.7% |
| `has_winner` | true on 43.2% |
| `more_text` (extra catalog notes, footnotes) | 44.4% |
| `end_time` (timed auctions) | 16.1% |
| `artist_name` / `artist_ref` | 10.9% (43.4% in Fine Art) |

#### Upcoming lots (`upcoming`)

| Field | Fill rate |
|---|---:|
| `posted_at`, `bidder_count`, `favorite_count`, `activity_count` | 100% |
| `subcategory`, `latitude` / `longitude`, `image_width` / `image_height` | 100% |
| `state` (auction house region) | 82.8% |
| `estimate_low` / `estimate_high` | 77.5% / 76.9% |
| `more_text` | 63.8% |
| `end_time` (timed auctions) | 33.1% |
| `artist_name` / `artist_ref` | 24.4% (66.4% in Fine Art) |
| `reserve_price` | 4.1% |

**Money is always in the lot's own currency**, with `currency` on every row
(USD, EUR, GBP, AUD, CAD, JPY and more). We never convert silently.

**A zero in the source is not a price.** Invaluable stores "no estimate" and "no
result" as `0`; this actor delivers them as `null`, so an average of
`price_realized` is never dragged down by fake zeros.

***

### Full lot page data: optional, charged separately

Turn on `scrapeDetails` to open each lot page and add what only the page has.
Measured on **n = 120 lot pages** (60 sold, 60 upcoming; paintings, rings, chairs):

| Field | Fill rate |
|---|---:|
| `photos`: **every photo** (4.7 per lot on average; the search gives 1) | 100% |
| `buyers_premium` and `buyers_premium_tiers` | 100% |
| `bid_increments`, `accepted_payment_forms`, `shipping_details` | 100% |
| `catalog_title`, `catalog_date`, `catalog_timezone`, live / timed flags | 100% |
| `house_street`, `house_city`, `house_postal_code`, `house_country_code` | 99–100% |
| `house_logo_url`, `house_region` | 98.3% |
| `sold_amount` (sold lots; equal to `price_realized` in 60 of 60) | 100% of sold |
| `usd_conversion_rate` | 66.7% |
| `condition_report` | 50.0% |
| `exhibited` | 16.7% |
| `dimensions` | 15.0% |
| `medium` | 8.3% |
| `provenance` | 3.3% |

A lot page takes about 1.5 s, so it is **off by default** and billed as its own
event, **only when the page is read successfully**. Lot page data may be reused for
up to `maxCacheAgeDays` (default 7); such rows say so in `detail_from_cache` and
`detail_fetched_at`.

***

### Auction houses and artists

Set `outputType` to get a directory instead of lots, one row type per run:

- **`auctionHouses`**: name, ID, country, logo and number of upcoming lots for each
  of about **6,900 auction houses**. Filter by `countries` or `keyword`.
- **`artists`**: name, first/last name, aliases, genres, total, upcoming and past
  lot counts and followers, for about **259,000 artists**.

***

### Pricing

Pay per event. **You never pay for an error row, a duplicate or a failed page.**

| Event | Price |
|---|---:|
| Actor start | $0.00001 (platform minimum) |
| **Auction lot** | **$0.0047** |
| Full lot page (optional) | $0.003 |
| Auction house | $0.001 |
| Artist | $0.001 |

1,000 sold lots with prices realized = **$4.70**. With full lot pages = $7.70.
Duplicates are removed **within a run**. If you set a maximum cost for the run, the
actor stops cleanly at it and never delivers a row it did not charge.

***

### Input

| Field | Default | Notes |
|---|---|---|
| `outputType` | `lots` | `lots`, `auctionHouses`, `artists` |
| `searchMode` | `past` | `past` = sold with prices realized, `upcoming` = open for bidding |
| `keyword` | empty | like the search box on invaluable.com; a pasted invaluable.com search URL also works |
| `categories` | all | the 14 top-level Invaluable categories |
| `countries` | all | country of the auction house, e.g. `Germany`; `USA` and `UK` work too |
| `auctionHouses` | all | house names, e.g. `Bonhams` |
| `artist` | any | artist name, e.g. `Pablo Picasso` |
| `saleType` | `any` | `Live` / `Timed`, upcoming lots only |
| `minEstimate` / `maxEstimate` | — | in each lot's currency, decimals allowed |
| `minPrice` / `maxPrice` | — | price realized (past) or current bid (upcoming) |
| `dateFrom` / `dateTo` | — | `YYYY-MM-DD`, UTC |
| `includeUnsold` | `false` | past lots without a published price |
| `sortBy` | `date` | date, oldest first, relevance, price high/low, newly listed, most bids |
| `maxItems` | 100 | hard cap on rows delivered and charged |
| `scrapeDetails` | `false` | full lot page data, separate event |

**Every filter was checked against the rows it returns** on the platform: category,
country, auction house, artist, sale type, estimate, price and date filters matched
100% of the delivered rows in our test runs, and every sort order came back in
order. Keywords return lots that actually contain the word (typo matches such as
"patent" for "patek" are left out).

***

### Privacy

The seller on Invaluable is a **registered auction house**, a business. Auction
house names, addresses and logos are business data and are included.

Bidders are people, and **no bidder identifier ever leaves this actor**: the site
exposes the IDs of watchers, bidders and winners, and we deliver only counts
(`watcher_count`, `bidder_count`) and a `has_winner` flag. Never the IDs, never
anyone's maximum bid. We checked every row of every test run: zero bidder IDs.

***

### Output example (sold lot, shortened)

```json
{
  "row_type": "lot",
  "lot_id": "205866906",
  "title": "Vintage Rolex Day-Date President Gold and Diamond Watch",
  "status": "sold",
  "auction_date": "2026-09-25T14:00:00.000Z",
  "currency": "USD",
  "estimate_low": 7000,
  "estimate_high": 10000,
  "price_realized": 13000,
  "bid_count": 17,
  "watcher_count": 50,
  "supercategory": "Jewelry",
  "category": "Watches, Women's",
  "house_name": "Charlton Hall",
  "location": "West Columbia, SC, US",
  "country": "United States of America",
  "lot_url": "https://www.invaluable.com/auction-lot/vintage-rolex-day-date-president-gold-and-diamond-656-c-692359e70e"
}
```

The run also writes `RUN_SUMMARY` (delivered and charged counts) and `ERRORS`
(pages that could not be read, never charged) to the key-value store.

***

### FAQ

**How do I get past auction results for one object?** Put the object in `keyword`
(e.g. `tiffany lamp`), keep `searchMode` = `past`, and optionally set `sortBy` =
`relevance`. Each row has the price realized and the estimate side by side.

**Can I get prices realized for one artist?** Yes: set `artist` (e.g. `Pablo
Picasso`). Turn on `scrapeDetails` for medium, dimensions and provenance when the
house published them.

**Are prices converted to USD?** No. Each row keeps the lot's own currency in
`currency`. With full lot pages, `usd_conversion_rate` gives the site's rate when
available (66.7% of lot pages). Note that sorting by price compares the raw numbers
across currencies.

**Why do some sold lots have an auction date a few days ahead?** Some houses publish
results under the catalog's closing date. The date is what Invaluable shows; we do
not alter it.

**Can I get every lot ever sold?** `maxItems` goes up to 100,000 per run and the
actor splits big searches by date. For more, schedule runs by date range.

**What happens if my search has no results or my input is wrong?** The run ends
green with one error row that says why, and no lot is charged.

**Is the data fresh?** Search results are read live on every run. Only the optional
lot page data can come from a cache, and those rows say so.

**Can I schedule it or call it from my code?** Yes: Apify schedules, the API, and
integrations (Google Sheets, Zapier, Make, webhooks) all work with this actor.

# Actor input Schema

## `outputType` (type: `string`):

One row type per run. Auction lots is the main product; auction houses and artists are cheap directory exports.

## `searchMode` (type: `string`):

Past = sold lots with the hammer price (price realized), newest first by default — roughly 9 million on Invaluable. Upcoming = lots open for bidding with current bid, bid count and watchers — about 300,000.

## `keyword` (type: `string`):

Free-text search, like the search box on invaluable.com (e.g. "rolex", "tiffany lamp", "picasso lithograph"). Leave empty to get every lot matching the filters. For auction houses and artists, it searches their names. A pasted invaluable.com search URL also works.

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

Top-level Invaluable categories. Empty = all.

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

Country of the auction house, as Invaluable writes it: "United States of America", "United Kingdom", "Germany", "Australia", "France"… Case does not matter, and USA / UK also work. Empty = all.

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

Exact auction house names as shown on Invaluable (tip: run once with outputType = Auction houses to get the list). Empty = all.

## `artist` (type: `string`):

Exact artist name as Invaluable attributes it, e.g. "Pablo Picasso". Empty = any.

## `saleType` (type: `string`):

Live or timed auctions. Only works for upcoming lots: the site does not keep the sale type filterable for past lots.

## `minEstimate` (type: `number`):

Only lots whose low estimate is at least this amount (in each lot's own currency).

## `maxEstimate` (type: `number`):

Only lots whose high estimate is at most this amount (in each lot's own currency).

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

Past lots: minimum price realized. Upcoming lots: minimum current bid. In each lot's own currency.

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

Past lots: maximum price realized. Upcoming lots: maximum current bid.

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

YYYY-MM-DD (UTC). Empty = no lower bound.

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

YYYY-MM-DD (UTC), inclusive. Empty = no upper bound.

## `includeUnsold` (type: `boolean`):

Off = only lots with a published hammer price (the valuation dataset). On = also past lots that passed or have no published result.

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

Date = newest first for past lots, ending soonest for upcoming lots. Newly listed and most bids apply to upcoming lots only; oldest first to past lots only.

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

Hard cap on rows delivered (and charged). Searches larger than 20,000 are split by date automatically.

## `scrapeDetails` (type: `boolean`):

Open each lot page to add every photo (4.3 on average instead of 1), dimensions, medium, condition report, provenance, the auction house address, buyer's premium tiers and bid increments. Charged per lot as a separate event, only when the page is read successfully. About 1.5 s per lot.

## `maxConcurrency` (type: `integer`):

Only used with full lot page data. The site paces lot pages; 3 is the measured sweet spot.

## `maxCacheAgeDays` (type: `integer`):

Lot page data fetched in the last N days may be reused (rows say so in detail\_from\_cache). 0 = always fetch fresh.

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

Optional. Only lot pages use a proxy; the search itself does not need one. Leave empty to use the actor's built-in setup.

## Actor input object example

```json
{
  "outputType": "lots",
  "searchMode": "past",
  "keyword": "rolex",
  "saleType": "any",
  "includeUnsold": false,
  "sortBy": "date",
  "maxItems": 50,
  "scrapeDetails": false,
  "maxConcurrency": 3,
  "maxCacheAgeDays": 7,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

One row per auction lot: title, estimate, current bid or price realized, auction date, category, artist, auction house, location and images.

## `runSummary` (type: `string`):

Counts delivered and charged, network summary and whether the run stopped early.

## `errors` (type: `string`):

Lot pages that could not be read and input adjustments (always written, empty when all went well). Never charged.

# 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 = {
    "keyword": "rolex",
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("oswaldocarabano/invaluable-auctions-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 = {
    "keyword": "rolex",
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("oswaldocarabano/invaluable-auctions-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 '{
  "keyword": "rolex",
  "maxItems": 50
}' |
apify call oswaldocarabano/invaluable-auctions-scraper --silent --output-dataset

```

## MCP server setup

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