# Chrono24 Scraper — Luxury Watch Listings & Dealer Data (`crawloop/chrono24-scraper`) Actor

Scrape Chrono24 watch listings by keyword, brand, or URL. Export price, reference, condition, box & papers, shipping, seller rating, and specs as JSON for dealers, appraisers, and pricing apps.

- **URL**: https://apify.com/crawloop/chrono24-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** E-commerce, Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 7 total users, 2 monthly users, 98.2% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.29 / 1,000 watch listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Chrono24 Scraper — Luxury Watch Listings & Dealer Data

> **Disclaimer:** Unofficial tool — not affiliated with, sponsored by, or endorsed by Chrono24 or its affiliates. Data is read from publicly accessible pages only. No login. You are responsible for complying with applicable law (including GDPR where personal data appears) and the site’s terms. No warranty on accuracy or availability. Provided for informational and research use.

**Chrono24 scraper** for the world's largest **luxury watch** marketplace. Pull live listings by keyword, brand, model page, or URL — asking price, reference number, condition, box & papers, shipping, seller rating, and full spec sheets — as JSON. Use it as a **Chrono24 API alternative** from Python, Node.js, or MCP. HTTP-first (`curl_cffi`), no browser.

This Actor is **luxury resale**, not a TCG/collectibles suite. For the public market price on the same reference, pair with [WatchCharts Scraper](https://apify.com/crawloop/watchcharts-scraper). For completed sales on another marketplace, pair with [eBay Sold Listings Scraper](https://apify.com/crawloop/ebay-sold-listings-scraper).

### When to use

- Monitor **Rolex / Patek / AP** inventory and asking prices across dealers
- Find **undervalued references** (box & papers, certified, private sellers)
- Build a **dealer map**: rating, review count, city, country, Chrono24 Direct vs private
- Feed appraisal, insurance, and grey-market dashboards with typed numeric fields
- Fast **card-only** runs for daily price watches; optional detail fetch for spec sheets

**When not to use:** Chrono24 does not publish a public sold-archive API. This Actor scrapes **live listings**, not historical sold prices.

### Monitor new listings and price drops

Turn on **`monitorMode`** with an [Apify Schedule](https://docs.apify.com/platform/schedules) (hourly or daily) to get **only new listings and price drops** since the last run. The **first run** is a baseline: it saves the current search snapshot and returns up to `maxItems` rows like a normal scrape. Later runs scan all pages (`maxPages`) but charge and push only changes; unchanged listings update monitor state silently. Use a separate **`monitorStoreName`** for each watch or query you track.

```json
{
  "searchQueries": ["Rolex Submariner"],
  "monitorMode": true,
  "monitorStoreName": "chrono24-monitor-rolex-sub"
}
```

Card-only mode (`fetchDetails: false`) keeps scheduled runs cheap; detail pages open only for new listings or price drops when details are enabled. In monitor mode, search queries sort by **newest** unless you pick another order; if you paste `startUrls`, sort them by newest too so the watch stays stable.

### Key features

- **Keywords, brands, or URLs** — mix search, brand catalog, model pages, and listing URLs
- **Human filters** — price, year range, condition, movement, case material, dial, gender, seller type, country, certified, box & papers
- **Dealer fields** — name, type, rating, reviews, city, country (detail mode)
- **Box & papers booleans** plus `scopeOfDelivery`
- **Numeric shipping** (`shippingAmount`) rather than label-only
- **HTTP-first** — Chrome TLS via `curl_cffi`. One Chromium unlock if Cloudflare blocks that page; if the unlock fails, the run stops

### Input

| Field | Description |
| --- | --- |
| `searchQueries` | Keywords (Rolex Daytona, 126610LN, Nautilus) |
| `brands` | Brand names or slugs (`Rolex`, `patek-philippe`) |
| `startUrls` | Search / brand / model / listing URLs |
| `maxItems` / `maxPages` | Caps |
| `fetchDetails` | `true` = spec sheet + seller (default) |
| `currency` | USD, EUR, GBP, CHF, … |
| Filters | `priceMin` / `priceMax`, `yearFrom` / `yearTo`, `usedOrNew`, `condition`, `movement`, `caseMaterial`, `dialColor`, `gender`, `sellerType`, `countries`, `certified`, `boxAndPapers`, `sortBy` |
| `proxyConfiguration` | Default: Apify Proxy **RESIDENTIAL** |
| `forceBrowser` | Off. One Chromium unlock if a page is blocked; the run stops if that unlock fails |

#### Example — Rolex Daytona cards

```json
{
  "searchQueries": ["Rolex Daytona"],
  "maxItems": 50,
  "fetchDetails": false,
  "currency": "USD",
  "sortBy": "newest"
}
```

#### Example — certified Submariners with box & papers

```json
{
  "brands": ["Rolex"],
  "searchQueries": ["126610LN"],
  "certified": true,
  "boxAndPapers": "box_and_papers",
  "priceMin": 8000,
  "priceMax": 20000,
  "maxItems": 100,
  "fetchDetails": true
}
```

### Output

One dataset row per listing. Card mode is ~15 fields; detail mode adds specs and seller.

| Field | Description |
| --- | --- |
| `listingId` / `url` | Chrono24 id and canonical URL |
| `title` / `brand` / `model` / `referenceNumber` | Identity |
| `priceValue` / `currency` | Numeric asking price |
| `shippingAmount` / `shippingLabel` | Shipping |
| `year` / `condition` / `movement` / `caliber` | Specs (detail) |
| `caseDiameterMm` / `caseMaterial` / `dialColor` | Case / dial |
| `hasBox` / `hasPapers` / `certified` | Delivery & authenticity |
| `sellerName` / `sellerType` / `sellerRating` / `sellerReviewCount` | Dealer |
| `sellerCity` / `sellerCountry` / `countryCode` | Location |
| `images` | Photo URLs |
| `sold` / `reserved` | Listing status when shown |

```json
{
  "listingId": "47341084",
  "url": "https://www.chrono24.com/rolex/submariner-date-116610ln--id47341084.htm",
  "title": "Rolex Submariner Date",
  "brand": "Rolex",
  "referenceNumber": "116610LN",
  "priceValue": 11495,
  "currency": "USD",
  "shippingAmount": 99,
  "hasBox": true,
  "hasPapers": true,
  "sellerName": "Pacific Watch Co.",
  "sellerRating": 4.9,
  "sellerCountry": "United States of America",
  "countryCode": "US"
}
```

### Use cases

- Daily **reference price** pulls for Daytona, Submariner, Nautilus, Royal Oak
- Grey-market **spread** vs boutique / other marketplaces after shipping
- Insurance **replacement value** from full spec sheets
- Dealer **sourcing** — private sellers, certified only, or Chrono24 Direct

### Integration

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawloop/chrono24-scraper').call({
  searchQueries: ['Rolex Daytona'],
  maxItems: 25,
  fetchDetails: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient(token)
run = client.actor("crawloop/chrono24-scraper").call(
    run_input={"searchQueries": ["Rolex Daytona"], "maxItems": 25, "fetchDetails": True}
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items[0])
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/crawloop~chrono24-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries":["Rolex Daytona"],"maxItems":25,"fetchDetails":true}'
```

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp). Connect your Apify account, then call `crawloop/chrono24-scraper`.

Example prompts:

- "Run Chrono24 Scraper for Rolex Daytona, max 30 listings, and return title, reference, price, and seller country as JSON"
- "Scrape certified Submariner 126610LN listings with box and papers under 18000 USD"
- "After Chrono24 asking prices for 126610LN, compare the market price with WatchCharts Scraper, then pull eBay sold comps with eBay Sold Listings Scraper"

### Next step

Live Chrono24 asks are one side of the book. For the public market price and retail price on the same reference, run [WatchCharts Scraper](https://apify.com/crawloop/watchcharts-scraper). For **completed sale comps** on a public marketplace, run [eBay Sold Listings Scraper](https://apify.com/crawloop/ebay-sold-listings-scraper) on the same reference numbers.

### FAQ

**Do I need start URLs?** No. Keywords and/or brand names are enough. URLs are optional and auto-classified.

**Card mode vs detail mode?** `fetchDetails: false` is faster (search cards only). Enable details for reference, year, movement, seller rating, and box/papers.

**Why residential proxy?** Chrono24 often challenges datacenter IPs. The default input uses Apify Proxy RESIDENTIAL.

**Sold history?** Not in v1. Chrono24 does not expose a public sold-price archive on listing HTML.

### Related Actors

| Actor | Role |
| --- | --- |
| Chrono24 Scraper ◄── you are here | Live luxury watch listings |
| [WatchCharts Scraper](https://apify.com/crawloop/watchcharts-scraper) | Public market price and retail price by reference |
| [eBay Sold Listings Scraper](https://apify.com/crawloop/ebay-sold-listings-scraper) | Completed marketplace comps |

# Actor input Schema

## `searchQueries` (type: `array`):

Free-text Chrono24 searches (brand + model, reference, or keyword). Example: Rolex Daytona, 126610LN, Patek Nautilus. Optional if startUrls or brands is set.

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

Brand names or Chrono24 slugs (Rolex, Omega, patek-philippe). Opens the brand catalog. Combine with filters below.

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

Search, brand, model, or listing URLs. Mixed types are classified automatically. Example: https://www.chrono24.com/rolex/index.htm

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

Hard cap on dataset rows across all queries and URLs.

## `maxPages` (type: `integer`):

Search/brand/model pagination cap. Chrono24 serves up to 60 listings per page.

## `pageSize` (type: `integer`):

Listings per search page (30, 60, or 120).

## `fetchDetails` (type: `boolean`):

Open each listing page for specs (reference, year, movement, box/papers, seller rating). Disable for fast card-only price monitoring.

## `flatten` (type: `boolean`):

Copy nested specs onto CSV-friendly specs\* columns.

## `currency` (type: `string`):

Display currency for Chrono24 prices.

## `priceMin` (type: `integer`):

Minimum listing price in the selected currency.

## `priceMax` (type: `integer`):

Maximum listing price in the selected currency.

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

Earliest production year.

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

Latest production year.

## `usedOrNew` (type: `string`):

Restrict to new/unworn or pre-owned watches.

## `condition` (type: `array`):

Seller-stated condition grades.

## `movement` (type: `array`):

Movement type.

## `caseMaterial` (type: `array`):

Case metal or material.

## `dialColor` (type: `array`):

Dial color filter.

## `gender` (type: `string`):

Men's/unisex or women's watches.

## `sellerType` (type: `string`):

Professional dealer, private seller, or Chrono24 Direct.

## `countries` (type: `array`):

ISO country codes (US, DE, CH, JP). Empty = worldwide.

## `certified` (type: `boolean`):

Only Chrono24 Certified listings (authenticity guarantee).

## `boxAndPapers` (type: `string`):

Filter by original box and/or papers included with the watch.

## `caseDiameterMm` (type: `string`):

Single size (40) or range (36,42).

## `availability` (type: `string`):

Restrict to in-stock listings when needed.

## `sortBy` (type: `string`):

How Chrono24 orders results before pagination.

## `searchParams` (type: `object`):

Optional raw Chrono24 query params (overrides the filters above on conflict). Example: {"braceletMaterial": "406", "functions": "1000"}.

## `requestDelaySecs` (type: `number`):

Pause between HTTP requests.

## `forceBrowser` (type: `boolean`):

Off by default. Chrono24 is fetched over HTTP. If Cloudflare blocks a page, the Actor tries one Chromium unlock and then stops if that page still fails. Enable to fetch every page in Chromium.

## `monitorMode` (type: `boolean`):

On a schedule, push and charge only new listings and price drops since the last run. The first run builds a baseline and still returns rows.

## `monitorStoreName` (type: `string`):

Named key-value store for monitor state. Use a distinct name per watch or search you track.

## `resetMonitorState` (type: `boolean`):

Clear saved monitor state before this run (starts a fresh baseline).

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

Chrono24 blocks many datacenter IPs. Use Apify Proxy RESIDENTIAL on the platform. Proxy 407 is rotated, not escalated to a full browser crawl.

## Actor input object example

```json
{
  "searchQueries": [
    "Rolex Daytona"
  ],
  "maxItems": 20,
  "maxPages": 5,
  "pageSize": 60,
  "fetchDetails": true,
  "flatten": true,
  "currency": "USD",
  "usedOrNew": "any",
  "gender": "any",
  "sellerType": "any",
  "certified": false,
  "boxAndPapers": "any",
  "availability": "any",
  "sortBy": "relevance",
  "requestDelaySecs": 0.25,
  "forceBrowser": false,
  "monitorMode": false,
  "monitorStoreName": "chrono24-monitor",
  "resetMonitorState": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Default dataset items — one Chrono24 listing per row.

# 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 = {
    "searchQueries": [
        "Rolex Daytona"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/chrono24-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 = {
    "searchQueries": ["Rolex Daytona"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/chrono24-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 '{
  "searchQueries": [
    "Rolex Daytona"
  ],
  "maxItems": 20
}' |
apify call crawloop/chrono24-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawloop/chrono24-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/4hPZcMrzzSEz020vd/builds/9FNrgYWwzeDRdXBVI/openapi.json
