# HomeStars Scraper (`scrapersdelight/homestars-scraper`) Actor

Scrape Canadian home-service business listings and profiles from HomeStars.com

- **URL**: https://apify.com/scrapersdelight/homestars-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Lead generation, SEO tools, Other
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 business profiles

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.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.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/platform/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

## HomeStars.ca Scraper

Scrape Canadian home-service businesses — plumbers, HVAC, electricians, roofers, contractors — from [HomeStars.ca](https://www.homestars.com), Canada's largest home-services review platform.

### Why this actor exists

If you sell to Canadian trades — HVAC contractors, plumbers, electricians, roofers, drywallers, renovation companies — HomeStars is the cleanest single source of targeted B2B contact data. It indexes ~50 000 verified service businesses across ~3 000 city+profession combinations, each with a verified license, phone number, and (when published) website. Google Maps' coverage of these same businesses is uneven; the bigger, review-rich pros often live on HomeStars in addition to (or instead of) Maps.

This actor pulls **phone number, social links, website, full company bio, ratings, review counts, HomeStars badges, professions, locality, and verification status** for every business in the directory — ready to drop into a CRM, outreach sequence, or enrichment pipeline.

Typical users:
- **B2B sales** targeting trades (SaaS, insurance, fleet/equipment, financing, marketing services).
- **Lead-gen and list-resellers** building Canadian trade lists by profession and metro.
- **Recruiting** for skilled-trades hiring.
- **Market research** on review/badge density by city and trade.

The records describe the **businesses themselves** — homeowner reviewers are not scraped.

### Quick start

```jsonc
{
  "mode": "all_listings",
  "cities": ["toronto-ontario", "kitchener-ontario"],
  "professions": ["plumber-pros", "hvac-pros"],
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "CA"
  }
}
````

This fetches every plumber and HVAC profile in Toronto and Kitchener.

### Modes

| Mode | What it does | Cost driver |
| --- | --- | --- |
| `all_listings` *(default)* | Walks listing sitemap, paginates each directory, fetches every profile. **Most complete output.** | Per-profile + per-listing-card charges |
| `listings_only` | Same crawl, but stops at listing cards. Output is the card snippet only (name, slug, locality, profession, rating, logo). **~30× cheaper, fewer fields.** | Per-listing-card charges only |
| `profiles_only` | Skips directories. Hits the `service_pros` sitemap directly and pulls every pro's profile in one pass. Fastest path to a full national dataset. **The `cities` filter is ignored** in this mode — profile URLs carry no location info; filter post-hoc on the `city` field of the output. | Per-profile charges only |

### Example output (profile record)

Real data from [Local Heating And Cooling](https://www.homestars.com/profile/2913450-local-heating-and-cooling), a 5-star Kitchener HVAC contractor, 122 reviews, BEST\_OF\_AWARD winner 2026:

```json
{
  "slug": "2913450-local-heating-and-cooling",
  "profileUrl": "https://www.homestars.com/profile/2913450-local-heating-and-cooling",
  "companyName": "Local Heating And Cooling",
  "phone": "+15198848888",
  "websiteUrl": "https://localheatingcooling.com",
  "facebookUrl": "https://www.facebook.com/localheatingandcooling/",
  "instagramUrl": "https://instagram.com/local_heating_and_cooling?igshid=YmMyMTA2M2Y=",
  "linkedinUrl": null,
  "youtubeUrl": null,
  "rating": 10,
  "ratingOutOfFive": 5,
  "reviewsCount": 122,
  "locality": "Kitchener, Ontario",
  "city": "Kitchener",
  "province": "Ontario",
  "professions": [
    "HVAC contractor", "Electrician", "Handyman", "Plumber", "Cleaning company",
    "Appliance repair specialist", "Excavation Specialist", "Refrigeration specialist",
    "Renewable Energy Specialist", "Home Electronics Specialist",
    "Fireplace and BBQ Specialist"
  ],
  "verifications": ["VALID_ID", "VERIFIED_LICENSE"],
  "badges": [
    { "badgeType": "VERIFICATION_BADGE",    "winningYear": 2022, "winCount": 1 },
    { "badgeType": "BEST_OF_THE_BEST_AWARD","winningYear": 2025, "winCount": 1 },
    { "badgeType": "BEST_OF_AWARD",         "winningYear": 2026, "winCount": 7 }
  ],
  "logoUrl": "https://www.homestars.com/images/sp/thumbnail_medium/6a8a78d0-eb98-5777-ad14-ba009463f852.jpg",
  "companyBio": "Visit our local showroom! 47 Bridge St E Unit 10 Kitchener. Whether you need a new furnace…",
  "isApproved": true,
  "warrantyIsProvided": false,
  "ableToInteract": true,
  "firstAbleToInteractAt": "2018-08-20T00:00:00+00:00",
  "sourceListingUrl": "https://www.homestars.com/heating-and-cooling/hvac-pros/kitchener-ontario",
  "scrapedAt": "2026-05-12T01:06:11.147Z"
}
```

### Pricing

This actor uses **pay-per-event** pricing — you only pay for results, not compute time.

| Event | Price | When it fires |
| --- | --- | --- |
| `profile_scraped` | **$0.008** | One per profile pushed to the dataset (modes: `all_listings`, `profiles_only`) |
| `listing_business_scraped` | **$0.003** | One per business card on a listing page (all modes) |

Worked examples:

- **Full Toronto plumbers harvest** (~600 pros across ~25 listing pages): ~600 × $0.008 + ~600 × $0.003 = **~$6.60**
- **National profiles-only sweep** (~50 000 pros): 50 000 × $0.008 = **~$400**
- **Listings-only sweep** of all 3 000 city+profession combos (~30 cards each): 90 000 × $0.003 = **~$270**

Apify proxy traffic and platform usage are billed separately on Apify's side, as with any actor.

### Filters

- **`cities`** — Lowercased city slugs as they appear in HomeStars URLs (e.g. `kitchener-ontario`, `toronto-ontario`). Match is substring; pass `toronto` to match `toronto-ontario`, `north-york-toronto`, etc. **Ignored in `profiles_only` mode.**
- **`professions`** — Lowercased profession slugs (e.g. `plumber-pros`, `hvac-pros`, `electrician-pros`, `roofer-pros`).
- **`maxListings`** / **`maxProfilesPerListing`** / **`maxPagesPerListing`** — Hard caps to bound run cost during testing.

### What's not included

- **Email addresses.** HomeStars hides business email behind a lead-gen form; it isn't exposed in their public page state. We confirmed this against multiple profile dumps. Use the phone number and website to reach the business.
- **Full review text.** Each profile carries the latest 5 reviews in its Apollo cache, but we don't extract them — they don't have a stable per-business uplift and bloat the dataset. If you need them, file a feature request.
- **Project / portfolio photos.** HomeStars loads these client-side from a separate endpoint, so capturing them would mean a second request per profile. Out of scope for v0.1; ask if you need it.
- **Email-reveal simulation.** This actor does not impersonate consumer accounts to trigger HomeStars's "Send message" flow.

### How it compares

| Need | Use this | Or |
| --- | --- | --- |
| Contact data for Canadian trade businesses with HomeStars-verified ratings | **HomeStars Scraper** | — |
| Generic local-business directory with Maps presence | [Google Maps Scraper](https://apify.com/compass/crawler-google-places) | this actor for HomeStars-exclusive businesses |
| US home services | [Yelp Scraper](https://apify.com/apify/yelp-scraper) | — |

HomeStars is the **only** large directory where HVAC, plumbing, roofing, and renovation pros submit verified-license documentation to get a `VERIFIED_LICENSE` badge — that field doesn't exist anywhere else in the Canadian directory landscape.

### Notes / known quirks

- **Pagination format.** HomeStars's listing pagination uses `?page=N` query parameters. The actor includes a runtime self-check: if page 2 returns the same first business as page 1, it automatically retries with the path-based `/page/N/` variant. You should not need to do anything, but watch the logs for `Pagination drift detected` on the first run if you're worried.
- **Cloudflare.** HomeStars is fronted by Cloudflare with managed challenge. Residential CA proxies clear it without issue; data-center proxies will get blocked.
- **Rating scale.** The `rating` field is on a 0–10 scale (matching HomeStars's internal Apollo cache). `ratingOutOfFive` is `rating / 2` for convenience — that's what HomeStars displays publicly.

# Actor input Schema

## `mode` (type: `string`):

What to crawl. `all_listings` walks every city+profession directory and fetches every business profile (most complete, most expensive). `listings_only` stops at the directory cards and emits one record per card (cheap, fewer fields). `profiles_only` skips directories entirely and fetches every business profile from the `service_pros` sitemap — note: the `city` filter is silently ignored in this mode because profile URLs carry no location info.

## `city` (type: `string`):

Pick one of the 30 largest Canadian metros from the dropdown. Need a smaller market not listed here? Use the **Cities filter** below instead — any HomeStars city slug works there (the actor recognizes all 7,000+).

## `profession` (type: `string`):

Single profession to scrape (slug, e.g. `plumber-pros`, `hvac-pros`). Becomes a dropdown after the cache refresh. Leave blank to scrape all professions.

## `cities` (type: `array`):

Free-form list of HomeStars city slugs (e.g. `waterloo-ontario`, `burlington`, `st-john-s`). Use this when the city you want is not in the dropdown above — every one of the 7,000+ Canadian cities HomeStars indexes is a valid value. Substring-matched against the URL's city segment. **Ignored in profiles\_only mode.** If the single-city dropdown is also set, both filters apply.

## `professions` (type: `array`):

Multi-profession filter as a free-form list of slugs (e.g. `plumber-pros`, `hvac-pros`). Substring-matched.

## `maxListings` (type: `integer`):

Cap on the number of distinct city+profession listing URLs (or profile URLs in profiles\_only mode) the actor will process. 0 = unlimited.

## `maxProfilesPerListing` (type: `integer`):

Cap on the number of business profiles fetched from a single listing page. 0 = unlimited (typically ~25 cards per page).

## `maxPagesPerListing` (type: `integer`):

Stop paginating a directory listing after this many pages. 0 = follow site-reported `totalPages`.

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

Higher values run faster but increase Cloudflare friction. Keep at 5 unless you know what you're doing.

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

Explicit URLs to crawl. When set, sitemap discovery and the `mode` field are bypassed. Use this to test a single listing page or profile. Each URL is routed by path: `/profile/...` -> profile parser, anything else -> listing parser.

## `proxyConfiguration` (type: `object`):

HomeStars is geo-targeted to Canada and protected by Cloudflare — residential CA proxies are strongly recommended.

## Actor input object example

```json
{
  "mode": "all_listings",
  "cities": [],
  "professions": [],
  "maxListings": 0,
  "maxProfilesPerListing": 0,
  "maxPagesPerListing": 0,
  "maxConcurrency": 5,
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "CA"
  }
}
```

# Actor output Schema

## `businesses` (type: `string`):

Default dataset of HomeStars business records, in JSON.

## `businessesCsv` (type: `string`):

Same records, exported as CSV.

## `consoleDataset` (type: `string`):

No description

# 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 = {
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "CA"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/homestars-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 = { "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "CA",
    } }

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/homestars-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 '{
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "CA"
  }
}' |
apify call scrapersdelight/homestars-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "HomeStars Scraper",
        "description": "Scrape Canadian home-service business listings and profiles from HomeStars.com",
        "version": "0.1",
        "x-build-id": "RRyY7HhYZVOj4AeCB"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/scrapersdelight~homestars-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-scrapersdelight-homestars-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/scrapersdelight~homestars-scraper/runs": {
            "post": {
                "operationId": "runs-sync-scrapersdelight-homestars-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/scrapersdelight~homestars-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-scrapersdelight-homestars-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",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Scrape mode",
                        "enum": [
                            "all_listings",
                            "listings_only",
                            "profiles_only"
                        ],
                        "type": "string",
                        "description": "What to crawl. `all_listings` walks every city+profession directory and fetches every business profile (most complete, most expensive). `listings_only` stops at the directory cards and emits one record per card (cheap, fewer fields). `profiles_only` skips directories entirely and fetches every business profile from the `service_pros` sitemap — note: the `city` filter is silently ignored in this mode because profile URLs carry no location info.",
                        "default": "all_listings"
                    },
                    "city": {
                        "title": "City",
                        "enum": [
                            "toronto",
                            "montreal",
                            "vancouver",
                            "calgary-alberta",
                            "edmonton",
                            "ottawa",
                            "quebec-city",
                            "winnipeg",
                            "hamilton",
                            "kitchener-ontario",
                            "london",
                            "halifax",
                            "victoria-british-columbia",
                            "windsor-ontario",
                            "oshawa",
                            "saskatoon",
                            "regina",
                            "barrie",
                            "kelowna",
                            "mississauga",
                            "brampton",
                            "vaughan",
                            "markham",
                            "richmond-hill",
                            "surrey",
                            "burnaby",
                            "north-york",
                            "scarborough",
                            "etobicoke",
                            "laval"
                        ],
                        "type": "string",
                        "description": "Pick one of the 30 largest Canadian metros from the dropdown. Need a smaller market not listed here? Use the **Cities filter** below instead — any HomeStars city slug works there (the actor recognizes all 7,000+)."
                    },
                    "profession": {
                        "title": "Profession",
                        "enum": [
                            "appliances-repair-specialist-pros",
                            "architect-pros",
                            "bathroom-renovation-company-pros",
                            "boiler-repair-service-pros",
                            "cabinet-maker-pros",
                            "carpenter-pros",
                            "cleaning-company-pros",
                            "concrete-specialist-pros",
                            "condominium-apartment-specialist-pros",
                            "countertops-specialist-pros",
                            "deck-contractor-pros",
                            "demolition-company-pros",
                            "drain-cleaning-pros",
                            "dryer-repair-specialist-pros",
                            "drywall-specialist-pros",
                            "electrician-pros",
                            "excavation-specialist-pros",
                            "fences-gates-specialist-pros",
                            "flooring-contractor-pros",
                            "fridge-repair-specialist-pros",
                            "furnace-repair-pros",
                            "garage-specialist-pros",
                            "general-contractor-pros",
                            "gutter-clearance-pros",
                            "gutters-eavestroughs-specialist-pros",
                            "handyman-pros",
                            "hearth-bbq-specialist-pros",
                            "home-electronics-specialist-pros",
                            "home-inspector-pros",
                            "hvac-contractor-pros",
                            "insulation-company-pros",
                            "interior-decorator-pros",
                            "interior-designer-pros",
                            "junk-removal-specialist-pros",
                            "kitchen-renovation-company-pros",
                            "landscaping-company-pros",
                            "lawn-care-pros",
                            "locksmith-pros",
                            "mason-pros",
                            "metal-worker-pros",
                            "mirrors-glass-specialist-pros",
                            "moving-company-pros",
                            "painter-pros",
                            "paving-contractor-pros",
                            "pest-treatment-specialist-pros",
                            "plasterer-pros",
                            "plumber-pros",
                            "pool-company-pros",
                            "refrigeration-specialist-pros",
                            "renewable-energy-specialist-pros",
                            "roof-repair-specialist-pros",
                            "roofing-specialist-pros",
                            "security-specialist-business-services-pros",
                            "siding-specialist-pros",
                            "snow-removal-pros",
                            "stairmaker-pros",
                            "stove-repair-specialist-pros",
                            "tiler-pros",
                            "tree-trimming-pros",
                            "upholsterer-pros",
                            "window-contractor-pros"
                        ],
                        "type": "string",
                        "description": "Single profession to scrape (slug, e.g. `plumber-pros`, `hvac-pros`). Becomes a dropdown after the cache refresh. Leave blank to scrape all professions."
                    },
                    "cities": {
                        "title": "Cities filter (any Canadian city)",
                        "type": "array",
                        "description": "Free-form list of HomeStars city slugs (e.g. `waterloo-ontario`, `burlington`, `st-john-s`). Use this when the city you want is not in the dropdown above — every one of the 7,000+ Canadian cities HomeStars indexes is a valid value. Substring-matched against the URL's city segment. **Ignored in profiles_only mode.** If the single-city dropdown is also set, both filters apply.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "professions": {
                        "title": "Professions filter (power user)",
                        "type": "array",
                        "description": "Multi-profession filter as a free-form list of slugs (e.g. `plumber-pros`, `hvac-pros`). Substring-matched.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxListings": {
                        "title": "Max listing URLs to crawl",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Cap on the number of distinct city+profession listing URLs (or profile URLs in profiles_only mode) the actor will process. 0 = unlimited.",
                        "default": 0
                    },
                    "maxProfilesPerListing": {
                        "title": "Max profiles per listing page",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Cap on the number of business profiles fetched from a single listing page. 0 = unlimited (typically ~25 cards per page).",
                        "default": 0
                    },
                    "maxPagesPerListing": {
                        "title": "Max pagination depth per listing",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Stop paginating a directory listing after this many pages. 0 = follow site-reported `totalPages`.",
                        "default": 0
                    },
                    "maxConcurrency": {
                        "title": "Max concurrent requests",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Higher values run faster but increase Cloudflare friction. Keep at 5 unless you know what you're doing.",
                        "default": 5
                    },
                    "startUrls": {
                        "title": "Start URLs (override)",
                        "type": "array",
                        "description": "Explicit URLs to crawl. When set, sitemap discovery and the `mode` field are bypassed. Use this to test a single listing page or profile. Each URL is routed by path: `/profile/...` -> profile parser, anything else -> listing parser.",
                        "default": [],
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "HomeStars is geo-targeted to Canada and protected by Cloudflare — residential CA proxies are strongly recommended.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ],
                            "apifyProxyCountry": "CA"
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
