# Choice Hotels Scraper — rates, ratings & amenities (`memo23/choicehotels-scraper`) Actor

Scrape Choice Hotels (choicehotels.com) — hotel name, brand, address, coordinates, star rating, review count, amenities, images, and nightly rates including the member price and discount. One search URL returns every hotel in the area. Residential proxy handled. JSON or CSV output.

- **URL**: https://apify.com/memo23/choicehotels-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Travel, AI, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 hotel results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Choice Hotels Scraper — hotels, rates & ratings from choicehotels.com

Scrape **Choice Hotels** (choicehotels.com) hotel data from any city or brand search page — name, brand, full address, coordinates, star rating and review count, amenities, images, and the **current "from" nightly rate including the member price and discount**. One search URL returns **every hotel in the area** in a single request. Clean JSON/CSV out.

> **About the rates:** the price fields are Choice's *current starting rate* (the "from $X / night" figure shown on the search page for a default one-night stay). They are **not** quotes for specific check-in/check-out dates or guest counts — Choice only prices those through a separate, bot-protected API this actor doesn't use. Great for tracking how starting rates move over time; not a dated-availability quote engine. See the [FAQ](#faq).

![How Choice Hotels Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-choicehotels.png)

### Why use this scraper?

- **Whole city in one request** — a single search page returns all hotels within an auto-expanding radius (often 40+), each fully detailed. No page-by-page crawling.
- **Rates with member pricing** — the current starting nightly rate, member rate, discount percentage, plus taxes and fees, all in the output (not date-specific — see the note above).
- **Every Choice brand** — Comfort, Quality Inn, Sleep Inn, Clarion, Econo Lodge, Rodeway Inn, Ascend, Cambria, WoodSpring, and more. Filter to one brand or scrape them all.
- **Built-in filters** — narrow results by brand, amenities (pool, free breakfast, EV charging…), pet-friendly, minimum rating/reviews, and max nightly price — all without extra requests.
- **Rich structured data** — coordinates, star rating + review count, coded amenities as readable labels, and image galleries.
- **Bot-protection handled** — browser-grade TLS via impit, residential proxy support, and automatic IP rotation when a challenge is detected.
- **Flexible input** — paste search URLs or build them from `{ state, city }` locations.

### Overview

Give the actor Choice Hotels search-results URLs (or locations to build them). For each, it fetches the search page, reads the hotel data Choice inlines in the page, and returns one clean row per hotel — identity, location, rating, amenities, images, and pricing. Overlapping searches are de-duplicated by hotel.

### Supported inputs

| Input | Example | Result |
|---|---|---|
| City search URL | `https://www.choicehotels.com/california/los-angeles/hotels` | all hotels in/around the city |
| Brand-filtered URL | `https://www.choicehotels.com/california/los-angeles/comfort-inn-hotels` | one brand in the city |
| Facet URL | `.../los-angeles/pet-friendly-hotels` | facet-filtered hotels |
| Location object | `{ "state": "texas", "city": "austin" }` | built into a city search URL |
| Location + brand | `{ "state": "texas", "city": "austin", "brand": "sleep-inn" }` | brand search URL |
| Single-hotel URL | `.../comfort-inn-hotels/ca785` | auto-collapsed to the city search |

### Use cases

- **Rate & competitive intelligence** — track starting nightly rates and member discounts across a market or brand.
- **Travel aggregators & meta-search** — feed a hotel inventory with pricing, ratings, and amenities.
- **Market research** — brand footprint, average ratings, and amenity coverage by city or state.
- **Lead lists** — build a directory of hotels (name, address, coordinates) for a region.
- **Price monitoring** — schedule the actor and diff the starting rates over time to watch how they trend.

### How it works

1. **Fetch** — each search URL is requested with browser-grade impit TLS through a residential proxy.
2. **Extract** — the hotel dataset Choice inlines in the search page is parsed directly (no per-hotel page fetch — the detail pages carry no extra data and are bot-walled).
3. **Map** — each hotel becomes a clean, flat record: identity, address, geo, rating, amenities, images, and rates.
4. **Dedupe** — hotels repeated across overlapping search radii are collapsed by hotel code.
5. **Push** — one dataset row per hotel, JSON or CSV.

### Input configuration

```json
{
    "startUrls": [
        "https://www.choicehotels.com/california/los-angeles/hotels"
    ],
    "locations": [
        "Austin, Texas",
        "Los Angeles, CA",
        "Miami, Florida, Comfort Inn"
    ],
    "maxItems": 1000,
    "proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
````

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | — | Choice Hotels search-results URLs |
| `locations` | array | `[]` | One `City, State` per line (state name or 2-letter code); add a brand as a third part to filter, e.g. `Miami, Florida, Comfort Inn` |
| `brands` | array | `[]` | Keep only these Choice brands (multi-select) |
| `amenities` | array | `[]` | Keep hotels having ALL these amenity keywords, e.g. `pool`, `free breakfast`, `ev charging` |
| `petFriendly` | boolean | `false` | Keep only pet-friendly hotels |
| `minRating` | integer | `0` | Minimum guest rating (0–5) |
| `minReviews` | integer | `0` | Minimum number of reviews |
| `maxPrice` | integer | `0` | Maximum starting nightly rate (0 = no cap) |
| `maxItems` | integer | `1000` | Hard cap on hotels scraped |
| `maxConcurrency` | integer | `3` | Parallel search pages — keep low (bot protection) |
| `proxy` | object | RESIDENTIAL | Residential proxy strongly recommended |

#### Filters

Choice Hotels applies its on-site filters (brand, amenities, rating, price) through a bot-protected API rather than the search page itself, so this actor replicates them **against the scraped results** — you still get exactly the hotels that match, they're just filtered after extraction:

- **`brands`** — pick one or more Choice brands (Comfort Inn, Sleep Inn, Cambria, …).
- **`amenities`** — list keywords; a hotel is kept only if it has *all* of them. Each keyword matches an amenity when every word appears in it, so `free breakfast` matches "Free Hot Breakfast" and `ev charging` matches "EV Charging Station".
- **`petFriendly`** — only hotels that explicitly allow pets.
- **`minRating` / `minReviews`** — drop low-rated or sparsely-reviewed hotels.
- **`maxPrice`** — cap by the starting nightly rate (after taxes/fees).

Filters combine with AND, and are applied *before* the `maxItems` cap so the cap counts hotels you actually wanted. Every result still carries the full `amenities`, `ratingValue`, `brandName`, and rate fields, so you can also post-filter downstream.

> Note: dates and guest counts still can't be filtered — those live only behind Choice's bot-walled pricing API (see the [FAQ](#faq)).

> **Locations format:** each line is `City, State` (e.g. `Austin, Texas` or `Los Angeles, CA`), optionally `City, State, Brand` (e.g. `Miami, Florida, Comfort Inn`). Every line becomes a city search that returns all hotels in that area.

### Output overview

```json
{
    "hotelCode": "CA785",
    "name": "Comfort Inn Los Angeles near Hollywood",
    "brandCode": "CI",
    "brandName": "Comfort",
    "productName": "Inn",
    "address": {
        "line1": "2717 West Sunset Blvd.",
        "line2": null,
        "city": "Los Angeles",
        "subdivision": "CA",
        "postalCode": "90026",
        "country": "US"
    },
    "latitude": 34.080911,
    "longitude": -118.270406,
    "ratingValue": 3.9,
    "ratingMax": 5,
    "reviews": 1281,
    "recommends": 992,
    "status": "ACTIVE",
    "currencyCode": "USD",
    "lowestRateBeforeTax": 129,
    "lowestRateAfterTax": 147.06,
    "memberRateAfterTax": 132.35,
    "discountPercentage": 10,
    "amenities": ["Premium Free WiFi", "Free Deluxe Continental Breakfast", "..."],
    "images": ["https://www.choicehotels.com/hoteldam/ca/ca785/images/480/CA785TWILIGHT1_1.jpg", "..."],
    "phone": null,
    "description": null,
    "sourceUrl": "https://www.choicehotels.com/california/los-angeles/hotels",
    "scrapedAt": "2026-07-16T04:00:00.000Z"
}
```

### Key output fields

| Field | Description |
|---|---|
| `hotelCode` | Choice Hotels property code (e.g. `CA785`) |
| `name` / `brandName` / `productName` | Hotel name and brand |
| `address` / `latitude` / `longitude` | Full address and coordinates |
| `ratingValue` / `ratingMax` / `reviews` / `recommends` | Guest rating, scale, review count, recommend count |
| `lowestRateBeforeTax` / `lowestRateAfterTax` | Current public starting nightly rate (default 1-night stay; not date-specific) |
| `memberRateAfterTax` / `discountPercentage` | Member starting price and its discount |
| `currencyCode` | Rate currency |
| `amenities` | Readable amenity labels |
| `images` | Hotel image URLs |
| `status` | Property status (e.g. `ACTIVE`) |
| `sourceUrl` | The search page this hotel came from |

### FAQ

**How many hotels do I get per search URL?**
All hotels within the search radius, which auto-expands to fill results — often 40+ from a single city page. Set `maxItems` to cap billing.

**Why are `phone` and `description` null?**
Choice Hotels does not include those on its search pages (only on the bot-walled per-hotel detail API), so the actor surfaces the fields as `null` rather than fetching an unreliable extra page. Everything else — address, geo, rating, amenities, rates — is present.

**Do I need a proxy?**
Yes, a residential proxy is strongly recommended and the default. Choice Hotels uses Akamai bot protection that flags datacenter IPs quickly; the actor rotates the residential IP automatically when it detects a challenge.

**Can I set check-in / check-out dates or guest counts to get dated pricing?**
No. Choice Hotels' search page always renders the **current starting rate for a default one-night stay** — it does not re-price the page for dates, guests, or amenity filters passed in the URL. Those filters are applied by a separate, bot-protected pricing API that this actor intentionally does not use. So the rate fields are a live "from $X / night" figure, not a quote for a specific stay. If you need dated, per-guest availability quotes, that's a different (heavier) build — reach out via the Issues tab to discuss.

**Do amenity / pet-friendly / "top-rated" filters work?**
Those are applied by the same bot-protected API, not by the search page itself, so the actor returns the full hotel set for the city regardless. You can filter the results yourself on the `amenities`, `ratingValue`, and `brandName` fields in the output, or narrow the input to a single brand.

**Which brands are covered?**
All Choice Hotels brands appear on the all-brands city page; use a brand-filtered URL (e.g. `/comfort-inn-hotels`) or the `brand` location field to narrow to one.

### Support

- **Issues tab** — fastest way to report a problem or request a field; I usually respond within 24 hours.
- The actor self-reports failed runs to me automatically, so breakages are often being fixed before you write in.

### Additional services

Need scheduled rate monitoring, nationwide coverage from the Choice Hotels sitemap, a private variant, or a scraper for another hotel brand (Marriott, Hilton, IHG, Wyndham)? Reach out via the Issues tab or my Apify profile.

### Explore more scrapers

Check my Apify profile for more scrapers — travel (Expedia, Booking), real estate (Zillow, Realtor, Rightmove, ImmoScout24, Idealista), jobs (LinkedIn, Indeed, Glassdoor), reviews (Trustpilot), social (Telegram, WhatsApp channels), and many more.

### ⚠️ Disclaimer

This actor collects only **publicly available data** from Choice Hotels' public search-results pages — the same information any visitor sees in a browser. It does not access private data, does not log in, and does not place bookings. You are responsible for how you use the data: comply with Choice Hotels' Terms of Service, applicable data-protection laws (GDPR, CCPA), and platform policies in your jurisdiction. This actor is not affiliated with or endorsed by Choice Hotels International.

### SEO Keywords

choice hotels scraper, choicehotels.com scraper, scrape choice hotels, hotel rates scraper, comfort inn scraper, quality inn scraper, hotel price scraper, hotel data scraper, hotel amenities scraper, hotel rating scraper, choice hotels api, scrape hotel prices, hotel rate monitoring, hotel listing scraper, comfort suites scraper, sleep inn scraper, clarion scraper, econo lodge scraper, rodeway inn scraper, hotel competitive intelligence

# Actor input Schema

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

Full choicehotels.com search-results URLs. One request returns all hotels in that city/brand search.

## `locations` (type: `array`):

Type one location per line as `City, State` — e.g. `Los Angeles, California` or `Austin, TX`. The state can be a full name or a 2-letter code. To limit a line to one brand, add it after the state: `Miami, Florida, Comfort Inn`. Each line is turned into a Choice Hotels city search that returns every hotel in that area.

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

Keep only these Choice brands. Leave empty for all brands.

## `amenities` (type: `array`):

Keep only hotels that have every amenity keyword listed, e.g. `pool`, `free breakfast`, `pet`, `fitness`, `ev charging`, `wifi`. Matched against each hotel's amenity list (case-insensitive).

## `petFriendly` (type: `boolean`):

Keep only hotels that explicitly allow pets.

## `minRating` (type: `integer`):

Keep only hotels with a guest rating at or above this value. 0 = no minimum.

## `minReviews` (type: `integer`):

Keep only hotels with at least this many guest reviews (filters out new / sparsely-rated hotels). 0 = no minimum.

## `maxPrice` (type: `integer`):

Keep only hotels whose starting nightly rate (after taxes/fees) is at or below this amount. 0 = no maximum.

## `maxItems` (type: `integer`):

Hard cap on the number of hotels collected. A single city search page can return 40+ hotels; use this to limit billing.

## `maxConcurrency` (type: `integer`):

Parallel search pages fetched at once. Keep this low (default 3) — Choice Hotels' bot protection penalizes bursts.

## `minConcurrency` (type: `integer`):

Minimum number of pages processed in parallel.

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

Number of retries before a failed request is given up.

## `proxy` (type: `object`):

Choice Hotels uses Akamai bot protection, so a residential proxy is strongly recommended (and the default). The actor rotates the IP automatically when it detects a challenge.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.choicehotels.com/california/los-angeles/hotels"
  ],
  "locations": [],
  "brands": [],
  "amenities": [],
  "petFriendly": false,
  "minRating": 0,
  "minReviews": 0,
  "maxPrice": 0,
  "maxItems": 1000,
  "maxConcurrency": 3,
  "minConcurrency": 1,
  "maxRequestRetries": 5,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        "https://www.choicehotels.com/california/los-angeles/hotels"
    ],
    "locations": [],
    "brands": [],
    "amenities": [],
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/choicehotels-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": ["https://www.choicehotels.com/california/los-angeles/hotels"],
    "locations": [],
    "brands": [],
    "amenities": [],
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/choicehotels-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    "https://www.choicehotels.com/california/los-angeles/hotels"
  ],
  "locations": [],
  "brands": [],
  "amenities": [],
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call memo23/choicehotels-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=memo23/choicehotels-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Choice Hotels Scraper — rates, ratings & amenities",
        "description": "Scrape Choice Hotels (choicehotels.com) — hotel name, brand, address, coordinates, star rating, review count, amenities, images, and nightly rates including the member price and discount. One search URL returns every hotel in the area. Residential proxy handled. JSON or CSV output.",
        "version": "0.0",
        "x-build-id": "oShuAu9KQXuJGi8RM"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/memo23~choicehotels-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-memo23-choicehotels-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/memo23~choicehotels-scraper/runs": {
            "post": {
                "operationId": "runs-sync-memo23-choicehotels-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/memo23~choicehotels-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-memo23-choicehotels-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "startUrls": {
                        "title": "Choice Hotels search URLs",
                        "type": "array",
                        "description": "Full choicehotels.com search-results URLs. One request returns all hotels in that city/brand search.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "locations": {
                        "title": "Locations — one city per line",
                        "type": "array",
                        "description": "Type one location per line as `City, State` — e.g. `Los Angeles, California` or `Austin, TX`. The state can be a full name or a 2-letter code. To limit a line to one brand, add it after the state: `Miami, Florida, Comfort Inn`. Each line is turned into a Choice Hotels city search that returns every hotel in that area.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "brands": {
                        "title": "Brands",
                        "type": "array",
                        "description": "Keep only these Choice brands. Leave empty for all brands.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "Comfort Inn",
                                "Comfort Suites",
                                "Quality Inn",
                                "Sleep Inn",
                                "Clarion",
                                "Clarion Pointe",
                                "Cambria",
                                "Ascend Collection",
                                "MainStay Suites",
                                "WoodSpring Suites",
                                "Suburban Studios",
                                "Everhome Suites",
                                "Econo Lodge",
                                "Rodeway Inn",
                                "Country Inn & Suites"
                            ]
                        }
                    },
                    "amenities": {
                        "title": "Amenities (must have ALL)",
                        "type": "array",
                        "description": "Keep only hotels that have every amenity keyword listed, e.g. `pool`, `free breakfast`, `pet`, `fitness`, `ev charging`, `wifi`. Matched against each hotel's amenity list (case-insensitive).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "petFriendly": {
                        "title": "Pet-friendly only",
                        "type": "boolean",
                        "description": "Keep only hotels that explicitly allow pets.",
                        "default": false
                    },
                    "minRating": {
                        "title": "Minimum guest rating (0–5)",
                        "minimum": 0,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Keep only hotels with a guest rating at or above this value. 0 = no minimum.",
                        "default": 0
                    },
                    "minReviews": {
                        "title": "Minimum number of reviews",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only hotels with at least this many guest reviews (filters out new / sparsely-rated hotels). 0 = no minimum.",
                        "default": 0
                    },
                    "maxPrice": {
                        "title": "Maximum nightly rate",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only hotels whose starting nightly rate (after taxes/fees) is at or below this amount. 0 = no maximum.",
                        "default": 0
                    },
                    "maxItems": {
                        "title": "Maximum hotels to scrape",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Hard cap on the number of hotels collected. A single city search page can return 40+ hotels; use this to limit billing.",
                        "default": 1000
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Parallel search pages fetched at once. Keep this low (default 3) — Choice Hotels' bot protection penalizes bursts.",
                        "default": 3
                    },
                    "minConcurrency": {
                        "title": "Min concurrency",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Minimum number of pages processed in parallel.",
                        "default": 1
                    },
                    "maxRequestRetries": {
                        "title": "Max request retries",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Number of retries before a failed request is given up.",
                        "default": 5
                    },
                    "proxy": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Choice Hotels uses Akamai bot protection, so a residential proxy is strongly recommended (and the default). The actor rotates the IP automatically when it detects a challenge.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ]
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
