{
  "data": {
    "id": "hifyYAy8vO71LL7pF",
    "actId": "SF1jQJF5bOSKvRV63",
    "userId": "NL4ThgItAwaoBlffQ",
    "startedAt": "2026-11-10T12:43:09.842Z",
    "finishedAt": "2026-11-10T12:45:16.497Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 126562,
      "runTimeSecs": 126.562,
      "computeUnits": 0.14062444444444444,
      "imageSizeBytes": 6120466432
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "zifX0mkAFMHe8CatY",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Booking.com Hotel Price & Rating Snapshot Input\",\n  \"description\": \"Choose a destination or paste hotel URLs, set your stay dates, and collect Booking.com prices, guest scores and review counts.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"mode\": {\n      \"title\": \"What to scrape\",\n      \"type\": \"string\",\n      \"description\": \"Search a destination for hotel prices, or load specific Booking.com hotel pages.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"search\",\n        \"details\"\n      ],\n      \"enumTitles\": [\n        \"Search a destination\",\n        \"Load hotel URLs\"\n      ],\n      \"default\": \"search\",\n      \"prefill\": \"search\"\n    },\n    \"destination\": {\n      \"title\": \"Destination\",\n      \"type\": \"string\",\n      \"description\": \"City, region or landmark to search, e.g. Paris, New York or Tokyo. Required in search mode.\",\n      \"editor\": \"textfield\",\n      \"prefill\": \"Paris\"\n    },\n    \"startUrls\": {\n      \"title\": \"Hotel URLs\",\n      \"type\": \"array\",\n      \"description\": \"Booking.com hotel page URLs, used in details mode. Copy links from a search result or your browser.\",\n      \"editor\": \"requestListSources\",\n      \"default\": [],\n      \"prefill\": [\n        {\n          \"url\": \"https://www.booking.com/hotel/fr/du-printemps-paris.html\"\n        }\n      ]\n    },\n    \"checkIn\": {\n      \"title\": \"Check-in date\",\n      \"type\": \"string\",\n      \"description\": \"Check-in date as YYYY-MM-DD. Leave empty to use tomorrow.\",\n      \"editor\": \"textfield\"\n    },\n    \"checkOut\": {\n      \"title\": \"Check-out date\",\n      \"type\": \"string\",\n      \"description\": \"Check-out date as YYYY-MM-DD. Leave empty to use a 3-night stay.\",\n      \"editor\": \"textfield\"\n    },\n    \"adults\": {\n      \"title\": \"Adults\",\n      \"type\": \"integer\",\n      \"description\": \"Number of adult guests.\",\n      \"default\": 2,\n      \"prefill\": 2,\n      \"minimum\": 1,\n      \"maximum\": 30\n    },\n    \"rooms\": {\n      \"title\": \"Rooms\",\n      \"type\": \"integer\",\n      \"description\": \"Number of rooms needed.\",\n      \"default\": 1,\n      \"prefill\": 1,\n      \"minimum\": 1,\n      \"maximum\": 30\n    },\n    \"propertyType\": {\n      \"title\": \"Property type\",\n      \"type\": \"string\",\n      \"description\": \"Keep only one Booking.com property type, or search all types.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"all\",\n        \"hotels\",\n        \"apartments\",\n        \"hostels\",\n        \"guesthouses\",\n        \"villas\",\n        \"resorts\"\n      ],\n      \"enumTitles\": [\n        \"All types\",\n        \"Hotels\",\n        \"Apartments\",\n        \"Hostels\",\n        \"Guesthouses\",\n        \"Villas\",\n        \"Resorts\"\n      ],\n      \"default\": \"all\",\n      \"prefill\": \"all\"\n    },\n    \"minReviewScore\": {\n      \"title\": \"Minimum review score\",\n      \"type\": \"number\",\n      \"description\": \"Minimum guest score from 0 to 10. The actor applies Booking.com's score filter and keeps only properties at or above this exact score.\",\n      \"default\": 0,\n      \"minimum\": 0,\n      \"maximum\": 10\n    },\n    \"stars\": {\n      \"title\": \"Stars\",\n      \"type\": \"string\",\n      \"description\": \"Keep only properties with this star rating, or any star rating.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"0\",\n        \"1\",\n        \"2\",\n        \"3\",\n        \"4\",\n        \"5\"\n      ],\n      \"enumTitles\": [\n        \"Any stars\",\n        \"1 star\",\n        \"2 stars\",\n        \"3 stars\",\n        \"4 stars\",\n        \"5 stars\"\n      ],\n      \"default\": \"0\",\n      \"prefill\": \"0\"\n    },\n    \"freeCancellation\": {\n      \"title\": \"Free cancellation only\",\n      \"type\": \"boolean\",\n      \"description\": \"Return properties with at least one free-cancellation rate.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"breakfast\": {\n      \"title\": \"Breakfast included only\",\n      \"type\": \"boolean\",\n      \"description\": \"Return properties with a breakfast-included rate.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"pool\": {\n      \"title\": \"Swimming pool only\",\n      \"type\": \"boolean\",\n      \"description\": \"Return properties that have a swimming pool.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"minPrice\": {\n      \"title\": \"Minimum price per night\",\n      \"type\": \"number\",\n      \"description\": \"Optional lower bound for the nightly price in the chosen currency.\",\n      \"minimum\": 0\n    },\n    \"maxPrice\": {\n      \"title\": \"Maximum price per night\",\n      \"type\": \"number\",\n      \"description\": \"Optional upper bound for the nightly price in the chosen currency.\",\n      \"minimum\": 0\n    },\n    \"currency\": {\n      \"title\": \"Currency\",\n      \"type\": \"string\",\n      \"description\": \"Three-letter currency code such as USD, EUR or GBP.\",\n      \"editor\": \"textfield\",\n      \"default\": \"USD\",\n      \"prefill\": \"USD\"\n    },\n    \"language\": {\n      \"title\": \"Language\",\n      \"type\": \"string\",\n      \"description\": \"Language Booking.com should use for the pages.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"en-us\",\n        \"en-gb\",\n        \"de\",\n        \"fr\",\n        \"es\",\n        \"it\",\n        \"pt-br\",\n        \"nl\",\n        \"ja\",\n        \"zh-cn\"\n      ],\n      \"enumTitles\": [\n        \"English (US)\",\n        \"English (UK)\",\n        \"German\",\n        \"French\",\n        \"Spanish\",\n        \"Italian\",\n        \"Portuguese (Brazil)\",\n        \"Dutch\",\n        \"Japanese\",\n        \"Chinese\"\n      ],\n      \"default\": \"en-us\",\n      \"prefill\": \"en-us\"\n    },\n    \"maxItems\": {\n      \"title\": \"Maximum results\",\n      \"type\": \"integer\",\n      \"description\": \"Stop after this many hotels.\",\n      \"default\": 10,\n      \"prefill\": 2,\n      \"minimum\": 1,\n      \"maximum\": 250\n    },\n    \"proxyConfiguration\": {\n      \"title\": \"Proxy configuration\",\n      \"type\": \"object\",\n      \"description\": \"Optional. Leave empty to connect directly; the actor automatically retries with Apify proxy if Booking.com blocks the direct connection.\",\n      \"editor\": \"proxy\"\n    }\n  },\n  \"required\": []\n}",
    "readme": "# Booking.com Hotel Price & Rating Snapshot Scraper\n\nPull a clean price-and-rating snapshot from Booking.com for a destination or a list of hotel URLs. This actor is built for speed: it reads search cards in search mode, or a hotel's own page in details mode, and returns flat JSON rows you can compare, schedule or load into a spreadsheet.\n\n## Two ways to use it\n\n| Mode | What it reads | Best for |\n|---|---|---|\n| **Search a destination** | Booking.com search result cards, expanded with the page's own \"Load more results\" control | Rate shopping across a city, market snapshots, price monitoring |\n| **Load hotel URLs** | Each hotel's Booking.com page (price and rating block) | Checking specific properties you already track |\n\nSearch mode never opens individual hotel pages, so it stays fast even at the 250-row cap. Details mode opens the pages you pass in and returns the property's own current rate, star rating and coordinates.\n\n## Output per hotel\n\nEvery row uses the same field names in both modes. Fields that do not apply to a mode are omitted.\n\n- `hotelId` — Booking.com property identifier from the URL\n- `name` — property name\n- `url` — canonical Booking.com property URL\n- `propertyType` — accommodation type (details mode)\n- `stars` — official star rating (1-5)\n- `address` — street address (details) or district and city (search)\n- `city`, `country`\n- `latitude`, `longitude` — map coordinates (details mode)\n- `distance` — distance from downtown as shown on the search card\n- `rating` — guest score on Booking.com's 0-10 scale\n- `reviewCount` — number of guest reviews\n- `reviewWord` — score label such as \"Wonderful\" or \"Very Good\"\n- `price` — price for the whole stay in the requested currency\n- `pricePerNight` — `price` divided by the number of nights\n- `originalPrice`, `discountPercent` — visible struck-through price and discount\n- `taxesAndFees` — taxes and fees shown with the rate\n- `currency` — three-letter currency code\n- `photoUrl` — main property photo\n- `checkin`, `checkout`, `nights`, `adults`, `rooms` — the search parameters used\n- `mode` — `search` or `details`\n- `detailStatus` — `search_only` or `enriched`\n- `source` — `booking.com`\n- `accessMethod` — `translate_mirror` or `browser+translate_mirror` when the direct/proxy paths were challenged\n- `scrapedAt` — capture timestamp in ISO 8601\n\n## Input\n\n| Field | Type | Default | Notes |\n|---|---|---|---|\n| `mode` | select | `search` | `search` for a destination, `details` for hotel URLs |\n| `destination` | string | — | City, region or landmark; required in search mode (prefilled with `Paris`) |\n| `startUrls` | array | — | Booking.com hotel links used by details mode (prefilled with one Paris hotel) |\n| `checkIn` | string | — | `YYYY-MM-DD`; empty means tomorrow |\n| `checkOut` | string | — | `YYYY-MM-DD`, must be after check-in; empty means check-in + 3 nights |\n| `adults` | integer | `2` | 1-30 |\n| `rooms` | integer | `1` | 1-30 |\n| `propertyType` | select | `all` | Hotels, apartments, hostels, guesthouses, villas or resorts |\n| `minReviewScore` | number | `0` | 0-10 exact minimum after Booking.com's own filter |\n| `stars` | select | `0` (any) | 1-5 |\n| `freeCancellation` | boolean | `false` | Only properties with a free-cancellation rate |\n| `breakfast` | boolean | `false` | Only properties with a breakfast-included rate |\n| `pool` | boolean | `false` | Only properties with a swimming pool |\n| `minPrice`, `maxPrice` | number | — | Nightly price bounds in the chosen currency |\n| `currency` | string | `USD` | `EUR`, `GBP`, `JPY`, etc. |\n| `language` | select | `en-us` | Page language used for the request |\n| `maxItems` | integer | `10` | 1-250 |\n| `proxyConfiguration` | object | Direct | Optional; without it the actor tries direct, then the free translate-mirror fallback, then Apify proxy |\n\nThe old input names are still accepted by the code: `location` maps to `destination`, `checkinDate`/`checkoutDate` map to `checkIn`/`checkOut`, and `maxResults` maps to `maxItems`.\n\n## Examples\n\nWeekend price check for Lisbon:\n\n```json\n{\n  \"mode\": \"search\",\n  \"destination\": \"Lisbon\",\n  \"checkIn\": \"2026-11-20\",\n  \"checkOut\": \"2026-11-23\",\n  \"currency\": \"EUR\",\n  \"maxItems\": 30\n}\n```\n\nTrack two specific hotels:\n\n```json\n{\n  \"mode\": \"details\",\n  \"startUrls\": [\n    { \"url\": \"https://www.booking.com/hotel/fr/du-printemps-paris.html\" },\n    { \"url\": \"https://www.booking.com/hotel/fr/sorbonne.html\" }\n  ],\n  \"checkIn\": \"2026-12-01\",\n  \"checkOut\": \"2026-12-04\",\n  \"adults\": 2,\n  \"rooms\": 1\n}\n```\n\nWell-rated hotels with free cancellation:\n\n```json\n{\n  \"mode\": \"search\",\n  \"destination\": \"Berlin\",\n  \"propertyType\": \"hotels\",\n  \"minReviewScore\": 8.5,\n  \"freeCancellation\": true,\n  \"maxItems\": 20\n}\n```\n\n## How pagination works\n\nBooking.com returns a first batch of cards and adds more when its own \"Load more results\" control is clicked. The actor keeps clicking that control and scrolling until it reaches `maxItems` or the page stops growing. When the live site is WAF-challenged, the translate-mirror fallback reads successive result pages across several sort orders and deduplicates by hotel URL. The practical ceiling is 250 rows per run; split a large market by neighborhood, dates or filters to collect more.\n\n## FAQ\n\n**Do I need a Booking.com account?**\nNo. The actor reads public search and hotel pages. No login, cookie or API key is required.\n\n**Do I need to configure a proxy?**\nNo. The actor connects directly first. If Booking.com challenges that connection, it retries through Google Translate's public mirror (no proxy or key) and only then falls back to Apify proxy groups. `accessMethod` tells you which path produced each row.\n\n**Is `price` per night or for the whole stay?**\n`price` is the full stay price Booking.com shows for your dates. `pricePerNight` divides it by `nights`.\n\n**Why is a field missing from some rows?**\nSearch cards and hotel pages expose different data. Coordinates and `propertyType` usually come from a hotel page, while `distance` comes from a search card. Empty values are omitted rather than filled with zeros or placeholders.\n\n**What happens when a hotel has no available rate?**\nDetails mode skips that hotel and reports a partial result. If every page fails, the run fails with a clear status instead of writing empty rows.\n\n**Can I scrape more than one destination in one run?**\nYes at the task level: one run is one destination. Create one task per city, or use details mode with a URL list.\n\n**Are prices guaranteed to match the live site a minute later?**\nNo. Availability and prices change continuously. Each row records `scrapedAt` so you can tell exactly when the snapshot was taken.\n\n**Is this affiliated with Booking.com?**\nNo. It is an independent third-party tool that reads publicly available Booking.com pages.\n\n## Limitations\n\n- Search mode returns what the search page exposes: price, rating, stars, address and distance. It does not open each property, so room types, amenities and full policies are not included.\n- Details mode reads the property page but does not wait for every lazy-loaded section; it returns the price/rating snapshot rather than a full facilities catalogue.\n- Booking.com caps how many search results it will page through, and the actor caps a single run at 250 rows.\n- Sold-out properties can be missing a rate. They are skipped in details mode and may be absent from search results.\n- Booking.com serves more than one search layout. Some sessions expose stars and the load-more control, while a stripped mirror variant exposes cards without star icons. The actor reads whatever the page provides and never invents missing values; price, score and review count remain available.\n- Booking.com can challenge direct, AUTO and residential exits with HTTP 202. The translate-mirror fallback normally recovers search and hotel pages; it can rate-limit (HTTP 429), serve a cached page, or omit a result batch. If every path fails the run stops with `BLOCKED` instead of returning empty or invented rows. Mirror rows are marked `accessMethod: translate_mirror`.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "booking-com-hotel-price-and-rating-snapshot",
      "title": "Booking.com Hotel Price & Rating Snapshot Scraper",
      "description": "Search Booking.com or paste hotel URLs to collect nightly prices, guest scores, review counts, stars, addresses and coordinates for your stay dates.",
      "version": "2.0",
      "input": {
        "title": "Booking.com Hotel Price & Rating Snapshot Input",
        "description": "Choose a destination or paste hotel URLs, set your stay dates, and collect Booking.com prices, guest scores and review counts.",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "mode": {
            "title": "What to scrape",
            "type": "string",
            "description": "Search a destination for hotel prices, or load specific Booking.com hotel pages.",
            "editor": "select",
            "enum": [
              "search",
              "details"
            ],
            "enumTitles": [
              "Search a destination",
              "Load hotel URLs"
            ],
            "default": "search",
            "prefill": "search"
          },
          "destination": {
            "title": "Destination",
            "type": "string",
            "description": "City, region or landmark to search, e.g. Paris, New York or Tokyo. Required in search mode.",
            "editor": "textfield",
            "prefill": "Paris"
          },
          "startUrls": {
            "title": "Hotel URLs",
            "type": "array",
            "description": "Booking.com hotel page URLs, used in details mode. Copy links from a search result or your browser.",
            "editor": "requestListSources",
            "default": [],
            "prefill": [
              {
                "url": "https://www.booking.com/hotel/fr/du-printemps-paris.html"
              }
            ]
          },
          "checkIn": {
            "title": "Check-in date",
            "type": "string",
            "description": "Check-in date as YYYY-MM-DD. Leave empty to use tomorrow.",
            "editor": "textfield"
          },
          "checkOut": {
            "title": "Check-out date",
            "type": "string",
            "description": "Check-out date as YYYY-MM-DD. Leave empty to use a 3-night stay.",
            "editor": "textfield"
          },
          "adults": {
            "title": "Adults",
            "type": "integer",
            "description": "Number of adult guests.",
            "default": 2,
            "prefill": 2,
            "minimum": 1,
            "maximum": 30
          },
          "rooms": {
            "title": "Rooms",
            "type": "integer",
            "description": "Number of rooms needed.",
            "default": 1,
            "prefill": 1,
            "minimum": 1,
            "maximum": 30
          },
          "propertyType": {
            "title": "Property type",
            "type": "string",
            "description": "Keep only one Booking.com property type, or search all types.",
            "editor": "select",
            "enum": [
              "all",
              "hotels",
              "apartments",
              "hostels",
              "guesthouses",
              "villas",
              "resorts"
            ],
            "enumTitles": [
              "All types",
              "Hotels",
              "Apartments",
              "Hostels",
              "Guesthouses",
              "Villas",
              "Resorts"
            ],
            "default": "all",
            "prefill": "all"
          },
          "minReviewScore": {
            "title": "Minimum review score",
            "type": "number",
            "description": "Minimum guest score from 0 to 10. The actor applies Booking.com's score filter and keeps only properties at or above this exact score.",
            "default": 0,
            "minimum": 0,
            "maximum": 10
          },
          "stars": {
            "title": "Stars",
            "type": "string",
            "description": "Keep only properties with this star rating, or any star rating.",
            "editor": "select",
            "enum": [
              "0",
              "1",
              "2",
              "3",
              "4",
              "5"
            ],
            "enumTitles": [
              "Any stars",
              "1 star",
              "2 stars",
              "3 stars",
              "4 stars",
              "5 stars"
            ],
            "default": "0",
            "prefill": "0"
          },
          "freeCancellation": {
            "title": "Free cancellation only",
            "type": "boolean",
            "description": "Return properties with at least one free-cancellation rate.",
            "default": false,
            "prefill": false
          },
          "breakfast": {
            "title": "Breakfast included only",
            "type": "boolean",
            "description": "Return properties with a breakfast-included rate.",
            "default": false,
            "prefill": false
          },
          "pool": {
            "title": "Swimming pool only",
            "type": "boolean",
            "description": "Return properties that have a swimming pool.",
            "default": false,
            "prefill": false
          },
          "minPrice": {
            "title": "Minimum price per night",
            "type": "number",
            "description": "Optional lower bound for the nightly price in the chosen currency.",
            "minimum": 0
          },
          "maxPrice": {
            "title": "Maximum price per night",
            "type": "number",
            "description": "Optional upper bound for the nightly price in the chosen currency.",
            "minimum": 0
          },
          "currency": {
            "title": "Currency",
            "type": "string",
            "description": "Three-letter currency code such as USD, EUR or GBP.",
            "editor": "textfield",
            "default": "USD",
            "prefill": "USD"
          },
          "language": {
            "title": "Language",
            "type": "string",
            "description": "Language Booking.com should use for the pages.",
            "editor": "select",
            "enum": [
              "en-us",
              "en-gb",
              "de",
              "fr",
              "es",
              "it",
              "pt-br",
              "nl",
              "ja",
              "zh-cn"
            ],
            "enumTitles": [
              "English (US)",
              "English (UK)",
              "German",
              "French",
              "Spanish",
              "Italian",
              "Portuguese (Brazil)",
              "Dutch",
              "Japanese",
              "Chinese"
            ],
            "default": "en-us",
            "prefill": "en-us"
          },
          "maxItems": {
            "title": "Maximum results",
            "type": "integer",
            "description": "Stop after this many hotels.",
            "default": 10,
            "prefill": 2,
            "minimum": 1,
            "maximum": 250
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Optional. Leave empty to connect directly; the actor automatically retries with Apify proxy if Booking.com blocks the direct connection.",
            "editor": "proxy"
          }
        },
        "required": []
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "Booking.com Hotel Price & Rating Snapshot Output",
        "description": "One row per Booking.com property with the stay price, nightly price, guest score, review count, star rating, location and stay dates.",
        "properties": {
          "hotels": {
            "type": "string",
            "title": "Hotel snapshots",
            "description": "Dataset containing every scraped Booking.com hotel snapshot.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "dockerfile": "../Dockerfile",
      "readme": "# Booking.com Hotel Price & Rating Snapshot Scraper\n\nPull a clean price-and-rating snapshot from Booking.com for a destination or a list of hotel URLs. This actor is built for speed: it reads search cards in search mode, or a hotel's own page in details mode, and returns flat JSON rows you can compare, schedule or load into a spreadsheet.\n\n## Two ways to use it\n\n| Mode | What it reads | Best for |\n|---|---|---|\n| **Search a destination** | Booking.com search result cards, expanded with the page's own \"Load more results\" control | Rate shopping across a city, market snapshots, price monitoring |\n| **Load hotel URLs** | Each hotel's Booking.com page (price and rating block) | Checking specific properties you already track |\n\nSearch mode never opens individual hotel pages, so it stays fast even at the 250-row cap. Details mode opens the pages you pass in and returns the property's own current rate, star rating and coordinates.\n\n## Output per hotel\n\nEvery row uses the same field names in both modes. Fields that do not apply to a mode are omitted.\n\n- `hotelId` — Booking.com property identifier from the URL\n- `name` — property name\n- `url` — canonical Booking.com property URL\n- `propertyType` — accommodation type (details mode)\n- `stars` — official star rating (1-5)\n- `address` — street address (details) or district and city (search)\n- `city`, `country`\n- `latitude`, `longitude` — map coordinates (details mode)\n- `distance` — distance from downtown as shown on the search card\n- `rating` — guest score on Booking.com's 0-10 scale\n- `reviewCount` — number of guest reviews\n- `reviewWord` — score label such as \"Wonderful\" or \"Very Good\"\n- `price` — price for the whole stay in the requested currency\n- `pricePerNight` — `price` divided by the number of nights\n- `originalPrice`, `discountPercent` — visible struck-through price and discount\n- `taxesAndFees` — taxes and fees shown with the rate\n- `currency` — three-letter currency code\n- `photoUrl` — main property photo\n- `checkin`, `checkout`, `nights`, `adults`, `rooms` — the search parameters used\n- `mode` — `search` or `details`\n- `detailStatus` — `search_only` or `enriched`\n- `source` — `booking.com`\n- `accessMethod` — `translate_mirror` or `browser+translate_mirror` when the direct/proxy paths were challenged\n- `scrapedAt` — capture timestamp in ISO 8601\n\n## Input\n\n| Field | Type | Default | Notes |\n|---|---|---|---|\n| `mode` | select | `search` | `search` for a destination, `details` for hotel URLs |\n| `destination` | string | — | City, region or landmark; required in search mode (prefilled with `Paris`) |\n| `startUrls` | array | — | Booking.com hotel links used by details mode (prefilled with one Paris hotel) |\n| `checkIn` | string | — | `YYYY-MM-DD`; empty means tomorrow |\n| `checkOut` | string | — | `YYYY-MM-DD`, must be after check-in; empty means check-in + 3 nights |\n| `adults` | integer | `2` | 1-30 |\n| `rooms` | integer | `1` | 1-30 |\n| `propertyType` | select | `all` | Hotels, apartments, hostels, guesthouses, villas or resorts |\n| `minReviewScore` | number | `0` | 0-10 exact minimum after Booking.com's own filter |\n| `stars` | select | `0` (any) | 1-5 |\n| `freeCancellation` | boolean | `false` | Only properties with a free-cancellation rate |\n| `breakfast` | boolean | `false` | Only properties with a breakfast-included rate |\n| `pool` | boolean | `false` | Only properties with a swimming pool |\n| `minPrice`, `maxPrice` | number | — | Nightly price bounds in the chosen currency |\n| `currency` | string | `USD` | `EUR`, `GBP`, `JPY`, etc. |\n| `language` | select | `en-us` | Page language used for the request |\n| `maxItems` | integer | `10` | 1-250 |\n| `proxyConfiguration` | object | Direct | Optional; without it the actor tries direct, then the free translate-mirror fallback, then Apify proxy |\n\nThe old input names are still accepted by the code: `location` maps to `destination`, `checkinDate`/`checkoutDate` map to `checkIn`/`checkOut`, and `maxResults` maps to `maxItems`.\n\n## Examples\n\nWeekend price check for Lisbon:\n\n```json\n{\n  \"mode\": \"search\",\n  \"destination\": \"Lisbon\",\n  \"checkIn\": \"2026-11-20\",\n  \"checkOut\": \"2026-11-23\",\n  \"currency\": \"EUR\",\n  \"maxItems\": 30\n}\n```\n\nTrack two specific hotels:\n\n```json\n{\n  \"mode\": \"details\",\n  \"startUrls\": [\n    { \"url\": \"https://www.booking.com/hotel/fr/du-printemps-paris.html\" },\n    { \"url\": \"https://www.booking.com/hotel/fr/sorbonne.html\" }\n  ],\n  \"checkIn\": \"2026-12-01\",\n  \"checkOut\": \"2026-12-04\",\n  \"adults\": 2,\n  \"rooms\": 1\n}\n```\n\nWell-rated hotels with free cancellation:\n\n```json\n{\n  \"mode\": \"search\",\n  \"destination\": \"Berlin\",\n  \"propertyType\": \"hotels\",\n  \"minReviewScore\": 8.5,\n  \"freeCancellation\": true,\n  \"maxItems\": 20\n}\n```\n\n## How pagination works\n\nBooking.com returns a first batch of cards and adds more when its own \"Load more results\" control is clicked. The actor keeps clicking that control and scrolling until it reaches `maxItems` or the page stops growing. When the live site is WAF-challenged, the translate-mirror fallback reads successive result pages across several sort orders and deduplicates by hotel URL. The practical ceiling is 250 rows per run; split a large market by neighborhood, dates or filters to collect more.\n\n## FAQ\n\n**Do I need a Booking.com account?**\nNo. The actor reads public search and hotel pages. No login, cookie or API key is required.\n\n**Do I need to configure a proxy?**\nNo. The actor connects directly first. If Booking.com challenges that connection, it retries through Google Translate's public mirror (no proxy or key) and only then falls back to Apify proxy groups. `accessMethod` tells you which path produced each row.\n\n**Is `price` per night or for the whole stay?**\n`price` is the full stay price Booking.com shows for your dates. `pricePerNight` divides it by `nights`.\n\n**Why is a field missing from some rows?**\nSearch cards and hotel pages expose different data. Coordinates and `propertyType` usually come from a hotel page, while `distance` comes from a search card. Empty values are omitted rather than filled with zeros or placeholders.\n\n**What happens when a hotel has no available rate?**\nDetails mode skips that hotel and reports a partial result. If every page fails, the run fails with a clear status instead of writing empty rows.\n\n**Can I scrape more than one destination in one run?**\nYes at the task level: one run is one destination. Create one task per city, or use details mode with a URL list.\n\n**Are prices guaranteed to match the live site a minute later?**\nNo. Availability and prices change continuously. Each row records `scrapedAt` so you can tell exactly when the snapshot was taken.\n\n**Is this affiliated with Booking.com?**\nNo. It is an independent third-party tool that reads publicly available Booking.com pages.\n\n## Limitations\n\n- Search mode returns what the search page exposes: price, rating, stars, address and distance. It does not open each property, so room types, amenities and full policies are not included.\n- Details mode reads the property page but does not wait for every lazy-loaded section; it returns the price/rating snapshot rather than a full facilities catalogue.\n- Booking.com caps how many search results it will page through, and the actor caps a single run at 250 rows.\n- Sold-out properties can be missing a rate. They are skipped in details mode and may be absent from search results.\n- Booking.com serves more than one search layout. Some sessions expose stars and the load-more control, while a stripped mirror variant exposes cards without star icons. The actor reads whatever the page provides and never invents missing values; price, score and review count remain available.\n- Booking.com can challenge direct, AUTO and residential exits with HTTP 202. The translate-mirror fallback normally recovers search and hotel pages; it can rate-limit (HTTP 429), serve a cached page, or omit a result batch. If every path fails the run stops with `BLOCKED` instead of returning empty or invented rows. Mirror rows are marked `accessMethod: translate_mirror`.\n",
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "title": "Booking.com Hotel Snapshots",
          "fields": {
            "type": "object",
            "properties": {
              "hotelId": {
                "type": "string",
                "description": "Booking.com hotel identifier"
              },
              "name": {
                "type": "string",
                "description": "Hotel or property name"
              },
              "url": {
                "type": "string",
                "description": "Canonical Booking.com hotel URL"
              },
              "propertyType": {
                "type": "string",
                "description": "Accommodation type"
              },
              "stars": {
                "type": "integer",
                "description": "Star rating (1-5)"
              },
              "address": {
                "type": "string",
                "description": "Street address or district and city"
              },
              "city": {
                "type": "string",
                "description": "City name"
              },
              "country": {
                "type": "string",
                "description": "Country name"
              },
              "latitude": {
                "type": "number",
                "description": "Latitude"
              },
              "longitude": {
                "type": "number",
                "description": "Longitude"
              },
              "distance": {
                "type": "string",
                "description": "Distance from downtown on the search result"
              },
              "rating": {
                "type": "number",
                "description": "Guest review score (0-10)"
              },
              "reviewCount": {
                "type": "integer",
                "description": "Number of guest reviews"
              },
              "reviewWord": {
                "type": "string",
                "description": "Rating label (Wonderful, Excellent, Very Good, Good, etc.)"
              },
              "price": {
                "type": "number",
                "description": "Stay price for the requested dates"
              },
              "pricePerNight": {
                "type": "number",
                "description": "Nightly price"
              },
              "originalPrice": {
                "type": "number",
                "description": "Price before a visible discount"
              },
              "currency": {
                "type": "string",
                "description": "Currency code"
              },
              "discountPercent": {
                "type": "number",
                "description": "Visible discount percentage"
              },
              "taxesAndFees": {
                "type": "number",
                "description": "Taxes and fees shown for the stay"
              },
              "photoUrl": {
                "type": "string",
                "description": "Main photo URL"
              },
              "checkin": {
                "type": "string",
                "description": "Check-in date (YYYY-MM-DD)"
              },
              "checkout": {
                "type": "string",
                "description": "Check-out date (YYYY-MM-DD)"
              },
              "nights": {
                "type": "integer",
                "description": "Number of nights"
              },
              "adults": {
                "type": "integer",
                "description": "Number of adults"
              },
              "rooms": {
                "type": "integer",
                "description": "Number of rooms"
              },
              "mode": {
                "type": "string",
                "description": "search or details"
              },
              "detailStatus": {
                "type": "string",
                "description": "search_only or enriched"
              },
              "source": {
                "type": "string",
                "description": "Data source"
              },
              "scrapedAt": {
                "type": "string",
                "description": "Scrape timestamp (ISO 8601)"
              },
              "accessMethod": {
                "type": "string",
                "description": "Access path used: direct, proxy, or translate_mirror"
              }
            }
          },
          "views": {
            "overview": {
              "title": "Hotel snapshots",
              "transformation": {
                "fields": [
                  "name",
                  "price",
                  "currency",
                  "pricePerNight",
                  "rating",
                  "reviewCount",
                  "reviewWord",
                  "stars",
                  "city",
                  "distance",
                  "url"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "name": {
                    "label": "Hotel",
                    "format": "text"
                  },
                  "price": {
                    "label": "Stay price",
                    "format": "number"
                  },
                  "currency": {
                    "label": "Currency",
                    "format": "text"
                  },
                  "pricePerNight": {
                    "label": "Per night",
                    "format": "number"
                  },
                  "rating": {
                    "label": "Rating",
                    "format": "number"
                  },
                  "reviewCount": {
                    "label": "Reviews",
                    "format": "number"
                  },
                  "reviewWord": {
                    "label": "Score",
                    "format": "text"
                  },
                  "stars": {
                    "label": "Stars",
                    "format": "number"
                  },
                  "city": {
                    "label": "City",
                    "format": "text"
                  },
                  "distance": {
                    "label": "Distance",
                    "format": "text"
                  },
                  "url": {
                    "label": "URL",
                    "format": "link"
                  }
                }
              }
            }
          }
        }
      }
    },
    "buildNumber": "2.0.1",
    "imageDigest": "68c568bddf0bfb157630ef3f59036a82f3234258f4b73d9535b95225f55befc5",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "2.0"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.14062444444444444
    }
  }
}