{
  "openapi": "3.0.1",
  "info": {
    "title": "Houzz $1💰 URL | Keywords | Reviews and Pro Data",
    "description": "From $1/1K. Pull Houzz pro listings across global sites. Search by category and location, keyword, or URL, plus review mode for specific pros. Returns 35+ fields including ratings, reviews, awards, services, address, GPS, contacts, social links, project counts, and featured review.",
    "version": "1.2",
    "x-build-id": "PlH12wNJtnHUdzvWp"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~houzz-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-houzz-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/abotapi~houzz-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-houzz-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/abotapi~houzz-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-houzz-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": "Mode",
            "enum": [
              "search",
              "review",
              "url"
            ],
            "type": "string",
            "description": "Pick what each output row should be. 'search' returns one row per pro (full profile). 'review' returns one row per review, pulling each matching pro's full review history. 'url' walks any directory URL you paste, one row per pro.",
            "default": "search"
          },
          "site": {
            "title": "Country",
            "enum": [
              "houzz.com",
              "houzz.com.au",
              "houzz.co.nz",
              "houzz.co.uk",
              "houzz.ie",
              "houzz.de",
              "houzz.fr",
              "houzz.it",
              "houzz.es",
              "houzz.dk",
              "houzz.se",
              "houzz.com.sg",
              "houzz.in",
              "houzz.jp"
            ],
            "type": "string",
            "description": "Houzz operates a separate site per country. Pick the one that matches the pros you want. Applied in 'search' mode.",
            "default": "houzz.com"
          },
          "category": {
            "title": "Category",
            "enum": [
              "all",
              "interior-designers",
              "architects",
              "home-builders",
              "general-contractors",
              "design-build-firms",
              "kitchen-and-bath-designers",
              "kitchen-and-bath-remodelers",
              "kitchen-remodelers",
              "bathroom-remodelers",
              "landscape-architects",
              "landscape-contractors",
              "lighting-designers",
              "home-stagers",
              "photographers",
              "tile-and-stone-contractors",
              "custom-countertops",
              "custom-cabinets",
              "flooring-contractors",
              "painters",
              "deck-and-patio-builders",
              "swimming-pool-builders",
              "fence-contractors",
              "garage-door-services",
              "roofing-and-gutters",
              "siding-and-exteriors",
              "carpenters",
              "electricians",
              "plumbers",
              "hvac-contractors"
            ],
            "type": "string",
            "description": "Service category. Auto-mapped to the right Houzz category id per country at runtime.",
            "default": "interior-designers"
          },
          "queries": {
            "title": "Keywords (free-text)",
            "uniqueItems": true,
            "type": "array",
            "description": "Optional free-text searches (e.g. 'mid century kitchen', 'sustainable architect'). Each query runs as a separate search and combines with the chosen category and locations. Leave empty to skip keyword filtering.",
            "items": {
              "type": "string"
            }
          },
          "locations": {
            "title": "Locations",
            "uniqueItems": true,
            "type": "array",
            "description": "Cities, regions, or country segments. Format examples: 'Sydney--NSW', 'New-York--NY', 'Berlin--BE', 'CA'. Each location runs as a separate search and combines with the chosen category and keywords. Leave empty to scrape across all locations.",
            "items": {
              "type": "string"
            }
          },
          "reviewSort": {
            "title": "Review sort order",
            "enum": [
              "NEWEST",
              "OLDEST",
              "HIGHEST_RATING",
              "LOWEST_RATING"
            ],
            "type": "string",
            "description": "Order in which each pro's reviews are pulled.",
            "default": "NEWEST"
          },
          "maxReviewsPerPro": {
            "title": "Max reviews per pro",
            "minimum": 0,
            "type": "integer",
            "description": "Cap how many reviews to pull per pro in review mode. 0 = all of a pro's reviews.",
            "default": 0
          },
          "urls": {
            "title": "Directory URLs",
            "uniqueItems": true,
            "type": "array",
            "description": "Paste any Houzz directory or search URL. Pagination continues automatically from where you start. Multiple URLs supported.",
            "items": {
              "type": "string"
            }
          },
          "minRating": {
            "title": "Minimum rating",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Only return pros with average rating >= this value (1 to 5). 0 = include all.",
            "default": 0
          },
          "minReviewCount": {
            "title": "Minimum review count",
            "minimum": 0,
            "type": "integer",
            "description": "Only return pros with at least this many reviews. 0 = include all.",
            "default": 0
          },
          "verifiedOnly": {
            "title": "Verified pros only",
            "type": "boolean",
            "description": "Skip pros without a verified company profile.",
            "default": false
          },
          "maxPages": {
            "title": "Max pages per search",
            "minimum": 1,
            "type": "integer",
            "description": "Stop after this many SERP pages per search. Each page has 15 pros.",
            "default": 1
          },
          "maxListings": {
            "title": "Max pros total",
            "minimum": 0,
            "type": "integer",
            "description": "Hard cap on total pros emitted across all searches. 0 = unlimited (still capped by maxPages).",
            "default": 0
          },
          "fetchDetails": {
            "title": "Fetch full profile per pro",
            "type": "boolean",
            "description": "Visit each pro's detail page for richer fields: full aboutMe, all services, awards, social links, operating hours, featured review, per-aspect ratings (communication / on-time / quality / value). Adds ~1 fetch per pro. Auto-enabled in 'review' mode.",
            "default": false
          },
          "resumeFromRunId": {
            "title": "Resume from run/dataset ID",
            "type": "string",
            "description": "Paste a previous run ID or dataset ID to continue an interrupted crawl: records already collected there are skipped so you get only what's still missing. One-off continuation of a SPECIFIC run - for ongoing scheduled monitoring of the same search, use Incremental mode below instead."
          },
          "incrementalMode": {
            "title": "Incremental mode (recurring monitoring)",
            "type": "boolean",
            "description": "For a search you run on a schedule (e.g. daily/weekly): remembers what this exact search returned last time and classifies every pro as NEW / UPDATED / UNCHANGED / REAPPEARED / EXPIRED, so you can act on only what changed. Off by default so existing scheduled runs are unaffected. Separate from Resume above, which continues one specific interrupted run. Uses State key below to isolate different searches; see Emit unchanged rows / Emit expired rows to control which of those get pushed (both bill extra rows when on).",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional)",
            "type": "string",
            "description": "Names the saved baseline Incremental mode compares against. Leave empty to auto-derive one from your mode/category/locations/queries/filters - two differently-configured searches never share a baseline even with this left empty. Set your own text only if you want to explicitly reuse or separate baselines yourself. Ignored when Incremental mode is off."
          },
          "emitUnchanged": {
            "title": "Emit unchanged rows",
            "type": "boolean",
            "description": "When Incremental mode is on: also push rows classified UNCHANGED (identical to last run), not just NEW/UPDATED/REAPPEARED/EXPIRED. Off by default to save you from paying for rows that didn't change. Turning this on bills the per-result event (and the detail-enrichment surcharge, if Fetch full profile is on) for every unchanged row too.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired rows",
            "type": "boolean",
            "description": "When Incremental mode is on: push a synthetic EXPIRED row for pros tracked in a previous run that no longer appear in this one. Only fires after a run that scanned every page of every search with no cap/resume truncating it - a partial scan can't tell 'gone' apart from 'not reached yet', so it's skipped (with a log line) otherwise. Off by default; turning it on bills the per-result event for each EXPIRED row emitted.",
            "default": false
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "The default proxy setting works on any Apify plan, including the free tier. Residential is optional and recommended for large volumes. The country is auto-applied to match the chosen Houzz country site when residential is selected.",
            "default": {
              "useApifyProxy": true
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON; the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com)."
          },
          "notionParentPageUrl": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}