{
  "openapi": "3.0.1",
  "info": {
    "title": "Building Permits Scraper — Roofing & Construction Leads",
    "description": "Scrape building permits and contractor leads from 120 official open-data datasets in 97 US and Canadian cities and counties (NYC, Chicago, LA, Seattle, Toronto, Calgary, more), incl. electrical, HVAC, plumbing, roof and solar permits. Contractor name, license, phone where published. $0.002/permit.",
    "version": "0.1",
    "x-build-id": "PKuOKNR2wQSUJ1xM3"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/owlabee~building-permits-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-owlabee-building-permits-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/owlabee~building-permits-scraper/runs": {
      "post": {
        "operationId": "runs-sync-owlabee-building-permits-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/owlabee~building-permits-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-owlabee-building-permits-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": [
          "jurisdictions"
        ],
        "properties": {
          "jurisdictions": {
            "title": "Jurisdictions",
            "minItems": 0,
            "uniqueItems": true,
            "type": "array",
            "description": "Cities, counties and states to query. Each entry is one official open-data dataset (Socrata, CKAN, ArcGIS or Carto); some cities have extra entries for their trade-permit datasets (electrical, mechanical/HVAC, plumbing, roof, solar). \"All 61 original US jurisdictions\" is the list as of October 2026 and does not grow, so a saved input keeps its cost; \"All US jurisdictions\" and \"All Canadian jurisdictions\" include the newer entries. Each jurisdiction crawled is one paid event; see the README table for source, freshness and update frequency. Canadian records carry country \"CA\", the province in state, costs in CAD, and business names only. May be left empty when \"Discover Socrata datasets\" is on.",
            "items": {
              "type": "string",
              "enum": [
                "all",
                "all-us",
                "all-canada",
                "nyc",
                "chicago",
                "los-angeles",
                "san-francisco",
                "seattle",
                "austin",
                "philadelphia",
                "boston",
                "washington-dc",
                "miami-dade-county",
                "maricopa-county-az",
                "nashville",
                "detroit",
                "raleigh",
                "baltimore",
                "cincinnati",
                "pittsburgh",
                "louisville",
                "memphis",
                "new-orleans",
                "tucson",
                "buffalo",
                "orlando",
                "montgomery-county-md-residential",
                "montgomery-county-md-commercial",
                "cambridge-ma",
                "mesa",
                "san-diego-county",
                "marin-county",
                "baton-rouge",
                "norfolk",
                "pierce-county-wa",
                "everett",
                "somerville-ma",
                "college-station",
                "corona-ca",
                "prince-georges-county",
                "urbana-il",
                "new-jersey",
                "collin-county-tx",
                "denver-residential",
                "denver-commercial",
                "columbus",
                "charlotte-mecklenburg",
                "fort-worth",
                "harris-county-tx",
                "miami",
                "minneapolis",
                "cleveland",
                "wake-county-nc",
                "durham",
                "anaheim",
                "tempe",
                "scottsdale",
                "bellevue-wa",
                "forsyth-county-ga",
                "charleston-sc",
                "portland-or",
                "las-vegas",
                "san-antonio",
                "san-jose",
                "los-angeles-electrical",
                "los-angeles-mechanical",
                "seattle-trade",
                "seattle-electrical",
                "nyc-electrical",
                "montgomery-county-md-electrical",
                "montgomery-county-md-mechanical",
                "cambridge-ma-roof",
                "cambridge-ma-solar",
                "cambridge-ma-electrical",
                "cambridge-ma-plumbing",
                "cambridge-ma-mechanical",
                "nashville-trade",
                "raleigh-trade",
                "tacoma-wa",
                "henderson-nv-residential",
                "henderson-nv-other",
                "cape-coral-fl",
                "baltimore-county-md",
                "baltimore-county-md-electrical",
                "baltimore-county-md-plumbing",
                "allentown-pa",
                "bend-or",
                "overland-park-ks",
                "tyler-tx",
                "st-charles-il",
                "placentia-ca",
                "campbell-ca",
                "atascadero-ca",
                "elk-grove-ca",
                "hutto-tx",
                "san-marcos-tx",
                "tallahassee-leon-sf",
                "normal-il",
                "morgantown-wv",
                "cody-wy",
                "weston-fl",
                "benton-county-wa",
                "fulton-county-oh",
                "talent-or",
                "cook-county-il",
                "toronto-on",
                "montreal-qc",
                "quebec-city-qc",
                "calgary-ab",
                "calgary-ab-electrical",
                "calgary-ab-mechanical",
                "calgary-ab-plumbing",
                "edmonton-ab",
                "winnipeg-mb",
                "winnipeg-mb-trade",
                "halifax-ns",
                "kitchener-on",
                "new-westminster-bc",
                "prince-george-bc",
                "squamish-bc",
                "caledon-on",
                "whitchurch-stouffville-on",
                "miramichi-nb"
              ],
              "enumTitles": [
                "All 61 original US jurisdictions (the October 2026 list; newer ones are opt-in)",
                "All US jurisdictions, including the November 2026 additions and trade-permit datasets",
                "All Canadian jurisdictions (business names only)",
                "New York City, NY (DOB NOW approved permits)",
                "Chicago, IL",
                "Los Angeles, CA",
                "San Francisco, CA",
                "Seattle, WA",
                "Austin, TX",
                "Philadelphia, PA",
                "Boston, MA",
                "Washington, DC",
                "Miami-Dade County, FL (unincorporated + county-permitted)",
                "Maricopa County, AZ (unincorporated)",
                "Nashville / Davidson County, TN",
                "Detroit, MI",
                "Raleigh, NC",
                "Baltimore, MD",
                "Cincinnati, OH",
                "Pittsburgh, PA",
                "Louisville / Jefferson County, KY",
                "Memphis / Shelby County, TN",
                "New Orleans, LA",
                "Tucson, AZ (residential permits)",
                "Buffalo, NY",
                "Orlando, FL",
                "Montgomery County, MD (residential)",
                "Montgomery County, MD (commercial)",
                "Cambridge, MA (addition / alteration permits)",
                "Mesa, AZ",
                "San Diego County, CA (unincorporated)",
                "Marin County, CA",
                "Baton Rouge / East Baton Rouge Parish, LA",
                "Norfolk, VA",
                "Pierce County, WA (unincorporated)",
                "Everett, WA",
                "Somerville, MA",
                "College Station, TX",
                "Corona, CA",
                "Prince George's County, MD",
                "Urbana, IL",
                "New Jersey (statewide, all municipalities)",
                "Collin County, TX (appraisal district permit feed)",
                "Denver, CO (residential construction)",
                "Denver, CO (commercial construction)",
                "Columbus, OH",
                "Charlotte / Mecklenburg County, NC",
                "Fort Worth, TX",
                "Harris County, TX (unincorporated, Houston area)",
                "Miami, FL (City of Miami)",
                "Minneapolis, MN",
                "Cleveland, OH",
                "Wake County, NC",
                "Durham / Durham County, NC",
                "Anaheim, CA",
                "Tempe, AZ",
                "Scottsdale, AZ",
                "Bellevue, WA",
                "Forsyth County, GA",
                "Charleston, SC (new construction)",
                "Portland, OR (residential new construction)",
                "Las Vegas, NV",
                "San Antonio, TX",
                "San Jose, CA",
                "Los Angeles, CA (electrical permits)",
                "Los Angeles, CA (mechanical, HVAC and plumbing permits)",
                "Seattle, WA (trade permits: mechanical, plumbing, gas)",
                "Seattle, WA (electrical permits)",
                "New York City, NY (DOB NOW electrical permits)",
                "Montgomery County, MD (electrical)",
                "Montgomery County, MD (mechanical / HVAC)",
                "Cambridge, MA (roof permits)",
                "Cambridge, MA (solar permits)",
                "Cambridge, MA (electrical permits)",
                "Cambridge, MA (plumbing permits)",
                "Cambridge, MA (mechanical / HVAC permits)",
                "Nashville / Davidson County, TN (trade permits)",
                "Raleigh, NC (trade and other non-building permits)",
                "Tacoma, WA",
                "Henderson, NV (residential dwellings)",
                "Henderson, NV (other building permits)",
                "Cape Coral, FL",
                "Baltimore County, MD (building permits)",
                "Baltimore County, MD (electrical permits)",
                "Baltimore County, MD (plumbing permits)",
                "Allentown, PA",
                "Bend, OR",
                "Overland Park, KS",
                "Tyler, TX",
                "St. Charles, IL",
                "Placentia, CA",
                "Campbell, CA",
                "Atascadero, CA",
                "Elk Grove, CA",
                "Hutto, TX",
                "San Marcos, TX",
                "Tallahassee / Leon County, FL (single-family new construction)",
                "Normal, IL",
                "Morgantown, WV",
                "Cody, WY",
                "Weston, FL",
                "Benton County, WA (unincorporated)",
                "Fulton County, OH",
                "Talent, OR",
                "Cook County, IL (assessor permit feed, all municipalities)",
                "Toronto, ON",
                "Montréal, QC",
                "Québec City, QC",
                "Calgary, AB (building permits)",
                "Calgary, AB (electrical permits)",
                "Calgary, AB (HVAC / mechanical permits)",
                "Calgary, AB (plumbing and gas permits)",
                "Edmonton, AB",
                "Winnipeg, MB (building permits)",
                "Winnipeg, MB (trade permits: electrical, plumbing, mechanical)",
                "Halifax Regional Municipality, NS",
                "Kitchener, ON",
                "New Westminster, BC",
                "Prince George, BC",
                "Squamish, BC",
                "Caledon, ON",
                "Whitchurch-Stouffville, ON",
                "Greater Miramichi Regional Service Commission, NB"
              ]
            },
            "default": [
              "chicago",
              "seattle"
            ]
          },
          "discoverSocrata": {
            "title": "Discover Socrata datasets for another place",
            "type": "boolean",
            "description": "Best effort for places not in the list: search the public Socrata Discovery API for building-permit datasets published for \"Place to discover\", map their columns automatically, and crawl the best matches like built-in jurisdictions. Every record from a discovered dataset carries mappingConfidence (high, medium or low) and discoveredDataset. A place that is already built in returns the built-in entry. Many cities publish on ArcGIS or CKAN instead, which discovery does not search.",
            "default": false
          },
          "discoveryPlace": {
            "title": "Place to discover",
            "type": "string",
            "description": "City or county to search for, optionally with the two-letter state: \"Cook County, IL\", \"Corona, CA\", \"Austin TX\". Used only when \"Discover Socrata datasets\" is on."
          },
          "maxDiscoveredDatasets": {
            "title": "Max discovered datasets",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "How many discovered datasets to crawl (1–5), best match first. Each one is billed like a jurisdiction.",
            "default": 2
          },
          "issuedWithinDays": {
            "title": "Issued within (days)",
            "minimum": 1,
            "maximum": 3650,
            "type": "integer",
            "description": "Only permits whose issued date falls in the last N days (1–3650). Applied server-side on every portal that supports it, so narrow windows are fast and cheap.",
            "default": 30
          },
          "permitTypes": {
            "title": "Permit type keywords (optional)",
            "type": "array",
            "description": "Keep only permits whose type or subtype contains one of these words, case-insensitive (for example \"electrical\", \"roof\", \"solar\", \"demolition\", \"new construction\"). Each portal uses its own type vocabulary, so prefer generic words. Applied server-side where the API allows, otherwise client-side.",
            "items": {
              "type": "string"
            }
          },
          "keyword": {
            "title": "Work description keyword (optional)",
            "type": "string",
            "description": "Keep only permits whose work description contains this text, case-insensitive (for example \"solar\", \"re-roof\", \"kitchen\", \"ADU\"). Applied server-side where the API allows, otherwise client-side."
          },
          "minEstimatedCost": {
            "title": "Minimum estimated cost (local currency, optional)",
            "minimum": 0,
            "type": "integer",
            "description": "Drop permits whose declared valuation / estimated cost is below this amount, compared in each record's own currency (USD for US jurisdictions, CAD for Canadian ones; no conversion). Permits with no published cost are kept (cost is null) so you do not silently lose jurisdictions that do not publish valuations."
          },
          "maxResultsPerJurisdiction": {
            "title": "Max permits per jurisdiction",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Upper bound on permit records saved per jurisdiction per run (newest first). Use it together with the run's maximum cost to control spend.",
            "default": 1000
          },
          "maxSecondsPerJurisdiction": {
            "title": "Max seconds per jurisdiction",
            "minimum": 60,
            "maximum": 3600,
            "type": "integer",
            "description": "Time budget for one jurisdiction (all its pages). A jurisdiction that yields no permits for 60 seconds, or uses up this budget, is cut off: permits already fetched are kept; with nothing fetched it becomes one error item (TIME_BUDGET).",
            "default": 900
          },
          "onlyNewSinceLastRun": {
            "title": "Only new permits since last run",
            "type": "boolean",
            "description": "Monitor mode for schedules: remember the permit numbers already seen per jurisdiction (up to 50,000 each) in the state store and emit only permits not seen before, flagged isNew: true. The first run is a baseline and emits (and charges for) everything in the window.",
            "default": false
          },
          "stateStoreName": {
            "title": "State store name",
            "type": "string",
            "description": "Named key-value store that holds the seen-permit sets for monitor mode. Use a different name per schedule if two schedules query the same jurisdiction with different filters.",
            "default": "building-permits-scraper-state"
          },
          "includeRaw": {
            "title": "Include raw source record",
            "type": "boolean",
            "description": "Attach the untouched source row as \"raw\" on every permit, so you can read jurisdiction-specific fields (fees, units, zoning, inspector...) that the normalized schema does not carry. Roughly doubles dataset size.",
            "default": false
          },
          "socrataAppToken": {
            "title": "Socrata app token (optional)",
            "type": "string",
            "description": "Optional free Socrata application token (sign up on any data.*.gov portal → Developer Settings). Raises the per-IP rate limit for the Socrata-backed jurisdictions. Works without it. Stored encrypted and never logged."
          },
          "webhookUrl": {
            "title": "Webhook URL (optional)",
            "pattern": "^https?://.+",
            "type": "string",
            "description": "If set, the Actor POSTs a JSON run summary plus the emitted permits (max 500; only the new ones in monitor mode) to this URL when it finishes. Failures are logged, never fatal."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}