# Bluethumb.com.au Artist & Artwork Scraper (`artsiom_k/bluethumb-scraper`) Actor

Bluethumb.com.au artist & artwork scraper with real per-artist sold/available/total counts read straight from each artist's profile page, no per-artwork fan-out, plus delta mode.

- **URL**: https://apify.com/artsiom\_k/bluethumb-scraper.md
- **Developed by:** [Artsiom Kunitsyn](https://apify.com/artsiom_k) (community)
- **Categories:**
- **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

## bluethumb-scraper

Scrapes both **artworks** and **artist profiles** from [Bluethumb.com.au](https://bluethumb.com.au),
Australia's largest online art marketplace — including real per-artist sold/available/total artwork
counts read straight from each artist's own profile page, no extra fetches needed.

### Contents

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

### 🔑 Key features

- **Two entity types, one Actor.** Set `entityType` to `artworks` or `artists` — no need for two
  separate scrapers to build a full picture of an artist and their work.
- **Real per-artist rollup stats, with no per-artwork fan-out.** `total_artworks`,
  `sold_artworks`, and `available_artworks` are all read directly from a single request to the
  artist's own profile page — Bluethumb computes these server-side already. Unlike some other art
  marketplace scrapers in this collection, filtering artists by `minSoldArtworks` costs nothing
  extra here.
- **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.
- **Exhaustive when you ask for it.** With no `startUrls`, discovery walks the site's own sitemaps —
  every artwork (~500K) and every artist (~19K) — but `maxItems` defaults to 50 (a fast preview, and
  what keeps an unconfigured run within Apify's automated 5-minute QA check), so clear it (`null`)
  for a real full crawl.
- **Confirmed-dead listings are never re-fetched.** A removed artwork or artist doesn't return a 404
  or 410 on this site — it silently serves a generic fallback page with HTTP 200. This Actor detects
  that from the page's own content (a missing product/profile data block, not a status code) and
  persists it, so a future run skips it without a wasted request.

### 📋 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": "bluethumb",
  "entity_type": "artworks",
  "external_id": "a-girl-and-her-cat-1137403",
  "url": "https://bluethumb.com.au/kimmagee/Artwork/a-girl-and-her-cat-1137403",
  "title": "A Girl and Her Cat",
  "artist_name": "kim magee",
  "artist_url": "https://bluethumb.com.au/kimmagee",
  "price": 350.0,
  "currency": "AUD",
  "availability_status": "for_sale",
  "medium": "Acrylic Paint",
  "category_tags": "Animal Cat People & Portrait",
  "width_cm": 60.0,
  "height_cm": 75.0,
  "depth_cm": 2.0,
  "weight_kg": 3.0,
  "change_type": "new"
}
```

**Example artist record:**

```json
{
  "source": "bluethumb",
  "entity_type": "artists",
  "external_id": "kimmagee",
  "url": "https://bluethumb.com.au/kimmagee",
  "name": "kim magee",
  "state": "VIC",
  "country": "AU",
  "total_artworks": 411,
  "verified_artworks": 32,
  "sold_artworks": 168,
  "available_artworks": 28,
  "followers": 41,
  "tier": "starter",
  "change_type": "new"
}
```

Results can be downloaded as JSON, CSV, or Excel from the Console's Output tab, or pulled via the
Apify API/dataset endpoint.

**Known gaps:**

- `awards`/`exhibitions`/`education`/`galleries`/`prizes` exist on Bluethumb's own artist data but
  were empty on every artist sampled while building this Actor (7 artists, a mix of catalog sizes) —
  not currently exposed as output fields since no populated example was ever seen to confirm the
  real shape. May be revisited if a customer needs them.
- `category_tags` and dimensions/weight are parsed from the artwork page's own meta description tag
  (Bluethumb doesn't expose them as separately labeled fields) — reliable on every artwork sampled,
  but a page missing that tag entirely would leave these fields `null` rather than erroring.

### ⚙️ Input

See [`.actor/input_schema.json`](.actor/input_schema.json) for the full JSON schema.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `entityType` | String | `artworks` | `artworks` or `artists`. |
| `startUrls` | Array of strings | *(none)* | Specific artist or artwork URLs to scrape directly, instead of discovering via the full site sitemap. No persisted delta tracking across runs for this scope. |
| `maxItems` | Integer | `50` | Stop after pushing this many dataset items. Clear it (`null`) for a full, uncapped crawl. |
| `minSoldArtworks` | Integer | `0` | Artists only. Only push artist records with at least this many sold artworks. Artists are still fully tracked internally either way; this only filters what's pushed. |
| `mode` | String | `auto` | `auto` (recommended): full scan on the first run, incremental after. `full`: always push every item and refresh the baseline. `incremental`: always push only new/changed items. |
| `impersonate` | String | `chrome` (internal) | curl\_cffi TLS-impersonation target — a hedge, not a requirement (see FAQ). |
| `proxyConfiguration` | Object | `{"useApifyProxy": false}` | Apify Proxy config. Off by default — no anti-bot friction was found on any route this Actor uses. |

### 🧪 Input examples

**Full artwork catalog scan** (exhaustive, every artwork's detail page is fetched):

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

**Full artist directory, with rollup stats:**

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

**Artists with at least one sold artwork only:**

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

**Scheduled tracking run** — full, uncapped run (`maxItems` cleared — required for the baseline to
save and delistings to be detected):

```json
{ "entityType": "artworks", "mode": "incremental", "maxItems": null }
```

### 🔄 Incremental (delta) mode

Every run classifies each item as `new`, `changed` (price or availability moved, for artworks;
sold/available/total counts moved, for artists), `unchanged`, or `delisted`, using a state baseline
persisted in a named Apify Key-Value Store scoped to `entityType`.

- `mode: auto` (default) — first run for a scope pushes everything (`full`); later runs push only
  `new`/`changed`/`delisted` (`incremental`).
- A `startUrls`-scoped run is always partial and never updates the baseline.
- A confirmed-gone artwork/artist is recorded and never fetched again on any future run, regardless
  of `mode` or scope. Doesn't count toward the baseline-save/delisted-detection gate, since it's a
  trustworthy, already-understood outcome rather than an ambiguous failure.

### 🚀 How to scrape Bluethumb.com.au

1. Open the Bluethumb Artist & Artwork Scraper in Apify Console and go to the **Input** tab.
2. Pick `entityType` (`artworks` or `artists`).
3. `maxItems` defaults to 50 (a quick preview) — clear it (set to `null`) for a full, uncapped run.
4. Click **Start**.
5. When the run finishes, browse results in the **Output** tab, or download as JSON/CSV/Excel, or
   fetch them via the API.
6. To track over time instead of scraping once: create a **Schedule** with `mode: auto` — the
   first run does a full scan, every run after only bills what actually changed.

### 🔗 You might also like

- **[SaatchiArt Artist & Artwork Scraper](https://apify.com/artsiom_k/saatchiart-scraper)**,
  **[Artmajeur Artist & Artwork Scraper](https://apify.com/artsiom_k/artmajeur-scraper)**,
  **[Artsper Artist & Artwork Scraper](https://apify.com/artsiom_k/artsper-scraper)**,
  **[Artfinder Artist & Artwork Scraper](https://apify.com/artsiom_k/artfinder-scraper)** — four
  more independent art marketplace sources, same entity-type/rollup-stats design.
- **[Artsy Artist, Artwork & Gallery Scraper](https://apify.com/artsiom_k/artsy-scraper)** — a
  sixth, independent art marketplace source, plus a real dealer/gallery angle this collection
  otherwise doesn't have.
- **[Riseart Artist & Artwork Scraper](https://apify.com/artsiom_k/riseart-scraper)** — a seventh,
  independent art marketplace source, built entirely on the site's own public GraphQL search API
  (no HTML scraping, no per-item detail fetch), with a real per-artist rollup (total artworks, avg
  price, for-sale vs. enquire-only split).
- **[Kunsthaus ARTES Artist & Artwork Scraper](https://apify.com/artsiom_k/kunsthaus-artes-scraper)**
  — an eighth, independent art marketplace source (German gallery), with a real four-state
  availability signal (for sale, price-on-request, reserved, sold) read from the site's own
  schema.org microdata.
- **[Ars Mundi Artist & Artwork Scraper](https://apify.com/artsiom_k/ars-mundi-scraper)** — a
  ninth, independent art marketplace source (a sibling German gallery running the same underlying
  platform as Kunsthaus ARTES), also selling jewelry and decorative objects alongside
  paintings/sculptures.
- **[Artprice.com Artist & Artwork Scraper](https://apify.com/artsiom_k/artprice-scraper)** — a
  tenth, independent art marketplace source, built on Artprice.com's own public unauthenticated
  JSON APIs (artist directory + current marketplace listings), with real per-artist rollup stats
  and multi-currency pricing (EUR/USD/GBP/CNY/BTC/ETH) on every artwork.

### ❓ FAQ

**Is it legal to scrape Bluethumb.com.au?** It's legal to collect publicly available marketplace
data such as artwork listings, prices, and public artist profile information. Scrape it only with a
legitimate purpose under applicable privacy law.

**How do I get only new/changed items?** Use `mode: auto` (or `incremental`) on a schedule — see
[Incremental mode](#incremental-delta-mode).

**Does this Actor use Bluethumb's internal search API?** No — that endpoint
(`/api/listings?...`) is genuinely Cloudflare-challenged, confirmed while building this Actor with
both a plain request and browser TLS impersonation. Not needed anyway: the site's own sitemaps are
exhaustive for both artworks and artists, and every route this Actor actually uses returned clean
responses in testing.

### Search keywords

bluethumb scraper, australian art marketplace scraper, artist data scraper, artwork data scraper,
art price data, art market analytics, art collector data feed

# Actor input Schema

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

Scrape artworks or artist profiles. Each produces a different output shape (see dataset\_schema.json).

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

Optional list of specific Bluethumb artist (https://bluethumb.com.au/{slug}) or artwork (https://bluethumb.com.au/{artist-slug}/Artwork/{artwork-slug}) URLs to scrape directly, instead of discovering via the full site sitemap — use whichever kind matches entityType. A startUrls-scoped run cannot detect delistings or update the incremental baseline.

## `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 sitemap crawl covers the entire site (~500,000 artworks, or the full ~19,000-artist directory as of this build) — raise this or clear it (set to null) for that.

## `minSoldArtworks` (type: `integer`):

Only push artist records with at least this many sold artworks (rollup field sold\_artworks, read straight from Bluethumb's own server-computed counts — no extra cost to filter on here, unlike some other actors in this collection). Set to 1 to skip artists who have never sold anything. Artists are still fully tracked internally either way (delta baseline, delisted-detection), so this only filters what gets pushed to the dataset. Ignored when entityType is "artworks".

## `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 a plain, unscoped sitemap crawl (no startUrls) can detect delistings or update the baseline.

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

How many artwork/artist detail pages to fetch in parallel. Defaults to 20 — validated live against bluethumb.com.au with zero blocking at concurrency 10/25/40 (only the site's already-known ~4-6% transient HTTP 504 rate, retried automatically). 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 — a hedge against Cloudflare bot-management the site runs on at least one route (its internal search API), even though every route this actor actually uses worked cleanly without impersonation in testing. 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 on any route this actor uses while building it.

## Actor input object example

```json
{
  "entityType": "artworks",
  "maxItems": 50,
  "minSoldArtworks": 0,
  "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/bluethumb-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/bluethumb-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/bluethumb-scraper --silent --output-dataset

```

## MCP server setup

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