# Artprice.com Artist & Artwork Scraper (`artsiom_k/artprice-scraper`) Actor

Scrape Artprice.com's marketplace artworks and artist directory with real per-artist rollup stats and built-in delta mode. No login required.

- **URL**: https://apify.com/artsiom\_k/artprice-scraper.md
- **Developed by:** [Artsiom Kunitsyn](https://apify.com/artsiom_k) (community)
- **Categories:** Other, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 results

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

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## artprice-scraper

Scrapes both **current marketplace artworks** and **artist profiles** from
[Artprice.com](https://www.artprice.com), the world's largest art-market database — via the site's
own public, unauthenticated JSON APIs. No login, no HTML scraping.

### Contents

- [Key features](#key-features)
- [Output](#output)
- [Input](#input)
- [Input examples](#input-examples)
- [Incremental (delta) mode](#incremental-delta-mode)
- [How to scrape Artprice.com](#how-to-scrape-artpricecom)
- [You might also like](#you-might-also-like)
- [FAQ](#faq)

### 🔑 Key features

- **Two entity types, one Actor.** Set `entityType` to `artworks` or `artists`.
- **No detail-page fetch at all.** Artprice's own public marketplace/artist-search APIs already
  return every field this Actor emits — no separate "discover a URL, then fetch its detail page"
  step.
- **Fast, concurrent fetching.** Both marketplace pages and per-artist rollups are fetched in
  parallel (`concurrency` input, default 20) — validated live against Artprice's own endpoints with
  zero blocking at concurrency up to 40 (~46 req/s in testing).
- **Real per-artist rollup stats.** `entityType: "artists"` computes `total_artworks`,
  `avg_price_eur`, and `mediums` from an artist's complete current marketplace listing.
- **Multi-currency pricing.** Every artwork carries its price in all 6 currencies the site itself
  reports (EUR, USD, GBP, CNY, BTC, ETH) — `price`/`currency` is the listing's own native pair,
  `price_eur`/`price_usd`/etc. give every conversion without you having to do it yourself.
- **Full artwork detail for specific artists.** Set `artistIds` on `entityType: "artworks"` to
  fetch every current listing for exactly those artists instead of the full site-wide catalog. Pair
  with an `entityType: "artists"` run to first collect the artist ids you want.
- **Delta mode built in.** Every run classifies each item as `new`, `changed`, `unchanged`, or
  `delisted` against a persisted baseline — pay for what changed, not a full re-scrape every time.
- **`maxItems` defaults to 50** — a fast preview, and what keeps an unconfigured run within Apify's
  automated 5-minute QA check. Clear it (`null`) for a full crawl of the catalog (~70,000 artworks
  or the full ~916,000-artist directory as of this build).

### 📋 Output

One dataset item per artwork or artist, depending on `entityType` — see
[`.actor/dataset_schema.json`](.actor/dataset_schema.json) for the full field list, or the
Output tab's **Artworks** / **Artists** views for a readable table.

**Example artwork record:**

```json
{
  "source": "artprice",
  "entity_type": "artworks",
  "external_id": "2993521",
  "url": "https://www.artprice.com/marketplace/2993521?category=&title=bouquet-a-la-pomme-a-r-306",
  "title": "Bouquet a la pomme (A. R. 306)",
  "artist_id": 22796,
  "artist_name": "Pablo PICASSO",
  "artist_url": "https://www.artprice.com/artist/22796",
  "price": 7500,
  "currency": "eur",
  "price_eur": 7500,
  "price_usd": 8690,
  "price_gbp": 6418,
  "price_cny": 58397,
  "price_btc": 0.1117,
  "price_eth": 3.5612,
  "dealer_name": "PMGALLERY",
  "dealer_url": "https://www.artprice.com/store/PMGALLERY",
  "category": "Ceramics - Glass",
  "material": "Ceramic",
  "condition": "excellent",
  "year": 1956,
  "width_cm": 25.5,
  "height_cm": 26.0,
  "length_cm": 3.0,
  "has_certificate": true,
  "has_signature": false,
  "has_bill": false,
  "description": "Pablo Picasso (1881-1973), Bouquet a la pomme(A.R.306) Unglazed ceramic Signed on the reverse. Diameter: 26x 25.5 cm. Provenance: Private Collection, Israel",
  "image_url": "https://imgprivate2.artprice.com/get/classifieds/.../450/450/....jpg",
  "full_image_url": "https://imgprivate2.artprice.com/get/classifieds/.../1024/1024/....jpg",
  "change_type": "new"
}
```

**Example artist record:**

```json
{
  "source": "artprice",
  "entity_type": "artists",
  "external_id": "22796",
  "url": "https://www.artprice.com/artist/22796/pablo-picasso?cl=en",
  "name": "Pablo PICASSO",
  "birth_year": 1881,
  "death_year": 1973,
  "is_blue_chip": true,
  "total_artworks": 404,
  "avg_price_eur": 6793.01,
  "mediums": "Ceramics - Glass",
  "change_type": "new"
}
```

### 🔧 Input

| Field | Type | Default | Description |
|---|---|---|---|
| `entityType` | string | `artworks` | `artworks` or `artists`. |
| `artistIds` | array | — | `artworks` only. List of Artprice artist ids — fetches every current listing for exactly those artists instead of the full catalog. Not supported for `entityType: "artists"` (no id-based artist lookup exists on this site — see [FAQ](#faq)). |
| `maxItems` | integer | `50` | Stop after pushing this many items. Set to `null` for a full crawl. |
| `mode` | string | `auto` | `auto` / `full` / `incremental` — see [Incremental mode](#incremental-delta-mode). |
| `concurrency` | integer | `20` | How many requests (marketplace pages, or per-artist rollup fetches) to run in parallel. |
| `impersonate` | string | `chrome` | curl\_cffi TLS-impersonation target — not required (bare requests work fine), kept for consistency. |
| `proxyConfiguration` | object | off | Apify Proxy config — not needed; no anti-bot friction found. |

### 📥 Input examples

**Default preview (50 artworks):**

```json
{ "entityType": "artworks" }
```

**Full artist directory:**

```json
{ "entityType": "artists", "maxItems": null }
```

**Full artwork detail for specific artists:**

```json
{ "entityType": "artworks", "artistIds": ["22796"], "maxItems": null }
```

### 🔁 Incremental (delta) mode

`auto` mode does a full scan the first time it runs for a given `entityType`/scope combination, then
only pushes new/changed items on later runs — cutting cost on repeat runs by not re-charging for
items that haven't changed. Only an uncapped run (no `maxItems` limit reached, and no page errors)
can detect delistings or update the baseline.

### 🌐 How to scrape Artprice.com

Artprice's frontend calls its own public JSON APIs directly (`artist_search`, `marketplace`) — this
Actor replicates exactly those calls, the same requests your own browser makes when you browse the
site, just automated and exhaustive. Historical/realized auction prices are a separate, paywalled
product on this site and are **not** covered by this Actor — see the FAQ below.

### 🔗 You might also like

- **[SaatchiArt Artist & Artwork Scraper](https://apify.com/artsiom_k/saatchiart-scraper)**,
  **[Artmajeur](https://apify.com/artsiom_k/artmajeur-scraper)**,
  **[Artsper](https://apify.com/artsiom_k/artsper-scraper)**,
  **[Artfinder](https://apify.com/artsiom_k/artfinder-scraper)**,
  **[Artsy](https://apify.com/artsiom_k/artsy-scraper)**,
  **[Bluethumb](https://apify.com/artsiom_k/bluethumb-scraper)**,
  **[Kunsthaus ARTES](https://apify.com/artsiom_k/kunsthaus-artes-scraper)**,
  **[Ars Mundi](https://apify.com/artsiom_k/ars-mundi-scraper)**, and
  **[Riseart](https://apify.com/artsiom_k/riseart-scraper)** — independent art-marketplace sources
  with the same entity-type/rollup-stats design.

### ❓ FAQ

**Does this Actor give me historical/realized auction prices?**
No. Artprice's core product — its "Cote" historical auction-price index — sits behind both a
paywall and a JS-based bot-check challenge on every page that would show it. This Actor covers what
*is* genuinely public: the artist directory and current marketplace (dealer/gallery for-sale)
listings, via Artprice's own open JSON APIs.

**Can I get full detail on a specific artist's artworks by id?**
Yes for `entityType: "artworks"` — set `artistIds`. Not for `entityType: "artists"`: there is no
id-based artist lookup API on this site (only name-based search), so a specific artist's base
record (name/dates/image) can't be re-fetched by id alone; only a fresh rollup can. Run
`entityType: "artists"` unscoped/with `maxItems` instead to (re)discover artist records.

**Does `total_artworks` on an artist record include sold pieces?**
No — it's the count of that artist's *current* marketplace listings. Sold-item data isn't exposed
by this site's public API (a real, checked finding, not a guess — see the Actor's build docs).

**Does this need a proxy?**
No — no anti-bot friction was found anywhere on the JSON APIs this Actor uses.

# Actor input Schema

## `entityType` (type: `string`):

Scrape current marketplace artworks or artist profiles, via Artprice.com's own public JSON APIs. Each produces a different output shape (see dataset\_schema.json). Artist records include a real rollup (total\_artworks/avg\_price\_eur/mediums) computed from that artist's complete current marketplace listing. Note: historical/realized auction prices are NOT available — that data is paywalled and bot-gated on this site (see README FAQ).

## `artistIds` (type: `array`):

Optional list of Artprice artist ids (the artist\_id field on an artwork record) — fetches every current marketplace listing for exactly those artists instead of the full site-wide catalog. Pair with an entityType="artists" run to first collect the artist ids you want. Gets its own delta-mode tracking scope. Not supported for entityType="artists" — there is no id-based artist lookup API on this site, only name search (see README FAQ).

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

Stop after pushing this many dataset items. Defaults to 50 — a fast, cheap preview, and what keeps an unconfigured run within Apify's automated 5-minute QA check. A full, uncapped run covers the entire marketplace catalog (~70,000 artworks as of this build) or the full artist directory (~916,000 artists claimed) — raise this or clear it for that.

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

"auto" (recommended): full scan on the first run for a given entityType/scope, incremental (new/changed only) afterwards. "full": always push every item and refresh the baseline — schedule this periodically to catch delistings. "incremental": always push only new/changed items. Only an uncapped run can detect delistings or update the baseline.

## `concurrency` (type: `integer`):

How many requests to run in parallel (marketplace pages, or per-artist rollup fetches). Defaults to 20 — validated live against Artprice's own JSON APIs with zero blocking at concurrency up to 40 (~46 req/s in testing). Lower it only if you start seeing errors; there's no anti-bot reason to.

## `impersonate` (type: `string`):

curl\_cffi browser TLS-impersonation target. Defaults to "chrome" internally, though no anti-bot friction was found on the JSON APIs this actor uses even without impersonation. Override only if that stops holding.

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

Apify Proxy configuration. Leave off unless you start seeing blocks from your own IP reputation — no anti-bot friction was found while building this actor.

## Actor input object example

```json
{
  "entityType": "artworks",
  "maxItems": 50,
  "mode": "auto",
  "concurrency": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("artsiom_k/artprice-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("artsiom_k/artprice-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 '{}' |
apify call artsiom_k/artprice-scraper --silent --output-dataset

```

## MCP server setup

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