{
  "openapi": "3.0.1",
  "info": {
    "title": "Building Permits Scraper — Contractor & Construction Leads",
    "description": "Multi-city building permits from city/county open-data APIs. cities[] + keyword. Contractor names, addresses, work type. Soft CTA → Skip Trace / UCC / Code Violations.",
    "version": "3.7",
    "x-build-id": "5kUsVN11WncFXo5Wp"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/intelscrape~building-permit-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-intelscrape-building-permit-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/intelscrape~building-permit-scraper/runs": {
      "post": {
        "operationId": "runs-sync-intelscrape-building-permit-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/intelscrape~building-permit-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-intelscrape-building-permit-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": {
          "city": {
            "title": "City",
            "type": "string",
            "description": "US city name (e.g. Chicago, Austin, Miami). Strongly recommended — improves city labeling and portal selection. Legacy alias: targetLocation (\"Austin, TX\")."
          },
          "cities": {
            "title": "Cities (multi-city list)",
            "type": "array",
            "description": "Optional list of US city names to scrape in one run (e.g. [\"Chicago\", \"Austin\", \"Miami\"]). When non-empty, each city is discovered separately and extractTop100 / extractStateMatrix are ignored. Cap with maxCities (default 25 for this list). Leave empty to use single City above.",
            "items": {
              "type": "string"
            }
          },
          "extractTop100": {
            "title": "Extract Top-100 USA Cities (Mass Execution)",
            "type": "boolean",
            "description": "Bypass manual search and autonomously scan all 100 largest municipal databases sequentially using the Universal Discovery Core.",
            "default": false
          },
          "extractStateMatrix": {
            "title": "National Scan (2,500 Cities)",
            "type": "boolean",
            "description": "Execute sequentially across all 50 US States autonomously extracting Socrata instances and injecting Walled-Garden targets. Extremely intensive.",
            "default": false
          },
          "state": {
            "title": "State",
            "enum": [
              "All States",
              "AL",
              "AK",
              "AZ",
              "AR",
              "CA",
              "CO",
              "CT",
              "DE",
              "FL",
              "GA",
              "HI",
              "ID",
              "IL",
              "IN",
              "IA",
              "KS",
              "KY",
              "LA",
              "ME",
              "MD",
              "MA",
              "MI",
              "MN",
              "MS",
              "MO",
              "MT",
              "NE",
              "NV",
              "NH",
              "NJ",
              "NM",
              "NY",
              "NC",
              "ND",
              "OH",
              "OK",
              "OR",
              "PA",
              "RI",
              "SC",
              "SD",
              "TN",
              "TX",
              "UT",
              "VT",
              "VA",
              "WA",
              "WV",
              "WI",
              "WY"
            ],
            "type": "string",
            "description": "Select a US State. Highly recommended for finding smaller cities.",
            "default": "All States"
          },
          "permitType": {
            "title": "Permit type",
            "enum": [
              "All Types",
              "New Construction",
              "Renovation / Remodel",
              "Demolition",
              "Roofing",
              "Solar / Photovoltaic",
              "Electrical",
              "Plumbing",
              "HVAC / Mechanical",
              "Fire Protection",
              "Addition / ADU",
              "Commercial",
              "Sign"
            ],
            "type": "string",
            "description": "What kind of permits are you looking for?",
            "default": "All Types"
          },
          "keyword": {
            "title": "Keyword filter (free text)",
            "type": "string",
            "description": "Optional free-text filter applied after scrape (case-insensitive). Matches permit description, permit type, contractor, or address — e.g. roof, solar, HVAC, pool. Rival-parity for keyword construction leads. Leave empty for no extra filter."
          },
          "zipCodes": {
            "title": "ZIP codes filter",
            "type": "array",
            "description": "Optional list of ZIP codes to keep after scrape (e.g. [\"60601\",\"60602\"]). Normalized to 5-digit when possible. Empty/absent = no ZIP filter.",
            "items": {
              "type": "string"
            }
          },
          "timePeriod": {
            "title": "Time period",
            "enum": [
              "Last 7 days",
              "Last 30 days",
              "Last 90 days",
              "Last 6 months",
              "Last year",
              "Last 2 years",
              "All time"
            ],
            "type": "string",
            "description": "How far back do you want to search?",
            "default": "Last 30 days"
          },
          "lastNDays": {
            "title": "Last N days (fresh window)",
            "minimum": 1,
            "maximum": 3650,
            "type": "integer",
            "description": "Convenience date window — e.g. 30 = permits issued in the last 30 days (rival lastNDays / daysBack). Overrides Time period. Explicit Date from / Date to win if set. freshLeadsOnly sets this to 30 when empty."
          },
          "dateFrom": {
            "title": "Date from (YYYY-MM-DD)",
            "type": "string",
            "description": "Optional start date (YYYY-MM-DD). When set, overrides the Time period dropdown window. Leave empty to use Time period."
          },
          "dateTo": {
            "title": "Date to (YYYY-MM-DD)",
            "type": "string",
            "description": "Optional end date (YYYY-MM-DD). When set with Date from, overrides the Time period dropdown. Leave empty for open-ended."
          },
          "minCost": {
            "title": "Minimum project cost ($)",
            "minimum": 0,
            "type": "integer",
            "description": "Only show permits with estimated cost above this amount."
          },
          "maxCost": {
            "title": "Maximum project cost ($)",
            "minimum": 0,
            "type": "integer",
            "description": "Optional. Keep only permits with estimatedValue ≤ this amount (rival parity with minCost). Leave empty for no upper bound."
          },
          "contractorContains": {
            "title": "Contractor name contains",
            "type": "string",
            "description": "Optional case-insensitive substring match on contractor / applicant name after scrape (e.g. \"Apex\", \"Roofing LLC\"). Leave empty for no contractor filter."
          },
          "tradeCategories": {
            "title": "Trade categories (multi)",
            "type": "array",
            "description": "Optional multi trade filter. Keep permits matching ANY category (OR). Aliases map to taxonomy: Roofing, Solar, HVAC/Mechanical, Electrical, Plumbing, Demolition, New Construction, Renovation, Addition/ADU, Fire Protection, Commercial, Sign. When non-empty, preferred over single Permit type for keep-filter.",
            "items": {
              "type": "string"
            }
          },
          "onlyNewConstruction": {
            "title": "Only new construction",
            "type": "boolean",
            "description": "When true, keep only New Construction / new-build style permits (uses classifyPermitType + type keywords). Default false.",
            "default": false
          },
          "maxResults": {
            "title": "How many leads",
            "minimum": 1,
            "maximum": 50000,
            "type": "integer",
            "description": "Maximum permits to return (min 1). Each delivered permit bills $0.005 (PPE). Start small (10–50) to validate city coverage before scaling.",
            "default": 50
          },
          "addressFilter": {
            "title": "Street name filter",
            "type": "string",
            "description": "Filter by street name (e.g., Broadway, Main St)."
          },
          "incrementalMode": {
            "title": "Incremental Mode (New Permits Only)",
            "type": "boolean",
            "description": "If enabled, the scraper remembers past runs and only returns newly discovered permits.",
            "default": false
          },
          "freshLeadsOnly": {
            "title": "Fresh leads only (last 30 days)",
            "type": "boolean",
            "description": "When true, equivalent to lastNDays=30 if lastNDays not set, or tightens to 30 if lastNDays > 30 (inexhaustible_glass parity). Explicit dateFrom/dateTo still win.",
            "default": false
          },
          "minLeadScore": {
            "title": "Minimum lead score",
            "enum": [
              "HOT",
              "WARM",
              "COLD"
            ],
            "type": "string",
            "description": "Optional post-scrape floor on categorical leadScore: HOT (only HOT), WARM (WARM+HOT), COLD (all). Output also includes leadScoreNumeric (0–100) and daysSinceIssue."
          },
          "onlyNewResults": {
            "title": "Only new results (alias)",
            "type": "boolean",
            "description": "Alias for Incremental Mode — only return newly discovered permits since the last run (4l3c onlyNewResults parity). Prefer Incremental Mode checkbox; both enable the same behavior.",
            "default": false
          },
          "enrichContractors": {
            "title": "Enrich contractor phone & email (optional, extra fee)",
            "type": "boolean",
            "description": "ON by default. When ON, best-effort Google Maps lookup for contractor phone/email/website. Only succeeds when the owner backend token is configured. Each successful enrichment costs an extra $0.05 (contractor-enrichment event) on top of the $0.005 per permit. Permit rows are always public-record fields (address, value, contractor NAME when the portal provides it) — phones/emails are NOT guaranteed.",
            "default": true
          },
          "maxContactsToEnrich": {
            "title": "Max contacts to enrich (advanced)",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Max contractor enrichments per run when enrichment is ON. Each hit bills $0.05. Default 50 keeps costs predictable.",
            "default": 50
          },
          "enableCensusGeocoding": {
            "title": "Enable Census Geocoding Fallback",
            "type": "boolean",
            "description": "If a city portal fails to provide latitude/longitude, automatically geocode the address using the US Census Bureau API.",
            "default": true
          },
          "enableContractorRollup": {
            "title": "Contractor Rollup Summary",
            "type": "boolean",
            "description": "ON by default. Groups delivered permits by contractor (top 25 by count then valuation) and pushes contractor-rollup rows plus one contractor-rollup-summary. Soft CTA links Skip Trace PRO / UCC Lien / Code Violations. When the Store PPE event is live, one contractor-rollup charge applies to the summary (not per contractor row).",
            "default": true
          },
          "webhookUrl": {
            "title": "Webhook URL (Make.com / Zapier)",
            "type": "string",
            "description": "Optional webhook URL to POST results to when the run completes."
          },
          "csvUrl": {
            "title": "📄 Bulk CSV Upload (URL)",
            "type": "string",
            "description": "Provide a link to a raw CSV file (e.g. Google Sheets Export) containing 'City' or 'Location' headers to process huge lists automatically."
          },
          "maxCities": {
            "title": "Max cities to scan (advanced)",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "When searching all cities: how many city portals to query.",
            "default": 50
          },
          "maxPerCity": {
            "title": "Max results per city (advanced)",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Maximum records to fetch from each city portal.",
            "default": 500
          },
          "stateKey": {
            "title": "Monitoring state name",
            "type": "string",
            "description": "Optional. Names the saved state for incremental mode so you can run several independent schedules from one Actor. Leave blank unless you need more than one."
          },
          "socrataAppToken": {
            "title": "Socrata App Token (optional)",
            "type": "string",
            "description": "Optional free token from a city open-data portal — raises Socrata rate limits on large runs. Leave empty for normal use."
          },
          "demoMode": {
            "title": "Demo mode (fictional sample)",
            "type": "boolean",
            "description": "Returns one clearly FICTIONAL sample permit so you can inspect the Output schema. No live municipal scrape. Not a real lead.",
            "default": false
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}