# Chrono24 Scraper · 60 Fields · Details Included · From $1.00/1k (`corvuslab/chrono24-scraper`) Actor

Scrape Chrono24 luxury watch listings with up to 56 fields each: reference number, year, caliber, jewels, power reserve, case material & diameter, water resistance, box & papers, price, shipping cost, dealer city/country and returns. All 560+ brands by name, plus incremental price monitoring.

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

## Pricing

from $1.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.
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?

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

### What does Chrono24 Scraper do?

[Chrono24](https://www.chrono24.com/) Scraper turns the world's largest luxury-watch marketplace — over 500,000 live listings from more than 100 countries — into a clean, typed dataset. Every listing comes back with up to **56 watch, dealer and deal fields** — reference number, production year, caliber and base caliber, jewels, power reserve, case material, diameter and thickness, crystal, dial, water resistance, bracelet material and colour, clasp, box-and-papers flags, asking price, shipping cost, dealer city and country, transit days and return policy. No code, no login: results export as **JSON, CSV, Excel** or stream straight into the **API** and **AI agents**.

Give it a search phrase (`Rolex Submariner`, `126610LN`, `Speedmaster Professional`), pick filters like brand, price range, condition, movement, case material or dealer country — or just paste Chrono24 URLs. **Search pages, brand index pages, model/reference index pages and individual listing pages are all auto-detected**, so you can mix them in one run. Each result is normalized into the same record shape, whether it came from a grid or a detail page.

> New to Apify? Sign up free and use the included monthly platform credit to try this Actor — no credit card needed.

**Why this scraper**

- ⚡ **Full specs at no extra charge** — one rate covers the listing *and* its complete spec sheet, with no separate enrichment fee. A lightweight request path that never starts a browser keeps large catalog sweeps fast and cheap.
- 🧾 **Rich, typed records** — up to 56 structured fields per listing (68 including contact extraction and run metadata), not raw HTML.
- ⌚ **Brands by name, not by ID** — all **565 Chrono24 manufacturers** resolve from the name you type: `Jaeger-LeCoultre`, `A. Lange & Söhne`, `F.P. Journe`. Spelling is matched loosely, so punctuation and accents don't have to be exact.
- ♻️ **Cheap to monitor** — incremental mode spots unchanged listings *before* their detail page is fetched, so a daily watch on a thousand listings bills only for the handful that actually moved.
- 🔔 **Notifications built in** — Telegram, Slack, Discord or any webhook.
- 🤖 **AI- & API-ready** — compact output, MCP-friendly, one-click integrations.

***

### What data can you extract from Chrono24?

Every record carries up to **56 listing fields** — plus contact-extraction and tracking fields, **68 in the schema overall**. That's every specification Chrono24 publishes on a watch, not just the headline price:

| Group | What you get |
|---|---|
| **Watch identity** | `brand`, `model`, `collection`, `referenceNumber`, `year`, `condition`, `gender`, `listingCode`, `breadcrumbs`, full `description` |
| **Movement & caliber** | `movement`, `caliber`, `baseCaliber`, `jewels`, `powerReserve`, `frequency` |
| **Case, dial & bracelet** | `caseMaterial`, `caseDiameter`, `caseThickness`, `crystal`, `dial`, `waterResistance`, `material`, `braceletMaterial`, `braceletColor`, `claspType`, `claspMaterial` |
| **Price & deal terms** | `price`, `currency`, `priceValidUntil`, `availability`, `isPromoted`, `hasBox`, `hasPapers`, `scopeOfDelivery`, `shippingCost`, `shippingCurrency`, `shipsToCountry`, `deliveryEstimate`, `transitDaysMin`/`Max`, `returnDays`, `freeReturns`, `paymentMethods` |
| **Dealer & location** | `dealerLocation`, `dealerCity`, `dealerRegion`, `dealerCountry`, `dealerCountryCode`, plus emails, phones, URLs and social profiles extracted from the listing where the seller publishes them |
| **Media & tracking** | `imageUrl`, the full `images` gallery, `url`, `id`, `source`, `searchKeyword`, `scrapedAt`, `detailFetched`, `contentHash`, `changeType`, repost detection |

The box-and-papers flags, the caliber breakdown and the shipping/returns block are what separate a usable valuation dataset from a price list — they are the biggest single drivers of what a pre-owned watch is actually worth.

***

### Key features

- 🔎 **Search or URL scraping** — run a keyword-plus-filter search, or paste Chrono24 URLs. Detail pages, search URLs, brand index pages and model/reference index pages are classified automatically, mixed freely in one run.
- ⌚ **All 565 brands by name** — the 60 most-traded sit in a dropdown; every other brand is typed into `otherBrands` and resolved for you. No opaque numeric manufacturer IDs to look up, and no guessing at exact punctuation — `F.P. Journe` and `Glashutte Original` both land.
- 🧾 **Full specification sheet** — reference number, year, caliber + base caliber + jewels + power reserve + frequency, case material/diameter/thickness, crystal, dial, water resistance, bracelet material and colour, clasp type and material.
- 📦 **Box & papers, decoded** — `hasBox` and `hasPapers` booleans plus the raw scope-of-delivery text, so you can filter for full-set watches instead of reading every description.
- 🚚 **Landed-cost fields** — shipping cost and currency, ships-to country, delivery estimate, minimum and maximum transit days, return window and free-returns flag. Price alone doesn't tell you what the watch costs you.
- 🎚️ **Marketplace filters applied on the site** — brand, price range, condition, movement, case material, bracelet material, gender, box/papers, dealer country, professional-dealers-only, listed-within-N-days and sort order. Rows you filter out are never fetched and never billed.
- 💸 **Listing-only mode is genuinely cheap** — turn off full details and you still get price, shipping cost, dealer country, promoted flag and images straight from the result grid, with no extra page fetch per watch.
- ♻️ **Incremental price monitoring** — schedule it and get only what changed (NEW / UPDATED / EXPIRED); a price move marks a listing UPDATED, and unchanged listings are skipped *before* their page is fetched.
- 🔔 **Notifications** — Telegram, Slack, Discord or any webhook (n8n / Make / Zapier).
- 🤖 **AI-ready** — compact mode and drop-empty-fields keep payloads small for LLMs and MCP clients.

***

### 🚀 How to scrape Chrono24

1. Open the Actor and type a **search phrase** (e.g. `Rolex Submariner`, or a bare reference like `126610LN`) — or paste Chrono24 URLs into **Start URLs**.
2. Pick your filters: brands, price range, condition, movement, case material, dealer country, box & papers.
3. Set **Max results** and decide whether to **fetch full details** (on by default — it's what unlocks caliber, year and the return policy).
4. (Optional) Turn on **incremental mode** and a **notification** channel, then open **Schedules**.
5. Click **Start** — results stream into the Output tab, ready to download as JSON, CSV or Excel.

No login, no cookies, no setup — it runs out of the box. Leave the input completely empty and it still returns real rows: the marketplace's eight most-traded luxury brands.

#### Quick-start example input

```json
{
  "query": "Rolex Submariner",
  "maxResults": 100,
  "condition": "used",
  "includedAccessories": ["box", "papers"]
}
```

This returns up to 100 pre-owned Submariners that ship with both the original box and papers — the full-set segment where resale pricing is tightest and the comparables are most reliable.

***

### Input

Configure it in the visual editor — no code needed — or pass JSON via the API. **35 inputs** are available, grouped exactly as you see them in the editor.

#### 🔎 Search

| Field | Type | What it does |
|---|---|---|
| `query` | string | Brand, model, reference number or free text — e.g. `Omega Speedmaster` or `126610LN`. Comma-separate several searches in one run. |
| `startUrls` | array | Paste Chrono24 URLs directly. Search URLs, brand pages, model pages, reference pages and single listing pages are each detected and handled. |
| `maxResults` | integer | Cap the number of listings (default 25, `0` = unlimited). |
| `ignoreUrlFailures` | boolean | Skip URLs that can't be interpreted instead of failing the whole run. |

#### 🎚️ Filters

| Field | Type | What it does |
|---|---|---|
| `brands` | array | Pick from the 60 most-traded brands — `Rolex`, `Omega`, `Patek Philippe`, `Jaeger-LeCoultre`. |
| `otherBrands` | array | Any of the other 500+ brands, typed by name — `A. Lange & Söhne`, `F.P. Journe`, `Glashütte Original`. Spelling is matched loosely, so `F.P. Journe`, `f.p.journe` and `fp journe` all resolve. |
| `condition` | enum | `new` or `used`. |
| `priceFrom` / `priceTo` | integer | Asking-price range. |
| `movements` | array | `automatic`, `manual winding`, `quartz`, `solar`, `smartwatch`. |
| `caseMaterials` | array | `steel`, `yellow gold`, `rose gold`, `white gold`, `platinum`, `titanium`, `ceramic`, `carbon`, `bronze` and more. |
| `braceletMaterial` | enum | `steel`, `leather`, `rubber`, `textile`, `ceramic`, `alligator skin` and more. |
| `gender` | enum | `men` (men's/unisex) or `women`. |
| `includedAccessories` | array | `box`, `papers` — the full-set filter. |
| `dealerCountries` | array | ISO codes: `US`, `UK`, `DE`, `IT`, `CH`, `FR`, `ES`, `NL`, `AT`, `JP` and more. |
| `dealersOnly` | boolean | Exclude private sellers, keep commercial dealers only. |
| `listedSince` | enum | `1`, `3`, `7` or `28` days — the fastest way to catch fresh stock. |
| `sortBy` | enum | `relevance`, `newest` or `price_asc`. |

#### 📄 Output

| Field | Type | What it does |
|---|---|---|
| `includeDetails` | boolean | Fetch each listing's page for reference, year, movement, caliber, jewels, power reserve, materials, water resistance and return policy (default on). |
| `compact` | boolean | Core fields only — ideal for AI agents and MCP clients. |
| `excludeEmptyFields` | boolean | Drop null, empty-string and empty-array fields. |
| `detailConcurrency` | integer | How many listing pages to fetch at once (default 6). |

#### ♻️ Incremental monitoring

| Field | Type | What it does |
|---|---|---|
| `incrementalMode` | boolean | Tag every listing with a `changeType` — NEW / UPDATED / UNCHANGED / EXPIRED. A price change marks a listing UPDATED. |
| `stateKey` | string | Stable name for the tracked search (auto-derived from your settings if blank). |
| `emitUnchanged` | boolean | Also emit listings that haven't changed. |
| `emitExpired` | boolean | Emit listings that were there last run and are gone now — i.e. sold or withdrawn. |

#### 🔔 Notifications

Credentials are secret inputs — encrypted at rest, masked in the UI and never written to the run log.

| Field | Type | What it does |
|---|---|---|
| `telegramToken` + `telegramChatId` | string | Bot token from @BotFather plus the chat or channel ID. |
| `slackWebhookUrl` / `discordWebhookUrl` | string | Incoming webhook URL. |
| `webhookUrl` + `webhookHeaders` | string / object | POST structured JSON anywhere — n8n, Make, Zapier. |
| `notificationLimit` | integer | How many listings to pack into each message. |

#### ⚙️ Advanced

`proxyConfiguration` is optional and **off by default** — this scraper is fastest and most reliable without one. `maxRequestRetries` controls how often a failed request is retried.

#### More example inputs

```json
{ "startUrls": ["https://www.chrono24.com/rolex/index.htm"], "maxResults": 500 }
```

```json
{ "brands": ["Patek Philippe", "Audemars Piguet"], "priceFrom": 20000, "dealerCountries": ["CH", "DE"] }
```

```json
{ "query": "Omega Speedmaster", "listedSince": "1", "incrementalMode": true, "emitExpired": true }
```

***

### Output

Each dataset item is one watch listing. Core fields (price, shipping, dealer country, images, promoted flag) come from the result grid; **Fetch full details** adds the reference number, year, the full caliber breakdown, materials, water resistance, box & papers and the return policy. A real record:

```json
{
  "id": "46166872",
  "title": "Rolex Submariner Full set",
  "url": "https://www.chrono24.com/rolex/submariner--id46166872.htm",
  "brand": "Rolex",
  "model": "Submariner (No Date)",
  "collection": "Submariner",
  "referenceNumber": "124060",
  "year": "2022",
  "condition": "Used (Very good)",
  "gender": "Men's watch/Unisex",
  "price": 13800.0,
  "currency": "USD",
  "priceValidUntil": "2026-12-31",
  "availability": "Item needs to be procured",
  "isPromoted": false,
  "movement": "Automatic",
  "caliber": "3230",
  "baseCaliber": "3130",
  "jewels": 31,
  "powerReserve": "70 h",
  "caseMaterial": "Steel",
  "caseDiameter": "41 x 40 mm",
  "crystal": "Sapphire crystal",
  "dial": "Black",
  "waterResistance": "30 ATM",
  "braceletMaterial": "Steel",
  "braceletColor": "Steel",
  "claspType": "Fold clasp",
  "claspMaterial": "Steel",
  "hasBox": true,
  "hasPapers": true,
  "shippingCost": 150.0,
  "shippingCostLabel": "+ $150 for shipping",
  "dealerLocation": "United States of America, Arizona, Phoenix",
  "dealerCity": "Phoenix",
  "dealerRegion": "AZ",
  "dealerCountry": "United States of America",
  "dealerCountryCode": "US",
  "deliveryEstimate": "Latest anticipated delivery on 10/1",
  "transitDaysMin": 1,
  "transitDaysMax": 7,
  "returnDays": 14,
  "freeReturns": true,
  "paymentMethods": ["CreditCard", "DirectDebit"],
  "listingCode": "RHIL44",
  "breadcrumbs": ["Rolex watches", "Submariner (No Date) watches", "Rolex 124060"],
  "images": ["https://img.chrono24.com/images/uhren/46166872-i7k05wa1equ3obexl5n3w74a-ExtraLarge.jpg"],
  "source": "chrono24.com",
  "searchKeyword": "Rolex Submariner",
  "detailFetched": true,
  "scrapedAt": "2026-09-11T06:20:32.176890+00:00"
}
```

In incremental mode each record also carries `changeType` (NEW / UPDATED / UNCHANGED / EXPIRED) and a `contentHash`, plus `isRepost`, `repostOfId` and `repostDetectedAt` when a dealer relists the same watch under a new ID.

#### Data fields

- **Core (always)** — id, title, url, brand, model, price, currency, availability, promoted flag, shipping cost and label, dealer location/city/region/country/country code, `imageUrl` and the full `images` array, `searchKeyword`, `scrapedAt`.
- **Details (with `includeDetails`)** — referenceNumber, year, condition, gender, collection, listingCode, breadcrumbs, description, movement, caliber, baseCaliber, jewels, powerReserve, frequency, caseMaterial, caseDiameter, caseThickness, material, crystal, dial, waterResistance, braceletMaterial, braceletColor, claspType, claspMaterial, hasBox, hasPapers, scopeOfDelivery, priceValidUntil, shipsToCountry, deliveryEstimate, transitDaysMin/Max, returnDays, freeReturns, paymentMethods.
- **Contacts** — emails, phones, URLs and social profiles extracted from the listing where the seller publishes them.
- **Tracking** — source, detailFetched, contentHash, changeType, isRepost, repostOfId, repostDetectedAt.

Every field is present in standard mode (missing values are `null`); **compact mode** returns the core fields only, for lean AI/MCP payloads; **`excludeEmptyFields`** drops empties entirely. The Output tab also ships a ready-made **Overview** view — title, brand, reference number, year, condition, price, currency, dealer country and URL in one scannable table.

***

### ♻️ How to monitor Chrono24 prices with incremental mode

Schedule the Actor and turn on **incremental mode**: each run compares against the last and emits only **NEW / UPDATED / EXPIRED** listings. A price cut marks a watch UPDATED; a watch that sold or was withdrawn comes back EXPIRED. Unchanged listings are recognised *before* their detail page is fetched, so you skip both the work and the cost.

| | First run (baseline) | Next run (nothing changed) |
|---|---|---|
| Listings found | all | all |
| Detail pages fetched | all | **none** |
| Records emitted & billed | all | **none** |

Your cost after the baseline scales with how much the market moves, not with how closely you watch it. Here is a month of **tracking 1,000 listings, once a day**, at the Business-plan rate below:

| Daily churn | Billable records/day | Incremental, per month | Re-scraping daily | You save |
|---|---|---|---|---|
| 5 % | 50 | **$1.53** | $30.03 | **95 %** |
| 15 % | 150 | **$4.53** | $30.03 | **85 %** |
| 30 % | 300 | **$9.03** | $30.03 | **70 %** |

Run-start fees for all 30 runs are included in those figures. On Free or Starter, multiply by 1.2.

#### Setting up scheduled monitoring

1. Configure your search and filters — e.g. a reference number plus a dealer-country list.
2. Turn on **Incremental mode** (and **Include sold / removed listings** if you want sell-through signals).
3. Run it once — this seeds the baseline.
4. Open the **Schedules** tab and set a recurring run (hourly for hot references, daily for a broad brand sweep).
5. Add a notification channel so price moves reach you the moment they land.

***

### 🔔 How to set up Chrono24 alerts

Get pinged the moment a matching watch is listed or repriced. Fill in only the channels you want:

| Channel | What to configure |
|---|---|
| ✈️ **Telegram** | `telegramToken` (from @BotFather) + `telegramChatId` |
| 💬 **Slack** | `slackWebhookUrl` (Incoming Webhook URL) |
| 🎮 **Discord** | `discordWebhookUrl` (channel webhook URL) |
| 🪝 **Webhook** | `webhookUrl` receives structured JSON — ideal for n8n / Make / Zapier |

Every channel fires independently — a broken channel can't stop the scrape or the others. Pair **incremental mode** with a `priceTo` ceiling and you have a standing "tell me when a 124060 with box and papers drops under my number" watchlist, with no duplicate pings across runs.

***

### 💡 What can you do with Chrono24 data?

#### Track reference-level prices over time

Pull every live listing for a reference — `126610LN`, `5711/1A`, `311.30.42.30.01.005` — and record asking price, condition, box/papers status and dealer country on a schedule. Stack the runs and you have a real price curve per reference, not a single-point guess.

#### Spot arbitrage and underpriced listings

Combine `price` with `shippingCost`, `transitDaysMax`, `returnDays` and `dealerCountryCode` to compare true landed cost across markets. A watch that looks cheap loses its edge once shipping and a 14-day return window are priced in — these fields let you rank on the number that matters.

#### Value a collection or build comparables

Reference number, year, caliber, case material and the box-and-papers flags are exactly the inputs an appraisal or insurance valuation needs. Export the matching comparables to Excel and you have a defensible spread rather than an anecdote.

#### Monitor dealer inventory and sell-through

Filter to professional dealers in a country set and run it daily with `emitExpired` on. New listings show what's being sourced; expired ones show what's actually moving and how fast.

#### Market & competitive research

Slice the market by brand, movement, case material, price band and dealer country to see where supply is concentrating and which segments are thinning out. The `isPromoted` flag shows which sellers are paying for placement in your niche.

#### Feed AI agents and LLM pipelines

Compact JSON straight into an LLM context, an MCP tool or a vector store — perfect for a "find me a full-set steel diver under X with fast shipping" agent. `excludeEmptyFields` and compact mode keep token costs low.

***

### 💰 How much does it cost to scrape Chrono24?

This Actor uses Apify's **pay-per-event** model: a small run-start fee, plus a per-record fee that falls with your Apify plan.

| Your Apify plan | Per record | Per 1,000 listings |
|---|---|---|
| Free / Starter | $0.00120 | $1.20 |
| Scale | $0.00110 | $1.10 |
| **Business and above** | **$0.00100** | **$1.00** |

**One rate, details included.** The full spec sheet — reference, year, caliber, jewels, power reserve, materials, water resistance, box & papers, shipping and returns — is in that rate, with **no separate enrichment fee**. That surcharge is the usual way a low headline number doubles once you ask for the data you came for. Platform usage isn't passed on to you either, so the rate above is what you actually pay.

Three things cut the bill further:

- **Marketplace filters** — listings you filtered out are never fetched and never billed.
- **Listing-only mode** — turn off full details when you only need price, shipping, dealer country and images; no second request per watch.
- **Incremental mode** — after the baseline you pay only for what changed (see the table above).

The **Pricing** tab renders the live figures, so check there if you want to be certain.

***

### 🔌 Integrations & export

Export to **JSON, CSV, Excel** or an HTML table, or pull from the **REST API** and the **JavaScript / Python** clients. Runs on a **schedule**, connects to **Google Sheets, Slack, Make, Zapier and n8n**, and works as an **MCP tool** for AI agents — compact mode keeps token usage small.

***

### 🔗 Using the API

Run this Actor from your own code. Example with the Apify Python client:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")

run_input = {
    "query": "Omega Speedmaster",
    "maxResults": 50,
    "includedAccessories": ["box", "papers"],
}

run = client.actor("corvuslab/chrono24-scraper").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["referenceNumber"], item["year"], item["price"], item["dealerCountryCode"])
```

It also works with the JavaScript/TypeScript client, the Apify CLI and the REST API.

***

### ❓ FAQ

**Do I need an account or login for Chrono24?** No. It reads public listing pages only — no account, no cookies, no setup.

**How many listings can I get?** Set `maxResults` (`0` = unlimited). A single Chrono24 search only paginates so far, so for very large sweeps split the work — by brand, by price band or by dealer country — and run several searches instead of one giant one.

**Why are `referenceNumber`, `year` or `caliber` empty on some records?** Those live on the listing's own page, so they only appear when **Fetch full details** is on. Even then, they're only as complete as the dealer's entry: a private seller who skips the caliber field leaves it `null` — the record shows the gap honestly rather than guessing.

**Which brands can I filter by?** All 565 manufacturers Chrono24 lists. The 60 most-traded are in the `brands` dropdown; anything else goes in `otherBrands` as free text. You don't have to match Chrono24's exact spelling — accents, dots, hyphens and spacing are all normalised, so `A. Lange & Sohne`, `f.p.journe` and `tag-heuer` each resolve to the right brand.

**In what currency are prices returned?** In the currency Chrono24 displays for the run's region, which is carried in the `currency` field of every record alongside `shippingCurrency`. Always read the number together with its currency code rather than assuming one.

**Does it handle Chrono24 URLs as well as searches?** Yes — paste any mix of search URLs, brand index pages (`/rolex/index.htm`), model or reference index pages and individual listing pages into `startUrls`. Each one is classified and handled correctly in the same run.

**What does `hasBox` / `hasPapers` mean exactly?** They're booleans derived from the listing's scope-of-delivery section, with the original text kept in `scopeOfDelivery` so you can audit any edge case. Full-set watches command a meaningful premium, so this is usually the first filter a serious buyer applies.

**Can I get only new or repriced listings on a schedule?** Yes — turn on incremental mode and schedule it. Each run emits only what changed, tags it NEW / UPDATED / EXPIRED, and can notify your channel.

**Is it good for AI agents?** Yes — enable compact mode; the output is MCP-friendly and can drop empty fields entirely.

**Do I pay extra for the full specs, or for compute and proxies?** No to both. One per-record fee covers the listing *and* its full spec sheet, and platform usage is never passed on. Filtered-out listings are never fetched and never billed; in incremental mode, unchanged listings are skipped before their page is fetched, so they cost nothing at all.

**Is my data kept private?** All credentials are secret inputs — encrypted at rest, masked in the UI, and never written to the run log.

***

### ⚖️ Is it legal to scrape Chrono24?

This Actor collects only **publicly available** data. You're responsible for how you use it — in particular any personal information about sellers — and for complying with the site's terms and applicable law (including the GDPR/LGPD where they apply). Not affiliated with, endorsed by or sponsored by Chrono24 GmbH.

***

**Keywords:** chrono24 scraper · chrono24 api · chrono24.com scraper · scrape chrono24 listings · luxury watch scraper · watch price tracking · used rolex prices · watch market research · watch reference number lookup · watch dealer data · pre-owned watch data · chrono24 price monitoring · watch arbitrage data · export to CSV · export to Excel · no-code scraper · MCP tool for AI agents

# Actor input Schema

## `query` (type: `string`):

What to search for — a brand, model, reference number or free text, e.g. "Rolex Submariner" or "126610LN". Comma-separate several searches.

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

Paste Chrono24 URLs to scrape directly. Search URLs, brand pages (/rolex/index.htm), model pages, reference pages and individual listing pages all work — each is detected automatically.

## `maxResults` (type: `integer`):

Maximum number of listings to return. Set 0 for unlimited (bounded by how many the search has).

## `ignoreUrlFailures` (type: `boolean`):

Skip URLs that cannot be interpreted instead of failing the whole run.

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

Limit to these watch brands. This list covers the 60 most traded — for any of the other 500+ brands Chrono24 carries, use "More brands" below.

## `otherBrands` (type: `array`):

Any other Chrono24 brand, by name — all 565 are recognised, e.g. "A. Lange & Söhne", "Glashütte Original", "Czapek", "F.P. Journe". Spelling is matched case-insensitively; names Chrono24 does not carry are ignored rather than failing the run.

## `condition` (type: `string`):

Restrict to new/unworn or pre-owned watches.

## `priceFrom` (type: `integer`):

Lowest asking price to include, in the currency Chrono24 shows for your region.

## `priceTo` (type: `integer`):

Highest asking price to include.

## `movements` (type: `array`):

Restrict to these movement types.

## `caseMaterials` (type: `array`):

Restrict to these case materials.

## `braceletMaterial` (type: `string`):

Restrict to one bracelet or strap material.

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

Restrict to men's/unisex or women's watches.

## `includedAccessories` (type: `array`):

Only listings that include the original box and/or papers — the biggest single driver of resale value.

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

Only listings from dealers in these countries (ISO codes).

## `dealersOnly` (type: `boolean`):

Exclude private sellers and keep only commercial dealers.

## `listedSince` (type: `string`):

Only listings published recently — the fastest way to catch new stock.

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

Order the results Chrono24 returns.

## `includeDetails` (type: `boolean`):

Fetch each listing's page for reference number, year, movement, caliber, jewels, power reserve, materials, water resistance, condition and return policy. Turn off for the fastest, cheapest runs.

## `compact` (type: `boolean`):

Emit only the core fields (brand, model, reference, year, condition, price, dealer, URL). Ideal for AI agents and MCP clients.

## `excludeEmptyFields` (type: `boolean`):

Remove null, empty-string and empty-array fields from each record.

## `detailConcurrency` (type: `integer`):

How many listing pages to fetch at once. Lower this if the site starts refusing requests.

## `incrementalMode` (type: `boolean`):

Track state between runs and tag every listing with a changeType (NEW / UPDATED / UNCHANGED / EXPIRED). A price change marks a listing UPDATED.

## `stateKey` (type: `string`):

Stable name for the tracked search. Leave empty to derive one automatically from your search settings.

## `emitUnchanged` (type: `boolean`):

Also emit listings that have not changed since the previous run.

## `emitExpired` (type: `boolean`):

Emit records for listings present last run but gone now — i.e. sold or withdrawn.

## `telegramToken` (type: `string`):

Bot token from @BotFather.

## `telegramChatId` (type: `string`):

Chat or channel ID, e.g. "-100123456789" or "@yourchannel".

## `slackWebhookUrl` (type: `string`):

Slack incoming-webhook URL.

## `discordWebhookUrl` (type: `string`):

Discord incoming-webhook URL.

## `webhookUrl` (type: `string`):

Any HTTPS endpoint. Receives a JSON POST with the matched listings — works with n8n, Make and Zapier.

## `webhookHeaders` (type: `object`):

Extra headers for the webhook request, e.g. {"Authorization": "Bearer xyz"}.

## `notificationLimit` (type: `integer`):

How many listings to include in each notification message.

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

Leave this on. Chrono24 refuses requests from unproxied cloud IPs, so runs need Apify Proxy; the default datacenter group is the cheapest that works. Switch to RESIDENTIAL only if runs start being refused.

## `maxRequestRetries` (type: `integer`):

How many times to retry a refused request before giving up. Each retry moves to a fresh proxy IP, so a higher number rides out a bad IP.

## Actor input object example

```json
{
  "query": "Rolex Submariner, Omega Speedmaster",
  "maxResults": 25,
  "ignoreUrlFailures": true,
  "condition": "",
  "braceletMaterial": "",
  "gender": "",
  "dealersOnly": false,
  "listedSince": "",
  "sortBy": "relevance",
  "includeDetails": true,
  "compact": false,
  "excludeEmptyFields": false,
  "detailConcurrency": 6,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "notificationLimit": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxRequestRetries": 6
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `allItems` (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 = {
    "query": "Rolex Submariner"
};

// Run the Actor and wait for it to finish
const run = await client.actor("corvuslab/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 = { "query": "Rolex Submariner" }

# Run the Actor and wait for it to finish
run = client.actor("corvuslab/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 '{
  "query": "Rolex Submariner"
}' |
apify call corvuslab/chrono24-scraper --silent --output-dataset

```

## MCP server setup

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