# Chrono24 Watch Scraper (`devilscrapes/chrono24-watch-scraper`) Actor

Scrape Chrono24 luxury watch listings: brand, model, reference number, price, condition, year, and seller location. Residential-proxy powered — we handle the blocks.

- **URL**: https://apify.com/devilscrapes/chrono24-watch-scraper.md
- **Developed by:** [DevilScrapes](https://apify.com/devilscrapes) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

<p align="center">
  <img src=".actor/icon.svg" width="160" alt="Chrono24 Watch Scraper icon">
</p>

## Chrono24 Watch Scraper

**$2.50 / 1 000 results** — pay only for results, no credit card to try.

Scrape Chrono24 luxury watch listings by brand or specific model page:
model name, reference number, price, condition, year of production, and
seller location. Point it at a brand slug and it does the dirty work so
your dataset stays clean.

### 🔎 What this scrapes

Chrono24 brand and model index pages, plus (optionally) each listing's
detail page — one row per watch listing, with brand, model, reference
number, price, condition, year, seller location, and a canonical
listing URL.

### 🔥 Features

- Discover listings by brand slug (`rolex`, `omega`, `patek-philippe`, …)
  or scope to a specific model taxonomy page.
- Optional detail-page enrichment for reference number, condition,
  year of production, and seller country/city.
- 🌐 We rotate residential proxies through Apify Proxy on every block —
  fresh session, fresh exit IP, pinned to your chosen country.
- 🔁 We retry with exponential backoff and rotate browser fingerprints
  when the target pushes back.
- 🧊 Clean, Pydantic-validated rows with stable ids and ISO-8601
  timestamps — dedup'd automatically within a run.

### 💡 Use cases

- Watch dealers and appraisers tracking active listing pools for a
  brand or reference.
- Insurers building resale/replacement-value comparables.
- Market researchers monitoring pricing trends across watch brands.

### ⚙️ How to use it

1. Add one or more brand slugs (or specific model URLs) to the input.
2. Choose whether to enrich each listing with its detail page.
3. Run the Actor — results land in the default dataset.

### 📥 Input

| Field | Type | Default | Description |
|---|---|---|---|
| `brands` | array of strings | `[]` | Chrono24 brand URL slugs, e.g. `"rolex"`. At least one of `brands` / `modelUrls` is required. |
| `modelUrls` | array of strings | — | Specific Chrono24 model taxonomy pages to scope discovery. |
| `maxResultsPerTarget` | integer | `120` | Cap on rows collected per brand or model URL. |
| `enrichDetails` | boolean | `true` | Fetch each listing's detail page for reference/condition/year/location. |
| `proxyCountryCode` | string | `"US"` | ISO-3166 alpha-2 pinned to the proxy session. |
| `runTimeoutSeconds` | integer | `1200` | Wall-clock budget for the run. |
| `proxyConfiguration` | object | RESIDENTIAL | Apify Proxy configuration. |

```json
{
  "brands": ["rolex"],
  "maxResultsPerTarget": 120,
  "enrichDetails": true,
  "proxyCountryCode": "US",
  "runTimeoutSeconds": 1200,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### 📤 Output

One dataset row per watch listing:

```json
{
  "id": "47176512",
  "brand": "rolex",
  "model_name": "Rolex Datejust Datejust Factory Grey Tapestry Dial Steel 36mm Jubilee 16234",
  "reference_number": "16234",
  "price": 6999.0,
  "currency": "USD",
  "condition": "Very good",
  "year_of_production": 1990,
  "seller_country": "United States",
  "seller_city": "New York",
  "image_url": "https://cdn2.chrono24.com/images/uhren/47176512-abc123.jpg",
  "listing_url": "https://www.chrono24.com/rolex/datejust--id47176512.htm",
  "source_target": "rolex",
  "scraped_at": "2026-08-10T14:32:07.512381+00:00"
}
```

### 💰 Pricing

Pay-Per-Event — you're only charged for what lands in your dataset.

| Event | Price |
|---|---|
| Actor start | $0.01 per run |
| Result scraped | $0.00249 per listing row |

At 1,000 rows: **$2.50** — no subscription, no per-page fees.

### 🚧 Limitations

- Free-text search on Chrono24 is not a usable data source (client-rendered);
  discovery is by brand slug or model taxonomy page only.
- Only the `.com` English/US storefront is covered in this version.
- No price-history or sold-listing archives — active listings only.
- No seller-profile enrichment (ratings, response time, inventory count).

### ❓ FAQ

**Can I scrape a specific model instead of a whole brand?**
Yes — pass a Chrono24 model taxonomy URL (`--mod<N>.htm`) in `modelUrls`.

**Why is a field `null`?**
Enrichment fields (`reference_number`, `condition`, `year_of_production`,
`seller_country`, `seller_city`) are only populated when `enrichDetails`
is `true`, and are best-effort per listing — one unparseable detail page
never blocks the rest of your run.

**Do I need my own proxy?**
No — Apify Proxy (residential) is wired in by default.

### 🗣️ Your feedback

Found a bug or have a feature request? Open an issue via
[apify.com/DevilScrapes](https://apify.com/DevilScrapes) — we read
every message and ship fixes fast.

# Actor input Schema

## `brands` (type: `array`):

Chrono24 brand URL slugs, e.g. "rolex", "omega", "patek-philippe". At least one of Brands / Model URLs is required.

## `modelUrls` (type: `array`):

Specific Chrono24 model taxonomy pages to scope discovery further than a whole brand, e.g. https://www.chrono24.com/rolex/datejust--mod123.htm.

## `maxResultsPerTarget` (type: `integer`):

Cap on rows collected per brand or model URL (one page = 120; cap of 2400 = 20 pages).

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

Fetch each listing's detail page for reference number, condition, year of production, and seller location. Off = cheaper, index-page fields only.

## `proxyCountryCode` (type: `string`):

ISO-3166 alpha-2 pinned to the Apify proxy session, e.g. US.

## `runTimeoutSeconds` (type: `integer`):

Wall-clock budget; the run stops discovering new targets past this and finishes in-flight work.

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

Mandatory-by-default RESIDENTIAL proxy — Chrono24 fronts a Cloudflare managed challenge that may still target datacenter-class IPs.

## Actor input object example

```json
{
  "brands": [
    "rolex"
  ],
  "maxResultsPerTarget": 120,
  "enrichDetails": true,
  "proxyCountryCode": "US",
  "runTimeoutSeconds": 1200,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

All dataset items as JSON.

## `datasetItemsCsv` (type: `string`):

Same data exported to CSV.

## `datasetView` (type: `string`):

Open the run dataset in the Console.

# 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 = {
    "brands": [
        "rolex"
    ],
    "proxyCountryCode": "US",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("devilscrapes/chrono24-watch-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 = {
    "brands": ["rolex"],
    "proxyCountryCode": "US",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("devilscrapes/chrono24-watch-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 '{
  "brands": [
    "rolex"
  ],
  "proxyCountryCode": "US",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call devilscrapes/chrono24-watch-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,devilscrapes/chrono24-watch-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/zGkVRWACx0aJqvXRB/builds/PD6bwbQZhzWt2b9oV/openapi.json
