{
  "data": {
    "id": "1WpFEhMVGrBpK1a3q",
    "actId": "sWIaAOuau5dEgTrPA",
    "userId": "IYgBDiXtHOijAaUel",
    "startedAt": "2026-11-12T07:21:21.626Z",
    "finishedAt": "2026-11-12T07:22:14.160Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 52467,
      "runTimeSecs": 52.467,
      "computeUnits": 0.05829666666666666,
      "imageSizeBytes": 6120127488
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "QYo53EZkJk0prePWY",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Booking.com Hotel Search & Details Scraper\",\n  \"description\": \"Search Booking.com or load hotel URLs, then collect prices, rooms, ratings, amenities, photos and policies for your travel dates.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"mode\": {\n      \"title\": \"What to scrape\",\n      \"type\": \"string\",\n      \"description\": \"Search a destination, or load specific Booking.com hotel URLs.\",\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 then 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      \"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      \"editor\": \"select\"\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      \"maximum\": 1000000\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      \"maximum\": 1000000\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\": 3,\n      \"prefill\": 1,\n      \"minimum\": 1,\n      \"maximum\": 250\n    },\n    \"includeRooms\": {\n      \"title\": \"Include room types\",\n      \"type\": \"boolean\",\n      \"description\": \"Add the room and rate table for each hotel. Turn off for a smaller, faster dataset.\",\n      \"default\": true,\n      \"prefill\": false\n    },\n    \"includeFullAmenities\": {\n      \"title\": \"Include full amenity list\",\n      \"type\": \"boolean\",\n      \"description\": \"Render each hotel page in a browser to collect the complete facility list. Slower and only needed when you want every amenity.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"proxyConfiguration\": {\n      \"title\": \"Proxy configuration\",\n      \"type\": \"object\",\n      \"description\": \"Optional proxy override. The actor selects Apify's proxy automatically; no setup is needed.\",\n      \"editor\": \"proxy\",\n      \"prefill\": {\n        \"useApifyProxy\": true\n      }\n    }\n  },\n  \"required\": []\n}",
    "readme": "# Booking.com Hotel Search & Details Scraper\r\n\r\nSearch Booking.com for a destination and travel dates, or paste hotel links directly, and get one row per property with the stay price, room and rate options, guest scores, review subscores, facilities, photos, description and booking policies.\r\n\r\n## What this actor does\r\n\r\n- **Search mode** runs a Booking.com destination search for your dates, guests and filters, then scrolls and clicks **Load more results** to go beyond the first page. It collects up to 250 properties per run.\r\n- **Details mode** loads Booking.com hotel URLs you provide and returns the same rich row for each one.\r\n- Solves Booking.com's AWS WAF challenge once in a browser, then reuses the session cookie over HTTP for the rest of the run. If a detail request is challenged again, the actor refreshes the cookie and falls back to the browser for that page.\r\n- Applies Booking.com's own filters for property type, review score, stars, free cancellation, breakfast, pool and nightly price.\r\n- Returns the cheapest room-table price for the whole stay, plus every room and rate option when `includeRooms` is on.\r\n- Optionally renders each hotel in a browser to collect the complete facility list, not just the headline amenities.\r\n- If some detail pages fail, the run finishes with a `PARTIAL` warning and keeps the search rows instead of failing the whole run.\r\n\r\n## Output per hotel\r\n\r\n| Field | What it contains |\r\n|---|---|\r\n| `hotelId`, `name`, `url` | Property identity and its Booking.com page |\r\n| `propertyType`, `stars` | Property type and star rating |\r\n| `address`, `city`, `country` | Full address and location |\r\n| `latitude`, `longitude` | Map coordinates |\r\n| `distance` | Distance from the city centre as Booking.com shows it |\r\n| `rating`, `reviewCount`, `reviewWord` | Guest score, number of reviews and Booking.com's label |\r\n| `reviewSubscores` | Category scores such as Location, Cleanliness and Staff |\r\n| `price`, `pricePerNight`, `currency` | Cheapest total for the stay, nightly equivalent and ISO currency code |\r\n| `originalPrice`, `discountPercent` | Pre-discount price and discount percentage when a deal is shown |\r\n| `taxesAndFees`, `priceWithTaxes` | Taxes and fees for the cheapest rate and the resulting total |\r\n| `roomTypes` | Room name, rate-plan count, price, original price, total, taxes, breakfast, cancellation, sleeps, bed, size and room amenities |\r\n| `topAmenities`, `fullAmenities` | Headline facilities, plus the complete list when `includeFullAmenities` is on |\r\n| `amenities` | Amenity keywords found on the search card |\r\n| `photos`, `photoUrl` | Photo URLs and the main image |\r\n| `description` | Property description |\r\n| `breakfastIncluded`, `breakfastAvailable`, `breakfastPrice` | Whether breakfast is included, merely available, or paid separately |\r\n| `freeCancellation` | Whether a free-cancellation rate exists |\r\n| `checkinTime`, `checkoutTime` | Property check-in and check-out times |\r\n| `checkin`, `checkout`, `nights`, `adults`, `rooms` | The stay used for pricing |\r\n| `mode`, `detailStatus`, `source`, `scrapedAt` | Run metadata and enrichment status |\r\n\r\nEmpty values are omitted from a record instead of being written as `null`.\r\n\r\n## Input\r\n\r\n| Field | Type | Default | Description |\r\n|---|---|---|---|\r\n| `mode` | select | `search` | `search` a destination or load hotel `details` |\r\n| `destination` | string | – | City, region or landmark; required in search mode |\r\n| `startUrls` | array | `[]` | Booking.com hotel URLs; required in details mode |\r\n| `checkIn` | string | - | Check-in date (`YYYY-MM-DD`); empty uses tomorrow |\r\n| `checkOut` | string | - | Check-out date (`YYYY-MM-DD`); empty uses a 3-night stay |\r\n| `adults` | integer | `2` | Adult guests (1–30) |\r\n| `rooms` | integer | `1` | Rooms needed (1–30) |\r\n| `propertyType` | select | `all` | All, hotels, apartments, hostels, guesthouses, villas or resorts |\r\n| `minReviewScore` | number | `0` | Minimum guest score (0–10) |\r\n| `stars` | select | `0` | Exact star rating, or any |\r\n| `freeCancellation` | boolean | `false` | Keep properties with a free-cancellation rate |\r\n| `breakfast` | boolean | `false` | Keep properties with breakfast included |\r\n| `pool` | boolean | `false` | Keep properties with a swimming pool |\r\n| `minPrice`, `maxPrice` | number | – | Nightly price bounds in the chosen currency |\r\n| `currency` | string | `USD` | Three-letter currency code |\r\n| `language` | select | `en-us` | Page language |\r\n| `maxItems` | integer | `3` | Maximum hotels to return (1–250) |\r\n| `includeRooms` | boolean | `true` | Add the room and rate table |\r\n| `includeFullAmenities` | boolean | `false` | Render each hotel page to collect every facility |\r\n| `proxyConfiguration` | object | Automatic | Optional proxy override; the actor selects the Apify proxy automatically |\r\n\r\n### Example: search Paris for three nights\r\n\r\n```json\r\n{\r\n  \"mode\": \"search\",\r\n  \"destination\": \"Paris\",\r\n  \"checkIn\": \"2026-11-13\",\r\n  \"checkOut\": \"2026-11-16\",\r\n  \"adults\": 2,\r\n  \"rooms\": 1,\r\n  \"maxItems\": 3,\r\n  \"includeFullAmenities\": false\r\n}\r\n```\r\n\r\n### Example: five-star hotels with a pool and free cancellation\r\n\r\n```json\r\n{\r\n  \"mode\": \"search\",\r\n  \"destination\": \"Barcelona\",\r\n  \"checkIn\": \"2026-11-13\",\r\n  \"checkOut\": \"2026-11-16\",\r\n  \"stars\": 5,\r\n  \"pool\": true,\r\n  \"freeCancellation\": true,\r\n  \"minReviewScore\": 8,\r\n  \"currency\": \"EUR\",\r\n  \"maxItems\": 25\r\n}\r\n```\r\n\r\n### Example: load specific hotel pages\r\n\r\n```json\r\n{\r\n  \"mode\": \"details\",\r\n  \"startUrls\": [\r\n    { \"url\": \"https://www.booking.com/hotel/fr/sorbonne.html\" },\r\n    { \"url\": \"https://www.booking.com/hotel/fr/moxy-paris-la-villette.html\" }\r\n  ],\r\n  \"checkIn\": \"2026-11-13\",\r\n  \"checkOut\": \"2026-11-16\",\r\n  \"includeRooms\": true,\r\n  \"includeFullAmenities\": true\r\n}\r\n```\r\n\r\n## Use cases\r\n\r\n- **Price comparison** — compare stay totals for the same dates across a destination\r\n- **Rate tracking** — schedule runs to watch prices and discounts move\r\n- **Room-level analysis** — compare room types, breakfast and cancellation terms\r\n- **Travel apps and spreadsheets** — feed structured hotel data into your own tools\r\n- **Market research** — analyse ratings, review subscores and facilities by city or property type\r\n\r\n## FAQ\r\n\r\n**Do I need a Booking.com account?**\r\nNo. The actor reads public hotel and search pages. It solves the site's technical challenge without you providing cookies or a login.\r\n\r\n**Why does the first request take longer?**\r\nBooking.com uses an AWS WAF JavaScript challenge. The actor opens one browser page to solve it, then reuses the resulting cookie over HTTP. That bootstrap is a few seconds per run.\r\n\r\n**What does `price` mean?**\r\nIt is the cheapest total for the whole stay, for the dates, guest count and room count in your input. `pricePerNight` divides that total by the number of nights. Use `originalPrice` when Booking.com shows a strike-through price.\r\n\r\n**Why do some prices differ from the search card?**\r\nThe search card can show a promotional or selected-room price. The detail parser takes the cheapest valid room-table price, which is the same number Booking.com uses for the cheapest rate on that page.\r\n\r\n**Why is `fullAmenities` missing?**\r\nIt is only collected when `includeFullAmenities` is on. That setting renders a hotel page in a browser, so it is slower and costs more than the default HTTP-only detail fetch.\r\n\r\n**What happens when Booking.com blocks the run?**\r\nThe actor selects its proxy automatically, so you do not need to configure anything. If every proxy path is blocked, it fails with a `BLOCKED` status instead of returning an empty dataset. If only some detail pages fail, it finishes with a `PARTIAL` status and keeps the rows it did collect.\r\n\r\n**What happens when a search has no results?**\r\nA valid search with no matches fails with `NO_RESULTS`, so you can tell it apart from a block. Loosen your filters or check the destination spelling.\r\n\r\n**Do the filters work in details mode?**\r\nYes. Property type, stars, review score, free cancellation, breakfast, pool and nightly price are applied to the hotel data after each detail page is parsed. Booking.com's own search filters are still used in search mode for the initial result set.\r\n\r\n**How many results can I get?**\r\nSet `maxItems` up to 250. Booking.com loads 25 cards at a time and exposes a \"Load more results\" button; the actor scrolls and clicks it until your cap or the page stops growing. Booking.com itself caps a single query at about 1,000 results. If the source or the filters run out before your cap, the run status says how many rows were actually pushed. Large detail runs can take several minutes because Booking.com challenges each hotel page separately.\r\n\r\n**Are prices and availability live?**\r\nYes. They are captured when the actor runs and can change as availability changes.\r\n\r\n**Is this affiliated with Booking.com?**\r\nNo. This is an independent third-party actor that reads publicly available Booking.com pages.\r\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "booking-com-hotel-price-and-amenity-search-scraper",
      "title": "Booking.com Hotel Search & Details Scraper",
      "description": "Search Booking.com or paste hotel URLs to get stay prices, room rates, guest scores, review subscores, amenities, photos and policies in one dataset.",
      "version": "2.0",
      "input": {
        "title": "Booking.com Hotel Search & Details Scraper",
        "description": "Search Booking.com or load hotel URLs, then collect prices, rooms, ratings, amenities, photos and policies for your travel dates.",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "mode": {
            "title": "What to scrape",
            "type": "string",
            "description": "Search a destination, or load specific Booking.com hotel URLs.",
            "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 then 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.",
            "enum": [
              "0",
              "1",
              "2",
              "3",
              "4",
              "5"
            ],
            "enumTitles": [
              "Any stars",
              "1 star",
              "2 stars",
              "3 stars",
              "4 stars",
              "5 stars"
            ],
            "default": "0",
            "prefill": "0",
            "editor": "select"
          },
          "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,
            "maximum": 1000000
          },
          "maxPrice": {
            "title": "Maximum price per night",
            "type": "number",
            "description": "Optional upper bound for the nightly price in the chosen currency.",
            "minimum": 0,
            "maximum": 1000000
          },
          "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": 3,
            "prefill": 1,
            "minimum": 1,
            "maximum": 250
          },
          "includeRooms": {
            "title": "Include room types",
            "type": "boolean",
            "description": "Add the room and rate table for each hotel. Turn off for a smaller, faster dataset.",
            "default": true,
            "prefill": false
          },
          "includeFullAmenities": {
            "title": "Include full amenity list",
            "type": "boolean",
            "description": "Render each hotel page in a browser to collect the complete facility list. Slower and only needed when you want every amenity.",
            "default": false,
            "prefill": false
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Optional proxy override. The actor selects Apify's proxy automatically; no setup is needed.",
            "editor": "proxy",
            "prefill": {
              "useApifyProxy": true
            }
          }
        },
        "required": []
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "Booking.com Hotel Search & Details Output",
        "description": "One row per Booking.com property with stay prices, room types, ratings, review subscores, amenities, photos, description and policies.",
        "properties": {
          "hotels": {
            "type": "string",
            "title": "Booking.com Hotels",
            "description": "Dataset containing every scraped Booking.com property.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "dockerfile": "../Dockerfile",
      "readme": "# Booking.com Hotel Search & Details Scraper\r\n\r\nSearch Booking.com for a destination and travel dates, or paste hotel links directly, and get one row per property with the stay price, room and rate options, guest scores, review subscores, facilities, photos, description and booking policies.\r\n\r\n## What this actor does\r\n\r\n- **Search mode** runs a Booking.com destination search for your dates, guests and filters, then scrolls and clicks **Load more results** to go beyond the first page. It collects up to 250 properties per run.\r\n- **Details mode** loads Booking.com hotel URLs you provide and returns the same rich row for each one.\r\n- Solves Booking.com's AWS WAF challenge once in a browser, then reuses the session cookie over HTTP for the rest of the run. If a detail request is challenged again, the actor refreshes the cookie and falls back to the browser for that page.\r\n- Applies Booking.com's own filters for property type, review score, stars, free cancellation, breakfast, pool and nightly price.\r\n- Returns the cheapest room-table price for the whole stay, plus every room and rate option when `includeRooms` is on.\r\n- Optionally renders each hotel in a browser to collect the complete facility list, not just the headline amenities.\r\n- If some detail pages fail, the run finishes with a `PARTIAL` warning and keeps the search rows instead of failing the whole run.\r\n\r\n## Output per hotel\r\n\r\n| Field | What it contains |\r\n|---|---|\r\n| `hotelId`, `name`, `url` | Property identity and its Booking.com page |\r\n| `propertyType`, `stars` | Property type and star rating |\r\n| `address`, `city`, `country` | Full address and location |\r\n| `latitude`, `longitude` | Map coordinates |\r\n| `distance` | Distance from the city centre as Booking.com shows it |\r\n| `rating`, `reviewCount`, `reviewWord` | Guest score, number of reviews and Booking.com's label |\r\n| `reviewSubscores` | Category scores such as Location, Cleanliness and Staff |\r\n| `price`, `pricePerNight`, `currency` | Cheapest total for the stay, nightly equivalent and ISO currency code |\r\n| `originalPrice`, `discountPercent` | Pre-discount price and discount percentage when a deal is shown |\r\n| `taxesAndFees`, `priceWithTaxes` | Taxes and fees for the cheapest rate and the resulting total |\r\n| `roomTypes` | Room name, rate-plan count, price, original price, total, taxes, breakfast, cancellation, sleeps, bed, size and room amenities |\r\n| `topAmenities`, `fullAmenities` | Headline facilities, plus the complete list when `includeFullAmenities` is on |\r\n| `amenities` | Amenity keywords found on the search card |\r\n| `photos`, `photoUrl` | Photo URLs and the main image |\r\n| `description` | Property description |\r\n| `breakfastIncluded`, `breakfastAvailable`, `breakfastPrice` | Whether breakfast is included, merely available, or paid separately |\r\n| `freeCancellation` | Whether a free-cancellation rate exists |\r\n| `checkinTime`, `checkoutTime` | Property check-in and check-out times |\r\n| `checkin`, `checkout`, `nights`, `adults`, `rooms` | The stay used for pricing |\r\n| `mode`, `detailStatus`, `source`, `scrapedAt` | Run metadata and enrichment status |\r\n\r\nEmpty values are omitted from a record instead of being written as `null`.\r\n\r\n## Input\r\n\r\n| Field | Type | Default | Description |\r\n|---|---|---|---|\r\n| `mode` | select | `search` | `search` a destination or load hotel `details` |\r\n| `destination` | string | – | City, region or landmark; required in search mode |\r\n| `startUrls` | array | `[]` | Booking.com hotel URLs; required in details mode |\r\n| `checkIn` | string | - | Check-in date (`YYYY-MM-DD`); empty uses tomorrow |\r\n| `checkOut` | string | - | Check-out date (`YYYY-MM-DD`); empty uses a 3-night stay |\r\n| `adults` | integer | `2` | Adult guests (1–30) |\r\n| `rooms` | integer | `1` | Rooms needed (1–30) |\r\n| `propertyType` | select | `all` | All, hotels, apartments, hostels, guesthouses, villas or resorts |\r\n| `minReviewScore` | number | `0` | Minimum guest score (0–10) |\r\n| `stars` | select | `0` | Exact star rating, or any |\r\n| `freeCancellation` | boolean | `false` | Keep properties with a free-cancellation rate |\r\n| `breakfast` | boolean | `false` | Keep properties with breakfast included |\r\n| `pool` | boolean | `false` | Keep properties with a swimming pool |\r\n| `minPrice`, `maxPrice` | number | – | Nightly price bounds in the chosen currency |\r\n| `currency` | string | `USD` | Three-letter currency code |\r\n| `language` | select | `en-us` | Page language |\r\n| `maxItems` | integer | `3` | Maximum hotels to return (1–250) |\r\n| `includeRooms` | boolean | `true` | Add the room and rate table |\r\n| `includeFullAmenities` | boolean | `false` | Render each hotel page to collect every facility |\r\n| `proxyConfiguration` | object | Automatic | Optional proxy override; the actor selects the Apify proxy automatically |\r\n\r\n### Example: search Paris for three nights\r\n\r\n```json\r\n{\r\n  \"mode\": \"search\",\r\n  \"destination\": \"Paris\",\r\n  \"checkIn\": \"2026-11-13\",\r\n  \"checkOut\": \"2026-11-16\",\r\n  \"adults\": 2,\r\n  \"rooms\": 1,\r\n  \"maxItems\": 3,\r\n  \"includeFullAmenities\": false\r\n}\r\n```\r\n\r\n### Example: five-star hotels with a pool and free cancellation\r\n\r\n```json\r\n{\r\n  \"mode\": \"search\",\r\n  \"destination\": \"Barcelona\",\r\n  \"checkIn\": \"2026-11-13\",\r\n  \"checkOut\": \"2026-11-16\",\r\n  \"stars\": 5,\r\n  \"pool\": true,\r\n  \"freeCancellation\": true,\r\n  \"minReviewScore\": 8,\r\n  \"currency\": \"EUR\",\r\n  \"maxItems\": 25\r\n}\r\n```\r\n\r\n### Example: load specific hotel pages\r\n\r\n```json\r\n{\r\n  \"mode\": \"details\",\r\n  \"startUrls\": [\r\n    { \"url\": \"https://www.booking.com/hotel/fr/sorbonne.html\" },\r\n    { \"url\": \"https://www.booking.com/hotel/fr/moxy-paris-la-villette.html\" }\r\n  ],\r\n  \"checkIn\": \"2026-11-13\",\r\n  \"checkOut\": \"2026-11-16\",\r\n  \"includeRooms\": true,\r\n  \"includeFullAmenities\": true\r\n}\r\n```\r\n\r\n## Use cases\r\n\r\n- **Price comparison** — compare stay totals for the same dates across a destination\r\n- **Rate tracking** — schedule runs to watch prices and discounts move\r\n- **Room-level analysis** — compare room types, breakfast and cancellation terms\r\n- **Travel apps and spreadsheets** — feed structured hotel data into your own tools\r\n- **Market research** — analyse ratings, review subscores and facilities by city or property type\r\n\r\n## FAQ\r\n\r\n**Do I need a Booking.com account?**\r\nNo. The actor reads public hotel and search pages. It solves the site's technical challenge without you providing cookies or a login.\r\n\r\n**Why does the first request take longer?**\r\nBooking.com uses an AWS WAF JavaScript challenge. The actor opens one browser page to solve it, then reuses the resulting cookie over HTTP. That bootstrap is a few seconds per run.\r\n\r\n**What does `price` mean?**\r\nIt is the cheapest total for the whole stay, for the dates, guest count and room count in your input. `pricePerNight` divides that total by the number of nights. Use `originalPrice` when Booking.com shows a strike-through price.\r\n\r\n**Why do some prices differ from the search card?**\r\nThe search card can show a promotional or selected-room price. The detail parser takes the cheapest valid room-table price, which is the same number Booking.com uses for the cheapest rate on that page.\r\n\r\n**Why is `fullAmenities` missing?**\r\nIt is only collected when `includeFullAmenities` is on. That setting renders a hotel page in a browser, so it is slower and costs more than the default HTTP-only detail fetch.\r\n\r\n**What happens when Booking.com blocks the run?**\r\nThe actor selects its proxy automatically, so you do not need to configure anything. If every proxy path is blocked, it fails with a `BLOCKED` status instead of returning an empty dataset. If only some detail pages fail, it finishes with a `PARTIAL` status and keeps the rows it did collect.\r\n\r\n**What happens when a search has no results?**\r\nA valid search with no matches fails with `NO_RESULTS`, so you can tell it apart from a block. Loosen your filters or check the destination spelling.\r\n\r\n**Do the filters work in details mode?**\r\nYes. Property type, stars, review score, free cancellation, breakfast, pool and nightly price are applied to the hotel data after each detail page is parsed. Booking.com's own search filters are still used in search mode for the initial result set.\r\n\r\n**How many results can I get?**\r\nSet `maxItems` up to 250. Booking.com loads 25 cards at a time and exposes a \"Load more results\" button; the actor scrolls and clicks it until your cap or the page stops growing. Booking.com itself caps a single query at about 1,000 results. If the source or the filters run out before your cap, the run status says how many rows were actually pushed. Large detail runs can take several minutes because Booking.com challenges each hotel page separately.\r\n\r\n**Are prices and availability live?**\r\nYes. They are captured when the actor runs and can change as availability changes.\r\n\r\n**Is this affiliated with Booking.com?**\r\nNo. This is an independent third-party actor that reads publicly available Booking.com pages.\r\n",
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "title": "Booking.com Hotel Search & Details",
          "fields": {
            "type": "object",
            "properties": {
              "hotelId": {
                "type": "string",
                "description": "Hotel slug from the Booking.com URL"
              },
              "name": {
                "type": "string",
                "description": "Hotel name"
              },
              "url": {
                "type": "string",
                "description": "Booking.com hotel URL"
              },
              "propertyType": {
                "type": "string",
                "description": "Property type from Booking.com"
              },
              "stars": {
                "type": "integer",
                "description": "Star rating (1-5)"
              },
              "address": {
                "type": "string",
                "description": "Full street address"
              },
              "city": {
                "type": "string",
                "description": "City"
              },
              "country": {
                "type": "string",
                "description": "Country name"
              },
              "latitude": {
                "type": "number",
                "description": "Latitude"
              },
              "longitude": {
                "type": "number",
                "description": "Longitude"
              },
              "distance": {
                "type": "string",
                "description": "Distance from the city centre as shown by Booking.com"
              },
              "rating": {
                "type": "number",
                "description": "Guest review score (0-10)"
              },
              "reviewCount": {
                "type": "integer",
                "description": "Number of guest reviews"
              },
              "reviewWord": {
                "type": "string",
                "description": "Booking.com rating label such as Wonderful or Very Good"
              },
              "reviewSubscores": {
                "type": "array",
                "description": "Guest subscores such as Location and Cleanliness",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "score": {
                      "type": "number"
                    }
                  }
                }
              },
              "price": {
                "type": "number",
                "description": "Cheapest total price for the whole stay"
              },
              "pricePerNight": {
                "type": "number",
                "description": "Total price divided by the number of nights"
              },
              "originalPrice": {
                "type": "number",
                "description": "Pre-discount price when Booking.com shows a strike-through price"
              },
              "currency": {
                "type": "string",
                "description": "ISO 4217 currency code"
              },
              "discountPercent": {
                "type": "number",
                "description": "Discount percentage when an original price is shown"
              },
              "taxesAndFees": {
                "type": "number",
                "description": "Taxes and fees shown for the cheapest rate"
              },
              "priceWithTaxes": {
                "type": "number",
                "description": "Cheapest rate total plus taxes and fees"
              },
              "roomTypeCount": {
                "type": "integer",
                "description": "Number of distinct room types"
              },
              "roomTypes": {
                "type": "array",
                "description": "Room and rate options",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "ratePlans": {
                      "type": "integer"
                    },
                    "price": {
                      "type": "number"
                    },
                    "originalPrice": {
                      "type": "number"
                    },
                    "totalPrice": {
                      "type": "number"
                    },
                    "taxesAndFees": {
                      "type": "number"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "breakfastIncluded": {
                      "type": "boolean"
                    },
                    "breakfastAvailable": {
                      "type": "boolean"
                    },
                    "breakfastPrice": {
                      "type": "number"
                    },
                    "freeCancellation": {
                      "type": "boolean"
                    },
                    "sleeps": {
                      "type": "string"
                    },
                    "bedType": {
                      "type": "string"
                    },
                    "size": {
                      "type": "string"
                    },
                    "amenities": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              },
              "topAmenities": {
                "type": "array",
                "description": "Headline facilities",
                "items": {
                  "type": "string"
                }
              },
              "fullAmenities": {
                "type": "array",
                "description": "Complete facility list when includeFullAmenities is on",
                "items": {
                  "type": "string"
                }
              },
              "amenities": {
                "type": "array",
                "description": "Amenity keywords found on the search card",
                "items": {
                  "type": "string"
                }
              },
              "photos": {
                "type": "array",
                "description": "Hotel photo URLs",
                "items": {
                  "type": "string"
                }
              },
              "photoUrl": {
                "type": "string",
                "description": "Main hotel photo URL"
              },
              "description": {
                "type": "string",
                "description": "Property description"
              },
              "breakfastIncluded": {
                "type": "boolean",
                "description": "Whether a breakfast-included rate exists"
              },
              "breakfastAvailable": {
                "type": "boolean",
                "description": "Whether breakfast is available"
              },
              "breakfastPrice": {
                "type": "number",
                "description": "Breakfast price when it is paid separately"
              },
              "freeCancellation": {
                "type": "boolean",
                "description": "Whether a free-cancellation rate exists"
              },
              "checkinTime": {
                "type": "string",
                "description": "Check-in time"
              },
              "checkoutTime": {
                "type": "string",
                "description": "Check-out time"
              },
              "checkin": {
                "type": "string",
                "description": "Stay check-in date used for the prices"
              },
              "checkout": {
                "type": "string",
                "description": "Stay check-out date used for the prices"
              },
              "nights": {
                "type": "integer",
                "description": "Number of nights in the stay"
              },
              "adults": {
                "type": "integer",
                "description": "Number of adults used for pricing"
              },
              "rooms": {
                "type": "integer",
                "description": "Number of rooms used for pricing"
              },
              "mode": {
                "type": "string",
                "description": "search or details"
              },
              "detailStatus": {
                "type": "string",
                "description": "enriched, search_only or failed"
              },
              "source": {
                "type": "string",
                "description": "Data source"
              },
              "scrapedAt": {
                "type": "string",
                "description": "Collection timestamp in ISO 8601 format"
              }
            }
          },
          "views": {
            "overview": {
              "title": "Hotels",
              "transformation": {
                "fields": [
                  "name",
                  "price",
                  "pricePerNight",
                  "currency",
                  "rating",
                  "reviewCount",
                  "reviewWord",
                  "stars",
                  "propertyType",
                  "city",
                  "country",
                  "freeCancellation",
                  "breakfastIncluded",
                  "topAmenities",
                  "url"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "name": {
                    "label": "Hotel",
                    "format": "text"
                  },
                  "price": {
                    "label": "Stay total",
                    "format": "number"
                  },
                  "pricePerNight": {
                    "label": "Per night",
                    "format": "number"
                  },
                  "currency": {
                    "label": "Currency",
                    "format": "text"
                  },
                  "rating": {
                    "label": "Rating",
                    "format": "number"
                  },
                  "reviewCount": {
                    "label": "Reviews",
                    "format": "number"
                  },
                  "reviewWord": {
                    "label": "Score word",
                    "format": "text"
                  },
                  "stars": {
                    "label": "Stars",
                    "format": "number"
                  },
                  "propertyType": {
                    "label": "Type",
                    "format": "text"
                  },
                  "city": {
                    "label": "City",
                    "format": "text"
                  },
                  "country": {
                    "label": "Country",
                    "format": "text"
                  },
                  "freeCancellation": {
                    "label": "Free cancellation",
                    "format": "text"
                  },
                  "breakfastIncluded": {
                    "label": "Breakfast",
                    "format": "text"
                  },
                  "topAmenities": {
                    "label": "Top amenities",
                    "format": "text"
                  },
                  "url": {
                    "label": "URL",
                    "format": "link"
                  }
                }
              }
            },
            "rooms": {
              "title": "Rooms",
              "transformation": {
                "fields": [
                  "name",
                  "roomTypeCount",
                  "roomTypes",
                  "url"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "name": {
                    "label": "Hotel",
                    "format": "text"
                  },
                  "roomTypeCount": {
                    "label": "Room types",
                    "format": "number"
                  },
                  "roomTypes": {
                    "label": "Rooms and rates",
                    "format": "text"
                  },
                  "url": {
                    "label": "URL",
                    "format": "link"
                  }
                }
              }
            }
          }
        }
      }
    },
    "buildNumber": "2.0.4",
    "imageDigest": "62a882bb9b24f1dcb5c7e0edd0bdb4e28fa1e47a8287b83739290f154511c2b2",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "2.0"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.05829666666666666
    }
  }
}