# Victoria & Albert Museum Collections Scraper (`ninhothedev/vam-museum-scraper`) Actor

$0.35/1K 🔥 V\&A Museum Scraper! Extract artworks, objects, artists, dates & images from London's Victoria and Albert Museum collection. No key. JSON, CSV, Excel or API in seconds. Power an art catalog or culture app ⚡

- **URL**: https://apify.com/ninhothedev/vam-museum-scraper.md
- **Developed by:** [ninhothedev](https://apify.com/ninhothedev) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 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

## Victoria & Albert Museum Collections Scraper

Scrape the **Victoria & Albert Museum (V\&A)** — the world's largest museum of
applied arts, decorative arts and design — straight from its free, key-less
[Collections API v2](https://api.vam.ac.uk/v2). Get structured objects with
makers, materials, techniques, dates, places of origin, dimensions and
high-quality **IIIF images**.

No API key. No login. ~**$0.50 per 1,000 objects** in Apify platform usage.

### What you get

Every object is one clean, flat record:

| Field | Description |
|-------|-------------|
| `system_number` | V\&A internal id (e.g. `O72610`) |
| `accession_number` | Museum accession number |
| `title` | Object title |
| `object_type` | e.g. Chair, Teapot, Kimono |
| `maker` / `maker_association` | Designer/maker and their role |
| `date_text` | Production date |
| `brief_description` | Short description (≤2000 chars) |
| `physical_description` | Detailed physical description (≤3000, detail only) |
| `materials` / `techniques` / `categories` | Lists (detail only) |
| `place_of_origin` | Where it was made (detail only) |
| `dimensions` | Compact dimension string (detail only) |
| `collection_code` | V\&A collection code |
| `on_display` / `gallery` | Whether it is on display and where |
| `image_id` / `image_url` / `has_image` | IIIF image id + a ready 400×400 image URL |
| `url` | Public V\&A page for the object |
| `source` | Always `vam` |
| `scraped_at` | ISO timestamp |

Image URLs use the V\&A IIIF server, e.g.
`https://framemark.vam.ac.uk/collections/{image_id}/full/!400,400/0/default.jpg`
(verified to resolve). Change the size segment for larger renders.

### Modes

- **search** — run one or more queries (`chair`, `teapot`, `kimono`, a maker's
  name, a keyword…) with optional material / year / images filters. Each hit is
  optionally enriched with its full object record.
- **objects** — pass explicit V\&A system numbers and get their full records.

### Input

| Field | Type | Default | Notes |
|-------|------|---------|-------|
| `mode` | select | `search` | `search` or `objects` |
| `queries` | array | `["chair","teapot","kimono"]` | Search terms (search mode) |
| `systemNumbers` | array | `[]` | System numbers (objects mode) |
| `materialFilter` | string | — | AAT material id, e.g. `AAT12849` |
| `yearFrom` / `yearTo` | int | — | Production-year range |
| `withImagesOnly` | bool | `false` | Only objects that have an image |
| `enrichDetails` | bool | `true` | Fetch full object records (richer, slower) |
| `maxItems` | int | `200` | Hard cap (max 3000) |

#### Example

```json
{
  "mode": "search",
  "queries": ["kimono", "art deco"],
  "yearFrom": 1900,
  "yearTo": 1940,
  "withImagesOnly": true,
  "enrichDetails": true,
  "maxItems": 500
}
```

### Use cases

- **Art & design datasets** for ML, catalogues and analysis
- **Design research** — trace materials, techniques and makers over time
- **Education** — build teaching resources from a world-class collection
- **Digital exhibitions** — power galleries with IIIF imagery and rich metadata

### How this differs from my other museum scrapers

This actor is dedicated to the **V\&A — applied arts and design** (furniture,
fashion, ceramics, textiles, metalwork, jewellery, product design). It is a
different institution and API from my other museum actors:

- [Met Museum Scraper](https://apify.com/ninhothedev/met-museum-scraper) — The
  Metropolitan Museum of Art (New York), encyclopedic fine-art collection.
- [Museum Collections Scraper](https://apify.com/ninhothedev/museum-collections-scraper)
  — Europeana / Smithsonian / Art Institute of Chicago aggregators.
- [Cleveland Art Scraper](https://apify.com/ninhothedev/cleveland-art-scraper)
  — Cleveland Museum of Art open-access collection.
- [Europeana Scraper](https://apify.com/ninhothedev/europeana-scraper) —
  pan-European cultural-heritage aggregator.

If you want **design and decorative-arts** objects specifically, use this one.

### Data licensing & terms

Data comes from the public V\&A Collections API. The V\&A provides its collection
data and IIIF images primarily for **personal, educational and research
(non-commercial) use**; many images are made available for creative and academic
reuse, but rights vary object-by-object and some records carry third-party
rights or content warnings. **You are responsible for checking the rights and
credit line of each object** on its V\&A page before reuse, and for complying with
the V\&A API terms. This actor is an independent tool and is not affiliated with
or endorsed by the Victoria & Albert Museum.

### Run locally

```bash
pip install -r requirements.txt
python -m src.main
python3 tests/test_mapper.py   # offline smoke tests
```

# Actor input Schema

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

How to collect objects. 'search' runs your queries (with optional filters) against the V\&A search API. 'objects' fetches full records for the exact system numbers you provide.

## `queries` (type: `array`):

Free-text search terms (object type, maker, keyword). Each query is paged through until maxItems is reached. Used only in 'search' mode.

## `systemNumbers` (type: `array`):

Explicit V\&A system numbers (e.g. 'O72610') to fetch full object records for. Used only in 'objects' mode.

## `materialFilter` (type: `string`):

Optional AAT material id to narrow search results (e.g. 'AAT12849' for plywood). Applied as id\_material. Search mode only.

## `yearFrom` (type: `integer`):

Optional earliest production year to include (year\_made\_from). Search mode only.

## `yearTo` (type: `integer`):

Optional latest production year to include (year\_made\_to). Search mode only.

## `withImagesOnly` (type: `boolean`):

If true, only return objects that have an IIIF image. In search mode this filters the query; in objects mode it drops image-less records.

## `enrichDetails` (type: `boolean`):

If true (default), each search hit is enriched with its full object record (physical description, materials, techniques, categories, place, dimensions). Slower but far richer. Search mode only.

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

Hard cap on the number of objects to scrape across all queries or system numbers.

## Actor input object example

```json
{
  "mode": "search",
  "queries": [
    "chair",
    "teapot",
    "kimono"
  ],
  "systemNumbers": [],
  "withImagesOnly": false,
  "enrichDetails": true,
  "maxItems": 200
}
```

# Actor output Schema

## `overview` (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 = {
    "queries": [
        "chair",
        "teapot",
        "kimono"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ninhothedev/vam-museum-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 = { "queries": [
        "chair",
        "teapot",
        "kimono",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ninhothedev/vam-museum-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 '{
  "queries": [
    "chair",
    "teapot",
    "kimono"
  ]
}' |
apify call ninhothedev/vam-museum-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ninhothedev/vam-museum-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/mOq2FwfuL5M7FHHHn/builds/8d4nVNhlfEiDqfybP/openapi.json
