# LiveAuctioneers Scraper — Auction Lots & Prices Realized (`scrapersdelight/liveauctioneers-scraper`) Actor

Paste any LiveAuctioneers search, category, catalogue, auctioneer or lot URL — or search by keyword. One row per lot: title, lot number, auction house, category path up to 4 levels, estimates, current bid, price realized, sale date, condition report, images, venue address and buyer premium.

- **URL**: https://apify.com/scrapersdelight/liveauctioneers-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** E-commerce, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 per lot returneds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

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

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

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

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

# README

## LiveAuctioneers Scraper — Auction Lots & Prices Realized

Fine-art, antique and collectible auction lots from [LiveAuctioneers](https://www.liveauctioneers.com).
**One row is one lot**, carrying **lotTitle**, **lotNumber**, **auctionHouse**, **auctionTitle**,
a **categoryPath** up to 4 levels deep, **creators** (artist/maker), **estimateLow** / **estimateHigh**,
**startPrice**, **currentBid**, **bidCount**, **salePrice** (the hammer price), **buyersPremiumPct**,
**saleStartAt** / **lotClosesAt**, **conditionReport**, the full **description**, every **image** URL,
the lot's city/state/country and the sale **venueAddress** with **latitude/longitude**.

Paste any LiveAuctioneers URL — a search, a browse category, a sale catalogue, an auctioneer page or a
single lot — or build a query from keywords, categories, houses and catalogue ids. One switch flips
between **upcoming lots you can still bid on** and the **prices-realized archive**.

**No login. No browser. No CAPTCHA solving.** It reads the site's own public JSON services.

Measured live on 2026-08-12: **977,647 lots currently listed** —
Jewelry 387,937 · Collectibles 198,363 · Art 128,509 · Home & Décor 105,173 · Fashion 101,757 ·
Furniture 20,572. The sold archive reaches back to **2009**.

***

### Quick start

Click **Try for free** and hit **Start**. This is the input the Actor ships with — it needs no edits:

```json
{
  "startUrls": ["https://www.liveauctioneers.com/c/art/paintings/"],
  "lotStatus": "upcoming",
  "sort": "-publishDate",
  "maxLots": 50
}
```

That run, measured twice on 2026-08-12 through the Apify datacenter proxy: **50 lots, 5 HTTP calls,
5/5 first try, 0 duplicates, 5 s and 11 s wall-clock** — $0.15 either way.

#### The way in is a URL you already have

Go to liveauctioneers.com, search or browse until the page shows what you want, copy the URL out of
the address bar, paste it into **Start URLs**. Five shapes are recognised and each is routed to the
right walker:

| Paste this | What you get |
|---|---|
| `https://www.liveauctioneers.com/search/?keyword=tiffany+lamp&status=online&sort=-estimatedPrice` | That keyword query. The URL's own `keyword`, `status` and `sort` override the form fields — what you were looking at is what you get. |
| `https://www.liveauctioneers.com/c/art/paintings/` · `https://www.liveauctioneers.com/c/jewelry/asian/6/158/` | That browse category. Slug paths are resolved against the live taxonomy; when the URL already carries the numeric ids, the most specific one is used directly. |
| `https://www.liveauctioneers.com/catalog/424639_splendid-relics-the-art-of-asian-dynasties/` | That whole sale catalogue, end to end. Zero pagination drift — measured 0.00% duplicates over 12 contiguous pages. |
| `https://www.liveauctioneers.com/auctioneer/197/freemans/` | Every lot that house currently has listed. |
| `https://www.liveauctioneers.com/item/82260058_tiffany-studios-table-lamp-with-lotus-shade-larchmont-ny` | Just those lots. Pasted lot URLs are fetched 50 at a time. |

Paste as many as you like, mixed freely. Anything that is not one of those five is **rejected with a
message naming the problem**, not silently guessed at — a `/price-result/` page carries a slug and no
lot id, so the Actor tells you to paste the catalogue instead rather than scraping something you did
not ask for.

Measured on 2026-08-12, one run with all five shapes plus two deliberate rejects:
**19 lots, 16 HTTP calls, 16/16 first try, 0 interstitials, 0.00% duplicates.**

#### How to use it

1. Create a free Apify account and open this Actor.
2. Paste one or more LiveAuctioneers URLs into **Start URLs** (or clear it and use the keyword/category boxes below).
3. Choose **Upcoming** or **Sold**, and set **Max lots** — that is your cost cap.
4. Click **Start**.
5. Download the dataset as JSON, CSV, Excel or XML, or pull it from the API.

***

### Sample row

A real upcoming lot, from the run above:

```jsonc
{
  "lotUrl": "https://www.liveauctioneers.com/item/237265777_rolex-submariner-date-watch-beverly-hills-ca",
  "itemId": 237265777,
  "lotNumber": "0175",
  "lotTitle": "ROLEX SUBMARINER DATE WATCH",

  "auctionHouse": "NY Elizabeth",
  "auctionTitle": "26820 | Crown & Complications",
  "categoryPath": "Jewelry > Watches > Wristwatches",

  "currency": "USD",
  "estimateLow": 97800,
  "estimateHigh": 143440,
  "startPrice": 25,
  "currentBid": 300,
  "bidCount": 2,
  "salePrice": null,          // not sold yet
  "isSold": false,
  "buyersPremiumPct": 30,

  "saleStartAt": "2026-08-16T23:00:00.000Z",
  "lotClosesAt": "2026-08-16T23:00:00.000Z",

  "lotCity": "Beverly Hills",
  "lotState": "CA",
  "lotCountry": "US",
  "conditionReport": "Pre-Owned",
  "imageCount": 4,

  "venueAddress": "269 South Beverly Drive Suite 142",
  "venueLatitude": 34.0625,
  "venueLongitude": -118.399
}
```

<details>
<summary><b>The same shape on a SOLD lot — full row, every field</b> (click to expand)</summary>

```json
{
  "lotUrl": "https://www.liveauctioneers.com/item/82260058_tiffany-studios-table-lamp-with-lotus-shade-larchmont-ny",
  "itemId": 82260058,
  "lotNumber": "0101",
  "lotTitle": "Tiffany Studios Table Lamp With \"Lotus\" Shade",
  "auctionHouse": "Clarke Auction Gallery",
  "auctionHouseId": 483,
  "auctionHouseRating": 4.59,
  "auctionHouseReviewCount": 623,
  "auctionHouseIsTopRated": true,
  "auctionTitle": "Tiffany Lamps, Lalique, Fine Art, Jewelry...",
  "auctionId": 162941,
  "auctionUrl": "https://www.liveauctioneers.com/catalog/162941_tiffany-lamps-lalique-fine-art-jewelry/",
  "auctionStatus": "done",
  "auctionLotCount": 570,
  "saleType": "live",
  "saleStartAt": "2020-03-22T15:00:00.000Z",
  "lotClosesAt": "2020-03-22T15:00:00.000Z",
  "category": "Home & Décor",
  "subcategory": "Lighting",
  "categoryPath": "Home & Décor > Lighting > Lamps > Table Lamps",
  "categoryId": 26727,
  "creators": ["Tiffany Studios"],
  "materials": [],
  "currency": "USD",
  "estimateLow": 125000,
  "estimateHigh": 225000,
  "startPrice": 60000,
  "currentBid": 120000,
  "bidCount": 9,
  "salePrice": 120000,
  "isSold": true,
  "isPassed": false,
  "isReserveMet": true,
  "buyersPremiumPct": 25,
  "lotCity": "Larchmont",
  "lotState": "NY",
  "lotPostalCode": "10538",
  "lotCountry": "US",
  "description": "Signed on base and shade has small loop where a signature tag would have hung. From an important NYC collection - Illustrated Neustadt Page 74. Dimensions: 26\".25\" dia x 6\"H the shade. Clarke Auction guarantees the authenticity of this lamp.",
  "conditionReport": "Good.",
  "imageCount": 20,
  "images": ["https://p1.liveauctioneers.com/483/162941/82260058_1_x.jpg", "…19 more"],
  "venueAddress": "2372 Boston Post Road",
  "venueCity": "Larchmont",
  "venueState": "NY",
  "venuePostalCode": "10538",
  "venueCountry": "US",
  "venueLatitude": 40.9234,
  "venueLongitude": -73.7611,
  "auctionPreview": "- Thursday, March 19th, 12pm - 6pm - Friday, March 20th, 12pm - 6pm …",
  "shipsWithLiveAuctioneers": false,
  "shipsWithAuctionHouse": false,
  "freeShipping": false,
  "freeLocalPickup": false,
  "scrapedAt": "2026-08-12T22:59:04.205Z"
}
```

</details>

Three things people misread:

- **`salePrice` is `null`, never `0`, when a lot is unsold or the house withheld the hammer price.**
  `0` never appears in a money column — LiveAuctioneers uses `0` and `-1` internally for
  "no value" and "not disclosed", and both are emitted as `null`.
- **`buyersPremiumPct` is a percentage (25, 30), `auctionHouseRating` is a 0–5 scale (4.59).**
  Different scales, never mixed in one column.
- **`currentBid` empty is a fact, not a miss** — it tracks `bidCount`, which is on every row.

***

### The wedge: the full category path and the hammer price, as numbers

Two things make a lot row worth money: what the object *is*, and what it *made*.

- **`categoryPath` — 93.3% fill, up to four levels deep**: `Home & Décor > Lighting > Lamps > Table Lamps`,
  `Jewelry > Watches > Wristwatches`. **The depth is the lot's own, not a promise** — that table lamp
  returns 4 levels, that wristwatch 3, and a lot listed straight under `/c/art/paintings/` returns
  `Art > Paintings` and stops there. You get every level LiveAuctioneers filed the lot under.
  Plus `creators` (39.6%), `materials` (69.6%), `origins` (34.2%)
  and `stylePeriods` (32.2%). That is LiveAuctioneers' own classification, flattened into readable
  strings instead of nested API objects, and it is what lets you filter 977,647 lots down to
  "signed table lamps" rather than grepping titles.
- **`salePrice` — 100% fill on a 600-lot sold sample**, alongside `estimateLow` (99.0%),
  `bidCount` (100%) and `isSold` / `isPassed`. That is a comparable-sales archive with the estimate
  range next to the result, going back to 2009.

Every money field is a **number** and every date is **ISO-8601 UTC**. Not `"$60"`, not
`1584889200`. You can sum a column the moment the CSV lands.

***

### How it compares

Facts checked on the Apify Store and in each Actor's own published README and sample output on
2026-08-12.

| | **This Actor** | ivanvs/liveauctioneers-scraper | parseforge/liveauctioneers-scraper |
|---|---|---|---|
| Way in | Paste search / browse / catalogue / auctioneer / lot URLs, **or** build a query from keywords, categories, houses, catalogue ids | Paste search / browse URLs | Numeric **House ID + Auction ID**, both required; no URL accepted |
| Prices realized | `salePrice` + `isSold` + `isPassed`, **100% fill on a 600-lot sold sample** | No `salePrice` in its documented output | `salePrice` present |
| Money & dates | Numbers and ISO-8601 UTC | Strings — its own published sample shows `price: '$60'` and `estimated: {}` | Raw API shapes — `leadingBid`, `saleStartTs` as a Unix integer |
| Category | `categoryPath` up to 4 levels, 93.3% fill, + creators / materials / origins / style periods | Not returned | Raw `categories` / `creators` / `materialsTechniques` objects |
| Venue | Street address, city, state, postcode, lat/lon — **100% / 99.4%** | Auction-house location as one string (`"Islip, NY, United States"`) | `sellerLocation` |
| Condition report | Cleaned to text, `--` and `N/A` collapse to `null` — 60.3% fill | Present | Present |
| Proxy | Apify **datacenter** — measured 100% on every route | Its README states it uses **RESIDENTIAL** | Not stated |
| Price | **$0.003 per lot**, no start fee | $0.01 per dataset item | $0.005 start + $0.01734/result (FREE tier), $0.01299 (GOLD and above) |
| Published fill measurements | Yes — two samples, 720 + 600 lots, below | None | None |

**There is a third one, and on price it beats us:**
[jungle\_synthesizer/liveauctioneers-art-prices-realized-scraper](https://apify.com/jungle_synthesizer/liveauctioneers-art-prices-realized-scraper)
charges **$0.1 per Actor start (per GB) + $0.0005 per record** — about **$0.60 per 1,000 rows against
our $3.00**. What you give up for that: it returns **sold art lots only** (no upcoming lots, no
bid-able inventory), 20 snake\_case fields, `sale_date` as a date with no time, **no condition report,
no venue address, no buyer's premium, no image list** (one `thumbnail_url`), and no published fill
measurements. It does do one thing we do not: it resolves `/price-result/<slug>` URLs. Checked on the
Apify Store 2026-08-12.

The honest one-liner: if you just want a handful of lots off a page you are looking at, any of them
will do it. This one is built for the buyer who is going to load 10,000 rows into a spreadsheet and
do arithmetic on them — upcoming *and* sold, with the condition report, the venue and the premium
attached.

***

### What you get — one row per lot

| Group | Fields |
|---|---|
| **Identity** | `lotUrl`, `itemId`, `lotNumber`, `lotTitle` |
| **The auction** | `auctionHouse`, `auctionHouseId`, `auctionHouseRating`, `auctionHouseReviewCount`, `auctionHouseIsTopRated`, `auctionTitle`, `auctionId`, `auctionUrl`, `auctionStatus`, `auctionLotCount`, `saleType` |
| **Timing** | `saleStartAt`, `saleEndAt`, `lotClosesAt` |
| **Classification** | `category`, `subcategory`, `categoryPath`, `categoryId`, `creators`, `materials`, `origins`, `stylePeriods` |
| **Money** | `currency`, `estimateLow`, `estimateHigh`, `startPrice`, `currentBid`, `bidCount`, `buyNowPrice`, `salePrice`, `isSold`, `isPassed`, `isReserveMet`, `buyersPremiumPct` |
| **Where the lot is** | `lotCity`, `lotState`, `lotPostalCode`, `lotCountry` |
| **Descriptive** | `description`, `conditionReport`, `dimensions`, `weight`, `shippingDimensions`, `shippingWeight` |
| **Media** | `imageCount`, `images` |
| **The venue** | `venueAddress`, `venueCity`, `venueState`, `venuePostalCode`, `venueCountry`, `venueLatitude`, `venueLongitude`, `auctionPreview` |
| **Shipping flags** | `shipsWithLiveAuctioneers`, `shipsWithAuctionHouse`, `freeShipping`, `freeLocalPickup` |
| **Provenance** | `scrapedAt` |

Conventions, stated once: **all dates are ISO-8601 UTC**; all money fields are **numbers in the lot's
own `currency`**, with no FX conversion; **HTML is stripped and entities decoded** in `description`
and `conditionReport`; empty and placeholder values are `null`, never `""`, `0` or `"N/A"`.

The Actor also writes **`RUN_STATS`** to the key-value store: cards seen, lots emitted, the measured
in-run duplicate rate, whether either server ceiling was hit, HTTP call count, first-try success rate,
Incapsula interstitials retried, and the per-field fill percentage **for your run**. It is linked from
the run's Output tab.

***

### Read this before you buy rows

#### 1. Two server-side result ceilings that no setting can lift

LiveAuctioneers' search index does not let an unauthenticated client walk a query forever.
Both limits were measured, not guessed:

| | Reachable per query | What happens at the wall |
|---|---:|---|
| **Upcoming / live lots** | **~10,000 rows** | pages start returning empty |
| **Sold lots (prices realized)** | **~1,200 rows** | HTTP **403** — page 10 of 120 OK, page 11 forbidden |

`totalFound` will happily tell you a sold query matched 9,000 lots. Only the first ~1,200 are
retrievable. **The fix is narrower queries, not a bigger `maxLots`** — split by category, by
auction house, by a tighter keyword, and run several. The Actor logs a loud warning the moment
it touches either ceiling and records `hitServerResultCap` / `hitSoldAuthWall` in `RUN_STATS`.

#### 2. The sort key decides which slice of the archive you get

Because a sold query only returns ~1,200 rows out of a much larger match, **the sort order is not
cosmetic — it chooses which 1,200**. Measured on the sold index for "persian rug" (9,000 matches,
first page of 120 each time):

| Sort | Sale years returned |
|---|---|
| **Newest listed** (`-publishDate`, default) | 2026 only |
| **Sale date, soonest first** (`saleStart`) | 2009 (93) · 2010 (27) |
| **Highest estimate** (`-estimatedPrice`) | 2009 → 2026, weighted to 2021-2023 |
| **Most relevant** (`-relevance`) | 2016 → 2026, weighted to 2017-2019 |

Want recent comps? Newest listed. Want the deepest historical comps? Sale date. Want the
high-value comps regardless of year? Highest estimate.

#### 3. The sort key also decides the duplicate rate

The search index is re-ranked between requests, so contiguous pages can overlap. Duplicates are
always removed by lot id — but a drifting index **also skips rows**, so this is a coverage
setting. Measured over **12 contiguous pages of 120 lots** (live index, keyword "antique"):

| Sort | Cards | Unique | Duplicate rate |
|---|---:|---:|---:|
| Highest estimate (`-estimatedPrice`) | 1,440 | 1,440 | **0.00%** |
| **Newest listed (`-publishDate`, default)** | 1,320 | 1,264 | **4.24%** |
| Most relevant (`-relevance`) | 1,440 | 1,367 | 5.07% |
| Sale date (`saleStart`) | 1,440 | 1,240 | 13.89% |

Same test on the **sold** index (9 × 120, "rolex submariner"): `-publishDate` **0.00%**,
`-estimatedPrice` 0.19%, `-relevance` **15.74%**. Un-keyworded category and auction-house walks
on `-publishDate` measured **0.00–0.21%**.

**That is why the default is "Newest listed" and not "Most relevant"** — relevance is the
default on the website and it is the worst one to page through. Use "Highest estimate" for
exhaustive sweeps.

**Auction catalogues have no drift at all:** 12 contiguous pages × 100 lots = 1,200 cards,
**1,200 unique, 0.00% duplicates**. If you need a complete, exact set of lots, scrape the
catalogue.

#### 4. `currentBid` is empty on most upcoming lots — and that is the truth, not a gap

In a 720-lot sample, 12.1% of upcoming lots carried a current bid, and **every one of those
lots had `bidCount ≥ 1`**. The other 87.9% genuinely have no bids yet. `bidCount` and
`startPrice` are on every row, so "no bids" is distinguishable from "we failed to read it."
On **sold** lots `currentBid` fill is 99.3% and `salePrice` is 100%.

***

### Field fill — measured on 720 upcoming and 600 sold lots

**Sample A — 720 upcoming lots**, 12 keywords across every category, 75 auction houses,
253 separate auctions, 10 countries, 3 currencies:

| Field | Fill | Note |
|---|---:|---|
| `lotUrl`, `itemId`, `lotNumber`, `lotTitle` | **100%** | |
| `auctionHouse`, `auctionId`, `auctionTitle`, `auctionUrl`, `saleType` | **100%** | |
| `saleStartAt`, `lotClosesAt`, `auctionStatus`, `auctionLotCount` | **100%** | ISO 8601, UTC |
| `currency`, `estimateLow`, `estimateHigh`, `startPrice`, `bidCount` | **100%** | |
| `buyersPremiumPct` | **100%** | |
| `lotCity`, `lotPostalCode`, `lotCountry` · `lotState` | 100% · 99.9% | |
| `venueAddress`, `venueCity`, `venuePostalCode`, `venueCountry` | **100%** | the house's own street address |
| `venueLatitude` / `venueLongitude` | 99.4% | |
| `description` | **100%** | HTML stripped, entities decoded |
| `images` / `imageCount` | 99.9% | **6.6 photos per lot on average** |
| `auctionHouseRating` / `auctionHouseReviewCount` | 94.0% | |
| **`category`, `categoryPath`, `categoryId`** | **93.3%** | |
| `subcategory` | 80.7% | |
| `materials` | 69.6% | |
| `shippingDimensions` / `shippingWeight` | 60.4% | |
| **`conditionReport`** | **60.3%** | placeholders like `--` and `N/A` return `null`, not junk |
| `buyNowPrice` | 47.5% | |
| `auctionPreview` | 46.4% | viewing arrangements, free text |
| `creators` (artist / maker) | 39.6% | |
| `origins` · `stylePeriods` | 34.2% · 32.2% | |
| **`currentBid`** | **12.1%** | matches `bidCount ≥ 1` exactly — see gotcha 4 |
| `dimensions` · `weight` | 7.2% · 4.4% | most houses put sizes in the description instead |
| `salePrice` | 0.0% | by definition — nothing is sold yet |

**Sample B — 600 sold lots**, 6 keywords, 138 auction houses, 184 auctions:

| Field | Fill |
|---|---:|
| **`salePrice`** (hammer price) | **100%** |
| `isSold` | 100% (600/600 sold, 0 passed) |
| `bidCount`, `saleStartAt`, `venueAddress` | 100% |
| `currentBid` | 99.3% |
| `estimateLow` | 99.0% |
| `description` / `images` | 99.8% |
| `category` | 97.3% |
| `conditionReport` | 50.7% |

**The headline that could mislead you: on upcoming lots this is not a current-bid product.**
`currentBid` is 12.1% because 87.9% of lots have no bids yet. Plan against `estimateLow` /
`estimateHigh` (100%) for upcoming work, and against `salePrice` (100%) for comps.

A single 6-category run drawn from newly published catalogues gives narrower spread —
25 auctions, `estimateLow` 86%, `conditionReport` 43% — because a handful of large catalogues
dominate the newest listings. Both numbers are real; the spread depends on how you query.

**Every run prints its own measured fill in the log and stores it in `RUN_STATS`.**

***

### How to run it

#### Paste URLs (the default)

```json
{
  "startUrls": [
    "https://www.liveauctioneers.com/search/?keyword=rolex+submariner&status=online",
    "https://www.liveauctioneers.com/auctioneer/197/freemans/",
    "https://www.liveauctioneers.com/catalog/424639_splendid-relics-the-art-of-asian-dynasties/"
  ],
  "maxLots": 300
}
```

`maxLots` is split evenly between the three, with any unused share rolling forward, so one busy
query cannot eat the whole run.

#### Keyword search across the whole site

```json
{
  "startUrls": [],
  "source": "search",
  "searchTerms": ["ming vase", "roseville pottery"],
  "lotStatus": "upcoming",
  "maxLots": 500
}
```

#### Comparable sales — the prices-realized archive

```json
{
  "startUrls": [],
  "source": "search",
  "searchTerms": ["tiffany studios lamp"],
  "lotStatus": "sold",
  "sort": "-estimatedPrice",
  "maxLots": 1000
}
```

`-estimatedPrice` spans 2009 → 2026 rather than returning only 2026 rows. Remember the ~1,200-row
sold ceiling: run several narrow queries rather than one broad one.

#### A whole sale catalogue, exactly

```json
{
  "startUrls": ["https://www.liveauctioneers.com/catalog/424639_splendid-relics-the-art-of-asian-dynasties/"],
  "maxLots": 0
}
```

`maxLots: 0` removes the cap. Catalogue walks measured **0.00% duplicates over 1,200 contiguous
cards**, so this is the way to get a complete, exact set.

#### The cheap mode

```json
{
  "startUrls": ["https://www.liveauctioneers.com/c/jewelry/"],
  "includeLotDetails": false,
  "includeCategories": false,
  "includeAuctionDetails": false,
  "maxLots": 2000
}
```

You keep every field on the listing card — title, lot number, house, auction, estimates, current bid,
bid count, sale dates, lot location, images, sale flags — and lose the full description, condition
report, dimensions, the category path, creators/materials, and the venue address and buyer's premium.
It drops roughly three batched calls per 50 lots. **The price per lot is identical either way** —
you are billed per lot returned, not per request, so this only buys you time.

***

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `startUrls` | array of strings | `["https://www.liveauctioneers.com/c/art/paintings/"]` | Any LiveAuctioneers search / browse / catalogue / auctioneer / lot URL. **Wins over everything below while it is non-empty.** Clear it to build a query by hand. |
| `source` | enum | `search` | `search` · `category` · `auctionHouse` · `catalogs`. Used only when `startUrls` is empty. All four produce the same row shape. |
| `searchTerms` | array | `["tiffany lamp"]` | `source=search`. Keywords as you would type them: `ming vase`, `rolex submariner`, `roseville pottery`. |
| `categories` | array | `["/c/art/paintings/"]` | `source=category`. A top-level slug, a browse path, a full browse URL, or a numeric category id. |
| `auctionHouses` | array | — | `source=auctionHouse`. Numeric house ids or auctioneer URLs. |
| `catalogUrls` | array | — | `source=catalogs`. Catalogue URLs or bare ids (`424639`). Past catalogues work and carry the prices realized. |
| `lotStatus` | enum | `upcoming` | `upcoming` (bid-able lots) or `sold` (price-results archive, ~1,200-row ceiling per query). Ignored for `catalogs`; overridden by `status=` in a pasted search URL. |
| `sort` | enum | `-publishDate` | `-publishDate` · `-estimatedPrice` · `-relevance` · `saleStart` · `-bidCount`. **A coverage setting, not a cosmetic one** — see gotchas 2 and 3. |
| `includeLotDetails` | boolean | `true` | Full description, condition report, dimensions, shipping weight. One batched call per 50 lots. Same price either way. |
| `includeCategories` | boolean | `true` | Category path, artist/maker, material, origin, style period. One batched call per 50 lots. Same price either way. |
| `includeAuctionDetails` | boolean | `true` | Venue street address, lat/lon, buyer's premium, preview times. One cached call per 20 auctions. Same price either way. |
| `maxLots` | integer | `200` (prefilled `50`) | Run-wide cap and **your cost cap** — billing is per lot. Split evenly across targets, unused share rolls forward. `0` = no cap. |
| `proxyConfiguration` | object | Apify proxy (datacenter) | The cheap rung, because the JSON routes measured 100% through it. |
| `requestConcurrency` | integer | `4` | 1–5; values above 5 are clamped. Kept low on purpose. |

#### Category slugs are validated, not guessed

A sub-category slug is resolved against LiveAuctioneers' live taxonomy. If you mistype one you
get a warning naming the valid children, and the run falls back to the parent instead of
silently returning a category you did not ask for:

```
WARN  category "/c/art/nonexistent-thing/": no sub-category "nonexistent-thing" under "art"
      — using "art" instead. Valid children: drawings, graffiti-and-street-art,
      indigenous-and-tribal-art, mixed-media-and-collages, paintings, photography,
      prints-and-multiples, scrolls-screens-and-fan-paintings, sculptures-and-carvings
```

Top-level slugs: `art` · `collectibles` · `fashion` · `furniture` · `home-and-decor` · `jewelry`.

***

### Pricing

**$0.003 per lot returned — $3 per 1,000 lots.** Charged on the `lot-scraped` event.
No start fee, no monthly platform fee from this Actor.

| Run | Lots | Cost |
|---|---:|---:|
| The prefilled smoke test | 50 | **$0.15** |
| A whole mid-size sale catalogue | 570 | **$1.71** |
| A full sold-archive query at the server ceiling | 1,200 | **$3.60** |
| A deep upcoming sweep at the server ceiling | 10,000 | **$30.00** |

You are charged **for lots delivered to your dataset, and nothing else**:

- Never for a duplicate. Rows are de-duplicated on `itemId` before anything is enriched or pushed,
  so the dataset — and your bill — never holds the same lot twice.
- Never for the enrichment requests. Detail, category and venue lookups are batched (50, 50 and 20
  ids per call) and cached; a 570-lot catalogue costs the same whether those three toggles are on
  or off.
- Never for a retried Incapsula interstitial, and never for the proxy.
- Rows are charged **as they are pushed** (`Actor.pushData(items, 'lot-scraped')`), so if you hit a
  budget cap you get whole rows and stop — not a half-billed dataset.

**`maxLots` is your hard cost cap.** Default 200, prefilled 50, `0` for no cap.

***

### Honest limits

- **~10,000 rows per upcoming query and ~1,200 per sold query. Server-side, unliftable.**
  A `totalFound` of 9,000 on a sold query does not mean 9,000 reachable rows. Narrow and repeat —
  by category, by house, by tighter keyword.
- **On upcoming lots, `currentBid` is 12.1%.** That is the site telling you 87.9% of lots have no
  bids yet, not a scraping failure — every row with a bid has `bidCount ≥ 1`. Use
  `estimateLow`/`estimateHigh` (100%) to plan upcoming work.
- **`conditionReport` is 60.3% on upcoming lots and 50.7% on sold ones.** Many houses never write
  one, and the ones who type `--` or `N/A` into the box are reported as `null` rather than as junk
  text. If your workflow needs condition on every row, this source cannot supply it.
- **`dimensions` is 7.2% and `weight` 4.4%.** Most houses put sizes inside the description prose
  instead. `description` is 100%, so that is where to parse them from.
- **Bidder-only data is not here.** Bidder names, bid histories and reserve amounts sit behind a
  login and this Actor never authenticates. There is no workaround that does not involve logging in,
  which it does not do.
- **`salePrice` is what LiveAuctioneers publishes.** Houses that withhold the hammer price are
  reported as `null`, never as `0`. If a sold run comes back with under 50% `salePrice` fill, the
  Actor says so in the log instead of leaving you to find it on the bill.
- **Estimates and prices are in the lot's own currency** (`currency` column). No FX conversion is
  applied — 3 currencies appeared in the 720-lot sample.
- **Photo URLs are links, not files.** They point at the auction house's originals on
  LiveAuctioneers' CDN; nothing is downloaded or re-hosted.
- **`categoryPath` is as deep as LiveAuctioneers filed the lot, not always four levels.** A table
  lamp comes back `Home & Décor > Lighting > Lamps > Table Lamps`; a lot listed straight under
  `/c/art/paintings/` comes back `Art > Paintings` and stops. 93.3% of rows carry a path at all.
- **A `/price-result/` URL is rejected today, not resolved.** Those pages carry a slug and no lot id,
  and this Actor does not look the slug up — paste the sale catalogue, or run a Sold search, instead.
  (It is resolvable: `jungle_synthesizer`'s Actor does it via a summary endpoint. We have not built
  it yet, and the page says so rather than pretending the URL is impossible.)
- **One site, one schema.** This Actor does not also scrape Invaluable. Invaluable's record shape is
  materially different — opaque `ref` ids instead of numeric lot ids, house photo filenames instead
  of derivable image URLs, HTML descriptions with the estimate baked in, a `catalogView` object
  instead of flat auction fields — and folding it into these columns would produce one half-empty
  dataset instead of two clean ones. It belongs in its own Actor with its own columns.

***

### How it works

Every `www.liveauctioneers.com` **HTML** page sits behind Imperva Incapsula and is unreadable
from a datacenter IP. The **JSON services** behind the single-page app are not, and this Actor only
ever touches those:

| Purpose | Endpoint |
|---|---|
| Keyword / house / status discovery | `search-party-prod…/search/v4/web?parameters=<json>` |
| Category discovery | `search-party-prod…/search/v4/categoryweb?ids=[id]&parameters=<json>` |
| Whole-catalogue walk | `www.liveauctioneers.com/content/catalog/<id>?page&pageSize` |
| Pasted lot URLs | `www.liveauctioneers.com/content/items?lotIds=<csv>` |
| Lot description + condition | `item-api-prod…/spa/small/item-detail?itemIds=<csv>` |
| Category path + maker + medium | `item-api-prod…/spa/small/item-facets?ids=<csv>` |
| Venue address + buyer's premium | `item-api-prod…/spa/small/catalogs?ids=<csv>` |
| Category taxonomy | `category-api-prod…/category-api/subcategory?categoryId=` |

No login, no cookies to mint, no API key, no browser, no CAPTCHA-solving service. It does not touch
any path `www.liveauctioneers.com/robots.txt` disallows — including `/search/?`, `/user/`, `/login/`,
`/dashboard/` and `/item-api/` on that host — and the three API hosts it reads
(`search-party-prod`, `item-api-prod`, `category-api-prod`) publish no robots.txt at all
(HTTP 404, checked 2026-08-12).

#### Transport ladder, measured through the Apify datacenter proxy

No residential, no session pinning, no browser:

| Rung | Result |
|---|---|
| Apify datacenter proxy — 10 contiguous search pages + hydrate + detail + facets + catalogue walk | **14/14 returned rows (100%)** |
| Apify datacenter proxy — 20 concurrent `search-party` requests | **20/20 (100%)** |
| Apify datacenter proxy — 20 concurrent `/content/items` requests | **20/20 (100%)** |
| Apify datacenter proxy — 20 concurrent `item-api` requests | **20/20 (100%)** |
| Same, re-run 2026-08-12 across the five start-URL shapes | **21/21 calls, 0 interstitials** |

That is why the proxy default is the cheap datacenter rung and not residential: paying for
residential bandwidth here buys nothing measurable.

Incapsula does occasionally answer a `/content/*` call with an HTTP **200** carrying a block
page instead of JSON (~1 in 30 observed). "Did the body parse as JSON" is therefore the only
honest success test; a failed parse burns the proxy session and retries on a fresh one. Across the
production runs used to write this page the interstitial rate was **0.0–1.3%**, all recovered.

#### Uniqueness and dedupe

Every lot is de-duplicated on `itemId` **before it is enriched, pushed or billed**, so a drifting
index costs you time, never money. All duplicate rates on this page were measured on **contiguous
page walks**, never sparse offsets — sparse sampling would have shown 0% for every sort key and
hidden the 13.89% that `saleStart` really produces. The mechanism is real and identifiable: the
search index re-ranks between requests, which is why catalogue walks (a fixed, ordered list) measure
0.00% and keyword walks do not.

Across runs, there is no cross-run dedupe: two runs of the same query return the same lots. Use
`sort` and narrower scopes to partition the archive, or de-duplicate on `itemId` at your end.

#### When a run fails

- **Zero rows throws.** A run that returns no lots ends in an error naming the scope and the HTTP
  call counts, rather than finishing green and empty. There is no "successful empty run" here.
- **A bad category slug warns and names the valid children**, then falls back to the parent instead
  of silently scraping a category you did not ask for.
- **A rejected start URL is named in the log** with the reason. If every URL is rejected, the run
  errors with the five accepted URL shapes spelled out.
- **Both server ceilings warn loudly** and set `hitServerResultCap` / `hitSoldAuthWall` in
  `RUN_STATS`, so a truncated sweep is visible in the output, not just in the row count.
- **A thin sold run warns**: under 50% `salePrice` fill logs a warning explaining that houses
  withhold hammer prices.

***

### Who buys these rows

| Buyer | The field they monetize |
|---|---|
| **Antiques and collectibles resellers** | `estimateLow` / `estimateHigh` against `salePrice` — spot under-estimated lots before the sale, and price your own inventory against what the archive actually made. |
| **Appraisers and insurers** | `salePrice` + `categoryPath` + `creators` + `conditionReport` + `images` — comparable sales filtered to one maker, medium or period, with the estimate range next to the result. |
| **Auction aggregators and marketplaces** | `lotClosesAt`, `saleStartAt`, `venueLatitude`/`venueLongitude`, `images` — a normalised, geocoded lot feed with closing times. |
| **Auction-house sales and BD teams** | `auctionHouse`, `venueAddress`, `buyersPremiumPct`, `auctionHouseRating`, `auctionHouseReviewCount` — every competitor running a sale in your category, with their premium and their public rating. |
| **Art-market analysts and data vendors** | `salePrice` + `saleStartAt` + `categoryPath` back to 2009 — a price series per category, per maker, per house. |

***

### Sibling Actors

| Actor | What it is | Why you would use it instead |
|---|---|---|
| [HiBid Auction Scraper](https://apify.com/scrapersdelight/hibid-scraper) | Lots, bids and prices across HiBid (USA & Canada) | The general-estate and farm/equipment end of the market |
| [Proxibid Scraper](https://apify.com/scrapersdelight/proxibid-scraper) | Auction lots, prices and new-lot alerts | Firearms, coins, heavy equipment and collector vehicles |
| [AuctionNinja Estate Sale Scraper](https://apify.com/scrapersdelight/auctionninja-scraper) | Estate-sale lots, bids and new-lot alerts | Estate-sale inventory rather than catalogued fine art |
| [GSA Auctions Scraper](https://apify.com/scrapersdelight/gsa-auctions-scraper) | US federal surplus lots, bids and alerts | Government surplus, not fine art |
| [PublicSurplus Scraper](https://apify.com/scrapersdelight/publicsurplus-scraper) | Government auctions and lots | Municipal and school-district surplus |
| [K-BID Scraper](https://apify.com/scrapersdelight/k-bid-scraper) · [Equip-Bid Scraper](https://apify.com/scrapersdelight/equip-bid-scraper) · [Municibid Scraper](https://apify.com/scrapersdelight/municibid-scraper) | Regional online auction platforms | Midwest estate, industrial and municipal lots |
| [Multi Auction Search](https://apify.com/scrapersdelight/multi-auction-search) | One keyword across storage, surplus and estate sites | You do not know yet which platform has the item |

LiveAuctioneers is where you go for **catalogued fine art, antiques and jewellery with a
prices-realized archive**. The siblings are where you go for everything sold out of a warehouse.

***

### FAQ

**Does this need a LiveAuctioneers account or login?**
No. It never authenticates and collects nothing behind a login. That is also why bidder identities
and bid histories are not in the output — those require an account.

**Can I just paste a URL from my browser?**
Yes, that is the primary input. Search pages, browse categories, sale catalogues, auctioneer pages
and individual lot pages all work, mixed freely in one run.

**Can I get the whole catalogue of the site in one run?**
No. A single query is walkable to about 10,000 upcoming rows or about 1,200 sold rows — a
server-side limit, not a setting. Split by category, house or keyword and run several.

**Do I get charged for rows that get de-duplicated?**
No. De-duplication happens on `itemId` before enrichment and before push, so a duplicate never
reaches the dataset or the bill.

**Two runs of the same query — will I get duplicates?**
Yes. There is no cross-run memory; a query returns the same lots each time. De-duplicate on `itemId`
at your end, or partition the archive with different `sort` keys and narrower scopes.

**Why is `currentBid` empty on so many lots?**
Because 87.9% of upcoming lots have no bids yet — measured on 720 lots. Every row with a bid has
`bidCount ≥ 1`, so an empty `currentBid` is a fact about the lot, not a missed field.

**How far back does the prices-realized archive go?**
To 2009, measured. Which years you actually receive depends on the sort key — see gotcha 2.

**Does it need a proxy? Do I need residential?**
It defaults to the Apify datacenter proxy, and that measured 100% on every route (14/14, and three
separate 20/20 concurrent bursts). Residential buys nothing here.

**What does a run cost?**
$0.003 per lot returned — $3 per 1,000. The prefilled 50-lot run is $0.15. `maxLots` is your cap.

**Can I schedule it?**
Yes — use Apify Schedules to re-run any input on a cadence. Note there is no built-in new-lot
alerting in this Actor; it returns the current state each run.

**Will a run ever succeed with zero rows?**
No. Zero rows throws with the scope and HTTP counts, so a broken query cannot look like an empty
market.

**Something looks wrong — how do I debug it?**
Open `RUN_STATS` in the run's key-value store. It carries the cards seen, lots emitted, measured
duplicate rate, whether either server ceiling was hit, HTTP counts, first-try success rate,
interstitials retried, and the per-field fill percentage for that exact run.

**Can I export to CSV or Excel?**
Yes — the dataset exports as JSON, CSV, Excel, XML, HTML or RSS, and the dataset view ships a
pre-configured lot table.

***

### Legal & fair use

This Actor reads publicly available auction listings from LiveAuctioneers' own public JSON services.
It does not log in, does not solve CAPTCHAs, does not use a CAPTCHA-solving service, and does not
touch any path disallowed by `www.liveauctioneers.com/robots.txt`. Images are referenced by URL and
never downloaded or re-hosted.

Rows describe lots and businesses, but auction-house names, addresses and preview arrangements can
identify individuals in the case of sole traders. **You are responsible for complying with
LiveAuctioneers' Terms of Service and with how you use the data**, including GDPR/UK GDPR, CCPA and
any marketing regime that applies to your outreach (CAN-SPAM, PECR).

LiveAuctioneers® is a trademark of its owner. This Actor is an independent tool and is not
affiliated with, endorsed by or sponsored by LiveAuctioneers, and all trademarks are the property of
their respective owners.

***

### Feedback

Missing a field, or want a filter that is not here? Open an issue on the **Issues** tab — new fields
get added when the source publishes them.

# Actor input Schema

## `startUrls` (type: `array`):

Any liveauctioneers.com URL. Five shapes are recognised and each is routed to the right walker: a search page (https://www.liveauctioneers.com/search/?keyword=tiffany+lamp\&status=online — its keyword, status and sort are read out of the URL and override the fields below), a browse category (https://www.liveauctioneers.com/c/art/paintings/ or https://www.liveauctioneers.com/c/jewelry/asian/6/158/), a sale catalogue (https://www.liveauctioneers.com/catalog/424639\_slug/ — zero pagination drift, measured 0.00% duplicates over 12 contiguous pages), an auctioneer page (https://www.liveauctioneers.com/auctioneer/197/freemans/), or a single lot (https://www.liveauctioneers.com/item/82260058\_slug — pasted lots are fetched 50 at a time). A /price-result/ page carries a slug and no lot id, so it is rejected with a message instead of being guessed at. Each URL is billed only for the lots it actually returns.

## `source` (type: `string`):

'Search' walks a keyword query, 'Category' walks a LiveAuctioneers browse category, 'Auction house' walks every current lot from a given house, and 'Auction catalogues' walks specific sale catalogues you paste in. Catalogues are the only source with zero pagination overlap (measured 0.00% duplicates over 12 contiguous pages) — the search index is re-ranked between requests, so search/category/house runs de-duplicate as they go.

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

Keywords typed exactly as you would into the LiveAuctioneers search box, e.g. 'ming vase', 'rolex submariner', 'tiffany lamp', 'roseville pottery'. Each term is walked page by page until the lot cap is hit, and the cap is split evenly between terms so one busy keyword cannot eat the whole run.

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

A top-level slug (art, collectibles, fashion, furniture, home-and-decor, jewelry), a full browse path ('/c/art/paintings/', '/c/jewelry/rings/'), a full browse URL, or a numeric LiveAuctioneers category id. Sub-category slugs are resolved against the live taxonomy, so a typo is reported with the list of valid children rather than silently widening your query to the parent you did not ask for.

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

Numeric house ids, or auctioneer page URLs such as https://www.liveauctioneers.com/auctioneer/197/freemans/ — the id is read out of the URL. One house returns every lot that house currently has listed (or every sold lot it published, with Sold selected).

## `catalogUrls` (type: `array`):

Full catalogue URLs, e.g. https://www.liveauctioneers.com/catalog/424639\_splendid-relics-the-art-of-asian-dynasties/ , or just the numeric catalogue id (424639). A LOT url (/item/…) does not contain the catalogue id and is skipped with a warning — paste it into Start URLs above instead. Past catalogues work too and carry the prices realized.

## `lotStatus` (type: `string`):

'Upcoming / live' returns lots you can still bid on (current bid, estimates, closing time). 'Sold' reads the price-results archive and fills salePrice (measured 100% fill on a 600-lot sold sample). IMPORTANT: LiveAuctioneers hard-blocks unauthenticated deep paging of sold lots — a single sold query stops at roughly 1,200 rows (measured: page 10 of 120 OK, page 11 returns HTTP 403). Run several narrow sold queries instead of one broad one. Ignored when source = catalogs, and overridden by a status= parameter in a pasted search URL.

## `sort` (type: `string`):

The sort key decides how much the index drifts while you page through it, so this is a coverage setting. Measured over 12 contiguous pages of 120 lots (live index, keyword 'antique'): 'Highest estimate' 0.00% duplicate cards, 'Newest listed' 4.24%, 'Most relevant' 5.07%, 'Sale date' 13.89%. Duplicates are always removed before billing, but a drifting index also SKIPS rows, so deep sweeps should stay on 'Newest listed' (the default) or 'Highest estimate'. On sold queries the sort also decides WHICH 1,200 rows you get: 'Newest listed' returned 2026 only, 'Sale date' returned 2009-2010, 'Highest estimate' spanned 2009-2026. Ignored when source = catalogs.

## `includeLotDetails` (type: `boolean`):

ON (default): one extra batched call per 50 lots adds the auction house's full lot description, condition report (60.3% fill on upcoming lots), dimensions, weight and shipping dimensions. OFF: rows still carry the ~200-character teaser description that comes with the listing card, and conditionReport is empty.

## `includeCategories` (type: `boolean`):

ON (default): one extra batched call per 50 lots adds LiveAuctioneers' own classification — category, sub-category, the full category path up to 4 levels deep (93.3% fill; the depth is whatever the lot was filed under, so 'Home & Decor > Lighting > Lamps > Table Lamps' but also just 'Art > Paintings'), artist/maker (39.6%), material (69.6%), origin and style period, flattened into readable strings rather than the raw nested objects the API returns. OFF: every category column comes back empty.

## `includeAuctionDetails` (type: `boolean`):

ON (default): each unique auction is looked up once (cached, batched 20 at a time) to add the venue street address, city/state/postcode, latitude/longitude (99.4% fill), preview arrangements and the buyer's premium percentage (100% fill). OFF: those columns are empty and a big multi-auction run finishes slightly sooner.

## `maxLots` (type: `integer`):

Hard cap on lots returned this run — this is also your cost cap. 50 lots = $0.15, 1,000 = $3, 10,000 = $30. Set 0 for no cap. When you list several keywords / categories / houses / URLs the cap is split evenly between them (unused share rolls forward). Note the server-side ceilings on top of this: a single upcoming-lot query is walkable to about 10,000 rows and a sold query to about 1,200.

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

The default Apify proxy (datacenter) is enough. Measured through it: 10 contiguous search pages plus the hydrate, detail, category and catalogue routes = 14/14 successful, and three separate 20-request concurrent bursts = 20/20 each. Residential bandwidth buys nothing here, so this Actor does not ask you to pay for it.

## `requestConcurrency` (type: `integer`):

Parallel enrichment requests. Kept low on purpose to stay polite to LiveAuctioneers; values above 5 are clamped and 4 is the measured-comfortable setting.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.liveauctioneers.com/c/art/paintings/"
  ],
  "source": "search",
  "searchTerms": [
    "tiffany lamp"
  ],
  "categories": [
    "/c/art/paintings/"
  ],
  "auctionHouses": [],
  "catalogUrls": [],
  "lotStatus": "upcoming",
  "sort": "-publishDate",
  "includeLotDetails": true,
  "includeCategories": true,
  "includeAuctionDetails": true,
  "maxLots": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "requestConcurrency": 4
}
```

# Actor output Schema

## `items` (type: `string`):

One row per LiveAuctioneers lot: lot title, lot number, auction house, auction title, category path, estimate low/high, current bid, price realized, sale date, lot location, condition report, description, images, venue address and lot URL.

## `runStats` (type: `string`):

This run's own audit: lot cards seen, lots emitted, measured in-run duplicate rate, whether the ~10,000-result server cap or the ~1,200-row sold auth wall was hit, HTTP call count, first-try success rate, Incapsula interstitials retried, and the measured per-field fill percentage for every column.

# 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 = {
    "startUrls": [
        "https://www.liveauctioneers.com/c/art/paintings/"
    ],
    "source": "search",
    "searchTerms": [
        "tiffany lamp"
    ],
    "categories": [
        "/c/art/paintings/"
    ],
    "lotStatus": "upcoming",
    "sort": "-publishDate",
    "includeLotDetails": true,
    "includeCategories": true,
    "includeAuctionDetails": true,
    "maxLots": 50,
    "requestConcurrency": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/liveauctioneers-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 = {
    "startUrls": ["https://www.liveauctioneers.com/c/art/paintings/"],
    "source": "search",
    "searchTerms": ["tiffany lamp"],
    "categories": ["/c/art/paintings/"],
    "lotStatus": "upcoming",
    "sort": "-publishDate",
    "includeLotDetails": True,
    "includeCategories": True,
    "includeAuctionDetails": True,
    "maxLots": 50,
    "requestConcurrency": 4,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/liveauctioneers-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 '{
  "startUrls": [
    "https://www.liveauctioneers.com/c/art/paintings/"
  ],
  "source": "search",
  "searchTerms": [
    "tiffany lamp"
  ],
  "categories": [
    "/c/art/paintings/"
  ],
  "lotStatus": "upcoming",
  "sort": "-publishDate",
  "includeLotDetails": true,
  "includeCategories": true,
  "includeAuctionDetails": true,
  "maxLots": 50,
  "requestConcurrency": 4
}' |
apify call scrapersdelight/liveauctioneers-scraper --silent --output-dataset

```

## MCP server setup

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