{
  "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}