logoPandorLabs
Shopping

Chrono24 Watches

Watch listings on Chrono24 — names, prices, descriptions and images, with optional full listing details.

chrono24-watcheschrono24shoppingmarketplacewatchesluxury

1,117 rows in the dataset

Download the dataset

Get every row this scraper has collected as one CSV or JSONL file. If the data is older than maxAgeHours, the scraper is re-run with its configured settings first. The key needs the datasets:export scope.

DOWNLOAD_ID=$(curl -s -X POST "https://api.pandorlabs.com/v1/datasets/chrono24-watches/downloads" \  -H "Authorization: Bearer $PANDORLABS_KEY" \  -H "Content-Type: application/json" \  -d '{"maxAgeHours":24,"format":"csv"}' | jq -r '.id')while true; do  STATUS=$(curl -s "https://api.pandorlabs.com/v1/downloads/$DOWNLOAD_ID" \    -H "Authorization: Bearer $PANDORLABS_KEY" | jq -r '.status')  [ "$STATUS" != "refreshing" ] && break  sleep 5donecurl -s "https://api.pandorlabs.com/v1/downloads/$DOWNLOAD_ID/file" \  -H "Authorization: Bearer $PANDORLABS_KEY" \  -o dataset.csv

At its current 1,117 rows, this download costs 12 credits when the data is fresh enough, or 24 credits when it has to be refreshed first.

The rate is 1 credit per 100 rows cached and 2 credits live, charged on the rows in the dataset when the download becomes ready. A failed refresh is not charged. The file stays downloadable for 24 hours. See pricing.

Start a run

To choose the targets yourself, send the parameters below as input. The call returns 202 with the run; the key needs the scrapers:run scope and the account a positive credit balance.

curl -X POST "https://api.pandorlabs.com/v1/scrapers/chrono24-watches/runs" \  -H "Authorization: Bearer $PANDORLABS_KEY" \  -H "Content-Type: application/json" \  -d '{    "input": {      "watchType": "used",      "query": "omega speedmaster",      "sortOrder": "relevance",      "currency": "USD"    }  }'

A run is billed at the live rate once it finishes: 2 credits per 100 rows it collected. A run that collects nothing costs nothing.

Parameters

Every parameter is optional. Anything you leave out uses the default shown here; an unknown name or an invalid value is rejected with a 400 that lists each problem.

Targeting

  • watchType

    enum

    Condition

    Sent as `usedOrNew`. The legacy `watchTypes=U` parameter is dead — it no longer filters anything.

    Default
    used
    Allowed values
    used
    new
    all
  • query

    string

    Search query

    Leave empty to walk the whole catalogue. A query that resolves to one brand or model makes Chrono24 redirect to a canonical listing path; pagination follows it either way.

    Default
    none
    Example
    omega speedmaster
  • sortOrder

    enum

    Sort order

    Only nine pages of any search are reachable, so the sort order decides which 1,080 listings a run sees.

    Default
    relevance
    Allowed values
    relevance
    priceAsc
    priceDesc
    newest
    popularity
  • priceFrom

    number

    Min price

    In the selected currency. Combined with a max price this is the practical way to walk more of the catalogue than nine pages.

    Default
    none
    Range
    0 to 100000000
  • priceTo

    number

    Max price

    In the selected currency. Ignored if it is below the min price.

    Default
    none
    Range
    0 to 100000000
  • currency

    enum

    Currency

    Set through the `c24userprefs` cookie as well as the query string — the query parameter alone is ignored. The currency stored on a row is read back off the page, not assumed from this.

    Default
    USD
    Allowed values
    USD
    EUR
    GBP
    CHF
    JPY
    AUD
    CAD

Depth

  • fetchDetails

    boolean

    Fetch listing detail pages

    Adds reference number, movement, case material and diameter, year, condition, box/papers, dealer, shipping cost and the full-size image set. Costs one request per listing.

    Default
    false
  • maxDetails

    number

    Max detail pages per run

    Listings past this keep their search-card fields; the run warns when the ceiling bites.

    Default
    100
    Range
    1 to 5000
  • pageSize

    enum

    Listings per page

    Only 30, 60 and 120 are honoured. Depth is capped in pages, so the largest size is the only way to reach more listings.

    Default
    120
    Allowed values
    30
    60
    120
  • maxPages

    number

    Max pages

    Chrono24 serves page 1-9 and answers a Cloudflare challenge for every page beyond, however many its own paginator advertises.

    Default
    9
    Range
    1 to 9
  • maxItems

    number

    Max listings per run

    Hard ceiling, applied across pages. One search cannot reach more than 1,080 listings anyway.

    Default
    1080
    Range
    1 to 50000

Advanced

  • requestDelayMs

    number

    Delay between requests (ms)

    Cloudflare fronts Chrono24 and answers bursts with a challenge page. Applies between result pages and between detail pages alike.

    Default
    1500
    Range
    0 to 60000
Input as JSON Schema

The same schema the API validates against. Use it as a tool input schema or to generate a typed client.

inputSchema
{  "type": "object",  "additionalProperties": false,  "properties": {    "watchType": {      "type": "string",      "enum": [        "used",        "new",        "all"      ],      "title": "Condition",      "description": "Sent as `usedOrNew`. The legacy `watchTypes=U` parameter is dead — it no longer filters anything.",      "default": "used"    },    "query": {      "type": "string",      "maxLength": 2000,      "title": "Search query",      "description": "Leave empty to walk the whole catalogue. A query that resolves to one brand or model makes Chrono24 redirect to a canonical listing path; pagination follows it either way.",      "examples": [        "omega speedmaster"      ]    },    "sortOrder": {      "type": "string",      "enum": [        "relevance",        "priceAsc",        "priceDesc",        "newest",        "popularity"      ],      "title": "Sort order",      "description": "Only nine pages of any search are reachable, so the sort order decides which 1,080 listings a run sees.",      "default": "relevance"    },    "priceFrom": {      "type": "number",      "minimum": 0,      "maximum": 100000000,      "title": "Min price",      "description": "In the selected currency. Combined with a max price this is the practical way to walk more of the catalogue than nine pages."    },    "priceTo": {      "type": "number",      "minimum": 0,      "maximum": 100000000,      "title": "Max price",      "description": "In the selected currency. Ignored if it is below the min price."    },    "currency": {      "type": "string",      "enum": [        "USD",        "EUR",        "GBP",        "CHF",        "JPY",        "AUD",        "CAD"      ],      "title": "Currency",      "description": "Set through the `c24userprefs` cookie as well as the query string — the query parameter alone is ignored. The currency stored on a row is read back off the page, not assumed from this.",      "default": "USD"    },    "fetchDetails": {      "type": "boolean",      "title": "Fetch listing detail pages",      "description": "Adds reference number, movement, case material and diameter, year, condition, box/papers, dealer, shipping cost and the full-size image set. Costs one request per listing.",      "default": false    },    "maxDetails": {      "type": "number",      "minimum": 1,      "maximum": 5000,      "title": "Max detail pages per run",      "description": "Listings past this keep their search-card fields; the run warns when the ceiling bites.",      "default": 100    },    "pageSize": {      "type": "string",      "enum": [        "30",        "60",        "120"      ],      "title": "Listings per page",      "description": "Only 30, 60 and 120 are honoured. Depth is capped in pages, so the largest size is the only way to reach more listings.",      "default": "120"    },    "maxPages": {      "type": "number",      "minimum": 1,      "maximum": 9,      "title": "Max pages",      "description": "Chrono24 serves page 1-9 and answers a Cloudflare challenge for every page beyond, however many its own paginator advertises.",      "default": 9    },    "maxItems": {      "type": "number",      "minimum": 1,      "maximum": 50000,      "title": "Max listings per run",      "description": "Hard ceiling, applied across pages. One search cannot reach more than 1,080 listings anyway.",      "default": 1080    },    "requestDelayMs": {      "type": "number",      "minimum": 0,      "maximum": 60000,      "title": "Delay between requests (ms)",      "description": "Cloudflare fronts Chrono24 and answers bursts with a challenge page. Applies between result pages and between detail pages alike.",      "default": 1500    }  }}

Run, poll, read rows

The run is asynchronous. Poll it until it reaches a terminal status and its billing is paid, then page through its rows. Until then the rows endpoint answers 409 (still queued or running) or 402 (payment required).

RUN_ID=$(curl -s -X POST "https://api.pandorlabs.com/v1/scrapers/chrono24-watches/runs" \  -H "Authorization: Bearer $PANDORLABS_KEY" \  -H "Content-Type: application/json" \  -d '{    "input": {      "watchType": "used",      "query": "omega speedmaster",      "sortOrder": "relevance",      "currency": "USD"    }  }' | jq -r '.id')while true; do  RUN=$(curl -s "https://api.pandorlabs.com/v1/runs/$RUN_ID" \    -H "Authorization: Bearer $PANDORLABS_KEY")  STATUS=$(echo "$RUN" | jq -r '.status')  BILLING=$(echo "$RUN" | jq -r '.billing.status')  case "$STATUS" in queued|running) ;; *) [ "$BILLING" != "pending" ] && break ;; esac  sleep 5doneecho "$RUN" | jq '{status, rowCount, billing}'curl -s "https://api.pandorlabs.com/v1/runs/$RUN_ID/rows?page=1&limit=100" \  -H "Authorization: Bearer $PANDORLABS_KEY"

See the API reference for pagination, cancelling and listing runs.

Output fields

Rows have no fixed schema; these are the fields observed in the rows collected so far. Coverage is the share of rows where the field is present.

FieldTypeCoverage
brandstring100%
categorystring100%
colorsarray100%
createdAtdate100%
currencystring100%
descriptionstring100%
imagesarray100%
marketplacestring100%
materialsarray100%
namestring100%
pricenumber100%
subCategorystring100%
subSubCategorystring10%
updatedAtdate100%
created_atdate100%
updated_atdate100%
_idstring100%

© 2026 PandorLabs LLC. All rights reserved.