# Chrono24 Scraper - Watch Listings & Market Prices (`automia-admin/chrono24-scraper`) Actor

Scrape Chrono24 luxury watch listings by brand or model: price, shipping, reference number, dealer country and city. Every run also returns market statistics per target - count, min, quartiles, median, max and median price by dealer country. Residential proxy handled. No personal data.

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

## Pricing

from $5.00 / 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.

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

## Chrono24 Scraper API - luxury watch prices by reference

Get Chrono24 listings as clean JSON, plus the one number a dealer actually
needs: **what a reference is going for right now**.

Point it at a brand (`rolex`, `omega`, `tudor`, `cartier`) or at a model catalog
URL, and every run returns two things:

1. **One row per listing** - price, shipping, reference number, dealer country
   and city, image and listing URL.
2. **Market statistics per target**, in the key-value store record
   `MARKET_STATS` - listing count, minimum, 25th percentile, median, 75th
   percentile, maximum, mean, and the median price broken down by dealer
   country.

Most Chrono24 scrapers hand you sixty rows and let you work out the market price
yourself. This one computes it.

### What you get per listing

| Field | Example |
|---|---|
| `title` | `Rolex Submariner (No Date)` |
| `referenceNumber` | `124060` |
| `priceValue` / `currency` | `11049.0` / `USD` |
| `shippingValue` / `totalValue` | `79.0` / `11128.0` |
| `priceOnRequest` | `false` |
| `dealerCity` / `dealerCountry` / `dealerCountryCode` | `Paramus` / `United States of America` / `US` |
| `brand`, `description`, `imageUrl`, `url`, `listingId` | |
| `position`, `page`, `sourceUrl`, `scrapedAt` | |

And in `MARKET_STATS`, per target:

```json
{
  "https://www.chrono24.com/rolex/submariner--mod1.htm": {
    "listingsWithPrice": 60,
    "currency": "USD",
    "min": 4350.0, "p25": 8846.0, "median": 12249.0,
    "p75": 20298.75, "max": 199000.0, "mean": 19562.52,
    "byDealerCountry": { "US": { "listings": 60, "median": 12249.0 } }
  }
}
```

### Typical uses

- **Price a reference before you buy or list it.** Median and quartiles for one
  model, in one run.
- **Watch a model over time.** Schedule it daily and diff the median.
- **Find the cheap market.** `byDealerCountry` shows where a reference trades
  below the global median.
- **Feed an AI agent.** The output is flat JSON with no nested surprises.

### Input, in one example

```json
{
  "startUrls": ["https://www.chrono24.com/rolex/submariner--mod1.htm"],
  "maxItems": 120,
  "maxPagesPerTarget": 2,
  "dealerCountries": ["US", "DE", "IT"],
  "minPrice": 5000
}
```

Leave the input empty and it reads the first page of Rolex.

### Two limits, stated up front

- **Chrono24 search URLs are not supported.** `/search/index.htm?query=` is
  served behind an anti-bot challenge and would fail silently, so this Actor
  refuses it. Use a brand or model catalog URL instead; that is what Chrono24
  publishes for indexing.
- **The residential proxy is not optional.** Chrono24 rejects datacenter IPs.
  `useApifyProxy` is on by default and turning it off will return nothing.

### No personal data

Dealers are recorded as a **business location only**: city and country. No
dealer names, no contact details, no seller profiles, no buyers. If you need
those, this is not the Actor for you, and that is deliberate.

### Pricing

Pay per event:

- `apify-default-dataset-item` - one per listing returned. Listings dropped by a
  filter are never charged.
- `catalog-page` - one per catalog page actually fetched and parsed. This is
  where the residential-proxy traffic goes. A page that fails is not charged.

A run that returns nothing charges nothing beyond the start event.

# Actor input Schema

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

Brand slugs as they appear in the Chrono24 URL, e.g. rolex, omega, tudor, cartier, patek-philippe, audemars-piguet. Each brand is read from its catalog page. Ignored if Start URLs is filled.

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

Chrono24 catalog URLs, for a brand (https://www.chrono24.com/rolex/index.htm) or a specific model (https://www.chrono24.com/rolex/submariner--mod1.htm). Use a model URL when you want the market price of one reference. The search URL (/search/index.htm?query=) is NOT supported: Chrono24 serves it behind an anti-bot challenge.

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

Upper bound on listings returned across all targets. A catalog page holds 60 listings, so asking for more than 60 requires raising Pages per target as well.

## `maxPagesPerTarget` (type: `integer`):

How many catalog pages to read per brand or URL, 60 listings each. Each page is one charged catalog-page event, so this is the main cost lever.

## `dealerCountries` (type: `array`):

Two-letter country codes of the dealer location, e.g. US, DE, IT, GB, CH, HK. Leave empty to keep every country. Filtered-out listings are not returned and not charged.

## `minPrice` (type: `integer`):

Drop listings priced below this, in the currency Chrono24 serves for the run (USD by default). Listings without a price are dropped when this is set.

## `maxPrice` (type: `integer`):

Drop listings priced above this. Leave empty for no ceiling.

## `skipPriceOnRequest` (type: `boolean`):

Off by default. Some dealers hide the price; those rows come back with priceOnRequest = true and no value. Turn this on to drop them instead.

## `politeDelayMs` (type: `integer`):

Milliseconds between catalog pages. The default of 2000 ms is deliberately conservative: Chrono24 throttles bursty clients and a throttled run returns nothing.

## `retriesPerPage` (type: `integer`):

Attempts per catalog page. Every attempt uses a fresh proxy IP, so a rejected page usually succeeds on the second try.

## `proxyCountry` (type: `string`):

Two-letter country code for the residential proxy exit IP, e.g. US, DE, GB. Useful if you need traffic to originate somewhere specific. Note: it does NOT change the catalog - measured 2026-08-07, Chrono24 serves the same US dealers and USD prices from a German exit IP. Leave empty unless you have a reason.

## `useApifyProxy` (type: `boolean`):

On by default, and it should stay on. Chrono24 rejects datacenter and unproxied requests; measured 2026-08-07, a run without the residential proxy returns nothing.

## Actor input object example

```json
{
  "brands": [
    "rolex",
    "omega"
  ],
  "startUrls": [
    "https://www.chrono24.com/rolex/submariner--mod1.htm"
  ],
  "maxItems": 60,
  "maxPagesPerTarget": 1,
  "dealerCountries": [],
  "skipPriceOnRequest": false,
  "politeDelayMs": 2000,
  "retriesPerPage": 3,
  "proxyCountry": "US",
  "useApifyProxy": true
}
```

# Actor output Schema

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

No description

## `marketStats` (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 = {
    "brands": [
        "rolex",
        "omega"
    ],
    "startUrls": [
        "https://www.chrono24.com/rolex/submariner--mod1.htm"
    ],
    "dealerCountries": [],
    "proxyCountry": "US"
};

// Run the Actor and wait for it to finish
const run = await client.actor("automia-admin/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 = {
    "brands": [
        "rolex",
        "omega",
    ],
    "startUrls": ["https://www.chrono24.com/rolex/submariner--mod1.htm"],
    "dealerCountries": [],
    "proxyCountry": "US",
}

# Run the Actor and wait for it to finish
run = client.actor("automia-admin/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 '{
  "brands": [
    "rolex",
    "omega"
  ],
  "startUrls": [
    "https://www.chrono24.com/rolex/submariner--mod1.htm"
  ],
  "dealerCountries": [],
  "proxyCountry": "US"
}' |
apify call automia-admin/chrono24-scraper --silent --output-dataset

```

## MCP server setup

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