Chrono24 Scraper - Luxury Watches, Prices, Specs & Reviews
Pricing
from $1.00 / 1,000 results
Chrono24 Scraper - Luxury Watches, Prices, Specs & Reviews
Scrape Chrono24 luxury watch listings by keyword, filters or URL. Extract 50+ fields including brand, model, reference number, price, year, condition, movement, case specifications, seller details, location, images and more.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
2
Monthly active users
5 days ago
Last modified
Categories
Share
Chrono24 Scraper: Watch Listings, Specs, Seller & Review Data
Chrono24 Scraper turns Chrono24, the global marketplace for new and pre-owned watches, into structured JSON. Search by keyword and filters, or paste any mix of detail, brand, model, and search URLs. Each listing comes back with brand, model, reference number, price, year, condition, the full movement and case spec sheet, seller and location, images, and the seller's rating and recent buyer reviews. Export to JSON, CSV, or Excel, or pull results straight into your app through the API.
Why This Scraper?
- 50+ fields per watch on the full record: the complete spec sheet (movement, caliber, case, dial, bracelet, clasp) plus seller, certification, listing code, and reference details.
- Seller rating and recent buyer reviews (date, stars, watch, reviewer, text) attached to every fully-enriched listing at no extra fetch.
- Two modes: keyword + filter search, or direct URLs, with detail, brand, model, and search links mixed freely in one run.
- Card mode for cheap, fast harvesting of search and list pages, or full-detail mode for the complete spec sheet, chosen per run.
- Rich filters: price, year, condition, case material, dial color, bracelet material, seller type, country, reference number, and more, with six sort orders.
- Chrono24's own curated Top Deals collection with one toggle, complete with the site's own per-listing savings percentage in card mode.
- Automatic pagination, de-duplication, and per-record output, with optional flattening to
specs_*columns for spreadsheet export.
Use Cases
- Dealers and resellers: track competitor pricing and stock across brands and reference numbers to price your own inventory.
- Collectors: monitor a specific reference or model for new listings, price drops, or newly reappeared stock.
- Market analysts: build historical pricing datasets by brand, condition, and case material for valuation models.
- Deal hunters: pull Chrono24's curated Top Deals collection sorted by savings to spot the steepest discounts first.
- Marketplace researchers: compare seller ratings, review samples, and seller type (dealer vs. private) across a search.
Data You Get
Sample shape: values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
listingId | "00000001" |
title | "Rolex Submariner Date" |
brand | "Rolex" |
model | "Submariner Date" |
referenceNumber | "126610LN" |
price | 12500 |
currency | "USD" |
availability | "InStock" |
condition | "Used (Very good)" |
year | "2022" |
location | "Germany, Bavaria, Munich" |
sellerCountry | "DE" |
sellerUsername | "sample_dealer" |
certificationStatus | "Basic" |
isDeal | false |
specs_movement | "Automatic" |
specs_caseMaterial | "Steel" |
specs_caseDiameter | "41 mm" |
specs_dialColor | "Black" |
specs_functions | "Date" |
sellerRating | 4.8 |
reviewCount | 12 |
images | ["https://img.chrono24.com/images/uhren/00000001-Square480.jpg"] |
listingUrl | "https://www.chrono24.com/rolex/submariner--id00000001.htm" |
A full-detail record also carries description, priceDisplay, availabilityText, conditionText, scopeOfDelivery, gender, Chrono24's internal productType/marketingType/collectionId/modelId/modelVariantId/refId, the remaining spec columns (specs_baseCaliber, specs_powerReserve, specs_jewels, specs_waterResistance, specs_bezelMaterial, specs_crystal, specs_dialNumerals, specs_braceletMaterial, specs_braceletColor, specs_clasp, specs_claspMaterial, specs_productSafety), a reviews array, a sample of the seller's recent reviews shown on the listing page (not the seller's full review history; date, rating, watch, reviewer name and country, received/shipped-from, text), and reviewCount, the number of reviews in that sample, thumbnail, rowType, and scrapedAt. buyingAgent (name, office, region) appears only on the minority of listings handled through Chrono24's own buying-agent/concierge program. rawHtmlBytes is a diagnostic byte count, only added when Include raw size marker is on. Chrono24 does not publish a structured was-price, original-price, or MSRP field on any listing, curated collections included, so this scraper does not fabricate one; the one real savings figure it does publish, a rendered "-N%" badge on the curated Top Deals collection, is picked up as discountPercent on lightweight cards (see below), while the full detail page carries only the boolean isDeal. Lightweight cards from a search, brand, model, or search-URL results page (fetch full details off) carry a narrower shape instead: rowType, listingId, watchId, title, price, currency, discountPercent (Top Deals collection only, null otherwise), sellerType, countryCode, thumbnail, images, listingUrl, sourceUrl, and scrapedAt, without any of the spec, seller-review, or Chrono24-internal fields above. A pasted single-listing URL (--id...htm) never returns this card shape: it always returns the full-detail record described above, regardless of the Fetch full details toggle (see "How to Use"). Incremental mode adds changeType, changedFields, firstSeenAt, and lastSeenAt to every record; these are absent when incremental mode is off.
How to Use
- Pick a mode:
search(keyword + filters) orurl(paste any mix of detail, brand, model, and search links). - In search mode, set a keyword and filters, or turn on Top Deals collection only to browse Chrono24's own curated deals instead. In URL mode, paste your links.
- Switch Fetch full details on for the full spec sheet, or off for fast, cheap cards from results pages. Set Max listings (and optionally Max pages) to control run size and cost.
- Click Start, then download the dataset as JSON, CSV, or Excel, or read it through the API.
Search by keyword with filters (full detail):
{"mode": "search","searchQuery": "Rolex Submariner","searchParams": { "priceFrom": 8000, "priceTo": 15000, "usedOrNew": "used", "caseMaterials": "steel" },"sortBy": "price-asc","fetchDetails": true,"maxListings": 50}
Fast card harvesting (no per-listing fetch):
{"mode": "search","searchQuery": "Omega Speedmaster","fetchDetails": false,"maxListings": 200}
Chrono24's curated Top Deals collection, sorted by the site's own savings percentage (card mode, needed to see discountPercent):
{"mode": "search","dealsOnly": true,"sortBy": "savings-desc","fetchDetails": false,"maxListings": 50}
Direct URLs, detail + model + search mixed, with Fetch full details off:
{"mode": "url","urls": ["https://www.chrono24.com/rolex/submariner--mod4.htm","https://www.chrono24.com/patek-philippe/nautilus--id00000001.htm","https://www.chrono24.com/search/index.htm?query=Daytona&dosearch=true"],"fetchDetails": false,"maxListings": 0}
This last example returns two different row shapes in one run: the model and search URLs return lightweight cards (Fetch full details is off), but the pasted detail URL still returns a full-detail record and is still billed the detail-enrichment charge, within whatever Max listings budget remains after the model and search URLs are walked. A single-listing URL has no lightweight card equivalent on Chrono24, so whenever it's read it is always fetched and enriched in full; Fetch full details only decides the row shape for brand, model, and search URLs (and for search mode). Set Max listings to 0 (unlimited) as shown here, or make sure the other URLs' budget doesn't consume the whole cap, or the pasted detail URL may never be reached in card mode, since list URLs are walked first.
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/chrono24-scraper").call(run_input={"mode": "search", "searchQuery": "Rolex Submariner", "maxListings": 20})for listing in client.dataset(run["defaultDatasetId"]).iterate_items():print(listing["title"], listing["price"], listing["currency"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/chrono24-scraper').call({ mode: 'search', searchQuery: 'Rolex Submariner', maxListings: 20 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets, or webhooks from the Integrations tab.
How Max listings and Max pages cap a run
Max listings (maxListings) is the single cap on total output; set it to 0 for unlimited. Max pages (maxPages) is a safety bound on how many result pages (120 listings each) the actor walks per search, brand, model, or search URL; set it to 0 for unlimited too. Either way, a walk also stops on its own the moment a page adds no new listings, so a run never loops on a search that has run out of fresh results.
Resume and recurring updates
Two distinct features:
- Resume from a previous run (
resumeFromRunId) continues one specific interrupted crawl: paste a previous run ID or dataset ID and this run skips every listing that run already collected, so a large pull finishes without paying for or re-returning what you already have. A run ID or dataset ID that cannot be read stops the run before anything is scraped. - Incremental mode (
incrementalMode) is for scheduling this actor against the same search or URL set again and again (daily, for example) and getting back only what changed. State is kept automatically per search/URL and detail-mode setup, or name it yourself withstateKeyto control sharing across runs. Every listing then carrieschangeType:NEWon first sight,UPDATED(withchangedFields) when a tracked field genuinely changes, orUNCHANGEDwhen nothing did (suppressed and not billed unlessemitUnchangedis on).EXPIREDandREAPPEAREDare opt-in and gated:EXPIREDonly fires withemitExpiredon, and only after a run that scanned the entire tracked search without being capped by Max listings or Max pages, resumed, or missing a page it could not read.REAPPEAREDcan then only happen afterward, for a listing an earlieremitExpiredrun had marked gone; without ever turningemitExpiredon, a schedule will only ever seeNEW,UPDATED, and (ifemitUnchangedis on)UNCHANGED. CombineincrementalModewithemitExpiredand setmaxListings/maxPagesto0if you need a complete scan every run.
Send results into your apps (MCP connectors)
Optionally pipe results into the apps you already use through Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, Integrations, then select it in the input. Notion receives a page per item; other connectors get a best-effort write or digest. The connector receives a condensed, human-readable summary per item (a title plus key fields), not the full JSON; the complete record always stays in the Apify dataset. Leave the field empty to skip. Supported: Notion, Linear, Airtable, Apify.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (keyword + filters) or url (paste links). |
searchQuery | string | no default (prefill: Rolex Submariner) | Keyword for search mode. Empty browses everything matching the filters. |
searchParams | object | no default (prefill: {}) | Filters: priceFrom, priceTo (USD), year, usedOrNew, caseMaterials, dialColor, braceletMaterial, sellerType, countryIds, referenceNumber, caseDiameter, man, certified, inStock. Friendly words or raw Chrono24 ids. |
sortBy | string | relevance | relevance, price-asc, price-desc, newest, popularity, savings-desc (Top Deals collection only; falls back to relevance elsewhere). |
dealsOnly | boolean | false | Browse Chrono24's curated Top Deals collection instead of a regular search. Ignores searchQuery and searchParams (not supported by that page); sortBy still applies, including savings-desc. |
urls | array | no default (prefill: one sample model URL) | Detail, brand, model, or search URLs (URL mode). The Top Deals collection also works here as a plain URL. |
fetchDetails | boolean | true | On: full spec sheet per listing. Off: lightweight cards from results pages for search/brand/model/search URLs; pasted detail URLs are always fully fetched regardless. |
fetchSellerReviews | boolean | true | Attach seller rating + recent buyer reviews to each fully-enriched listing. Read in the same pass as the details, so it adds no extra fetch. Only applies when Fetch full details is on (or on a pasted detail URL, which is always fully fetched). |
flatten | boolean | true | Also expose nested specs as flat specs_* columns. |
includeRaw | boolean | false | Attach a rawHtmlBytes diagnostic field. |
maxListings | integer | 20 | The single cap on output. 0 means unlimited. |
maxPages | integer | 0 | Safety bound on pages per search URL (120 listings per page). 0 means unlimited: the run stops at Max listings, or when a page stops returning new listings. |
resumeFromRunId | string | no default | Continue one specific interrupted run: paste its run ID or dataset ID and this run skips listings already collected there. |
incrementalMode | boolean | false | Recurring/scheduled monitoring of the same search or URL set; see "Resume and recurring updates". |
stateKey | string | no default | Name a monitoring campaign (incremental mode) to keep its state stable, or leave empty for an automatic key derived from the search/URL and detail settings. |
emitUnchanged | boolean | false | Incremental mode: also return (and bill) listings unchanged since the last run, marked UNCHANGED. |
emitExpired | boolean | false | Incremental mode: also return (and bill) listings from a previous run no longer found, marked EXPIRED. Only produced after a complete scan; see "Resume and recurring updates". |
proxy | object | no default (prefill: Apify Proxy enabled) | Connection settings; see "Plan Requirement". |
mcpConnectors | array | no default | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | no default | Notion connector only: page under which records are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. |
Output Example
Sample shape: values are illustrative placeholders, not from a live listing.
{"rowType": "detail","listingId": "00000001","watchId": "00000001","listingUrl": "https://www.chrono24.com/rolex/submariner--id00000001.htm","title": "Rolex Submariner Date","brand": "Rolex","model": "Submariner Date","referenceNumber": "126610LN","listingCode": "AAA000","price": 12500,"currency": "USD","availability": "InStock","condition": "Used (Very good)","year": "2022","location": "Germany, Bavaria, Munich","sellerCountry": "DE","sellerUsername": "sample_dealer","certificationStatus": "Basic","isDeal": false,"scopeOfDelivery": "Original box, original papers","gender": "Men's watch/Unisex","specs": {"movement": "Automatic","caliber": "3235","baseCaliber": "3235","powerReserve": "70 h","jewels": "31","caseMaterial": "Steel","caseDiameter": "41 mm","waterResistance": "30 ATM","bezelMaterial": "Ceramic","crystal": "Sapphire crystal","dialColor": "Black","braceletMaterial": "Steel","clasp": "Fold clasp","functions": "Date"},"sellerRating": 4.8,"reviewCount": 12,"reviews": [{"date": "2026-01-01","rating": 5,"watch": "Rolex Submariner","received": "2026-01-01","shippedFrom": "United States of America","reviewerName": "Jane D.","reviewerCountry": "United States of America","text": "Sample review text appears here."}],"images": ["https://img.chrono24.com/images/uhren/00000001-Square480.jpg"],"scrapedAt": "2026-01-01T00:00:00.000Z"}
A lightweight card (Fetch full details off, on a search, brand, model, or search-URL page) instead returns just rowType: "card", listingId, watchId, title, price, currency, discountPercent (Top Deals collection only, null otherwise), sellerType, countryCode, thumbnail, images, listingUrl, sourceUrl, and scrapedAt, with none of the spec, seller, or review fields above.
Plan Requirement
The default proxy setting works out of the box, and the actor automatically retries on a different connection when one is refused. For large or frequent runs, the residential proxy group gives the widest IP rotation; pick it under Connection. If the account running this actor has no Apify Proxy access, the actor falls back to a backup connection, which may be slower or return fewer results.
FAQ
How much does it cost?
You pay per run start, per listing returned, and an extra detail-enrichment charge for each listing that is fully fetched (Fetch full details on, or any pasted single-listing URL, which is always fully fetched regardless of that toggle). The Pricing tab shows the current rates. Use Max listings to cap the cost of any run.
Is it legal to scrape Chrono24?
This actor collects only publicly available marketplace listing data. You are responsible for how you use it: follow Chrono24's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Listings can include a seller's username, general location, and reviews from other users; handle that data responsibly and avoid republishing it in ways that identify individuals.
Can I get only new or changed listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated listings by default, and unchanged ones are not billed. Turning on emitExpired also surfaces listings that disappeared, but only after a run that scans the whole tracked search; see "Resume and recurring updates" for the exact gating.
Does "Fetch full details" apply to a pasted single-listing URL?
No. A pasted detail URL (--id...htm) has no lightweight card equivalent on Chrono24, so it is always fetched and enriched in full, and always billed the detail-enrichment charge, whether Fetch full details is on or off. The toggle only changes the row shape for search results and for pasted brand, model, and search URLs.
Why did my run fail instead of returning an empty dataset?
If Chrono24 refuses every request this run makes, or a pasted resumeFromRunId cannot be resolved, the run stops with a clear failed status instead of quietly finishing with zero items, so "nothing could be read" is never confused with "nothing matches". A search or URL set that genuinely matches nothing, or an incremental run where every listing was unchanged, still finishes normally with zero new items and a status message explaining why.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear, or Airtable.
๐ Want more classifieds data?
Pair this actor with these related scrapers from the same team:
| ๐ท๏ธ Vinted.fr Scrape Vinted.fr, France's C2C second-hand fashion marketplace: search with... | ๐ท๏ธ Subito.it Scrape Subito.it listings across cars, real estate, marketplace, jobs, and more. Search... |
| ๐ท๏ธ bol.com Scraper Scrape bol.com products: title, price, list price and discount, EAN, brand, images... | ๐ท๏ธ ThredUp Scraper Scrape ThredUp resale listings by keyword, department, brand, size, condition, price or... |
| ๐ท๏ธ Gumtree AU Scraper Scrape gumtree.com.au classifieds across every vertical: for-sale goods, motors, real... | ๐ท๏ธ OLX Global From $1/1K. Fast OLX scraper across 9 countries, including Poland, Romania, Portugal... |
๐ Browse all abotapi scrapers
๐ฌ Support & custom scrapers
- ๐ Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- ๐ ๏ธ Need another site, extra fields or a private build? Email abotapi@proton.me or message Telegram @abotapi.
- โญ Enjoying it? A quick review on the actor page helps other users find it.