{
  "openapi": "3.0.1",
  "info": {
    "title": "Accela & EnerGov Building Permit Portal Scraper (Any City)",
    "description": "Scrape building permits from US cities and counties on Accela Citizen Access or Tyler EnerGov Citizen Self Service portals: permit type, status, dates, valuation, address, contractor. Normalized JSON, daily new-permit monitor with webhooks. No login, no proxies. $0.003/permit.",
    "version": "0.1",
    "x-build-id": "sGe4Z9DcvoyghNvih"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/owlabee~accela-energov-permit-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-owlabee-accela-energov-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/owlabee~accela-energov-permit-scraper/runs": {
      "post": {
        "operationId": "runs-sync-owlabee-accela-energov-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/owlabee~accela-energov-permit-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-owlabee-accela-energov-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",
        "required": [
          "jurisdictions"
        ],
        "properties": {
          "jurisdictions": {
            "title": "Jurisdictions",
            "minItems": 1,
            "uniqueItems": true,
            "type": "array",
            "description": "Cities and counties to query. Each entry is one Accela Citizen Access (ACA) or Tyler EnerGov Citizen Self Service portal from the verified registry; pick \"All supported jurisdictions\" to crawl every entry, or the per-vendor groups. Each portal queried is one paid portal-run event; see the README table for engine, date semantics and volume per jurisdiction.",
            "items": {
              "type": "string",
              "enum": [
                "all",
                "all-energov",
                "all-accela",
                "richmond-va",
                "overland-park-ks",
                "southlake-tx",
                "doral-fl",
                "hernando-county-fl",
                "riverside-county-ca",
                "santa-fe-nm",
                "danville-ca",
                "carson-ca",
                "imperial-beach-ca",
                "wilmington-nc",
                "la-vergne-tn",
                "grand-traverse-county-mi",
                "reading-pa",
                "shelton-wa",
                "snohomish-wa",
                "rockland-county-ny",
                "sacramento-ca",
                "tampa-fl",
                "hillsborough-county-fl",
                "oakland-ca",
                "san-mateo-county-ca",
                "stockton-ca",
                "monterey-county-ca",
                "santa-clara-county-ca",
                "mesa-az",
                "omaha-ne",
                "oklahoma-city-ok",
                "fort-worth-tx",
                "denver-co",
                "charlotte-nc"
              ],
              "enumTitles": [
                "All supported jurisdictions (31 portals)",
                "All EnerGov portals (17)",
                "All Accela Citizen Access portals (14)",
                "Richmond, VA (EnerGov)",
                "Overland Park, KS (EnerGov)",
                "Southlake, TX (EnerGov)",
                "Doral, FL (EnerGov)",
                "Hernando County, FL (EnerGov)",
                "Riverside County, CA (unincorporated) (EnerGov)",
                "Santa Fe, NM (EnerGov)",
                "Danville, CA (EnerGov)",
                "Carson, CA (EnerGov)",
                "Imperial Beach, CA (EnerGov)",
                "Wilmington, NC (EnerGov)",
                "La Vergne, TN (EnerGov)",
                "Grand Traverse County, MI (EnerGov)",
                "Reading, PA (EnerGov)",
                "Shelton, WA (EnerGov)",
                "Snohomish, WA (EnerGov)",
                "Rockland County, NY (EnerGov)",
                "Sacramento, CA (Accela ACA)",
                "Tampa, FL (Accela ACA)",
                "Hillsborough County, FL (Accela ACA)",
                "Oakland, CA (Accela ACA)",
                "San Mateo County, CA (Accela ACA)",
                "Stockton, CA (Accela ACA)",
                "Monterey County, CA (Accela ACA)",
                "Santa Clara County, CA (Accela ACA)",
                "Mesa, AZ (Accela ACA)",
                "Omaha, NE (Accela ACA)",
                "Oklahoma City, OK (Accela ACA)",
                "Fort Worth, TX (Accela ACA)",
                "Denver, CO (Accela ACA)",
                "Charlotte, NC (land development) (Accela ACA)"
              ]
            },
            "default": [
              "overland-park-ks",
              "southlake-tx"
            ]
          },
          "issuedWithinDays": {
            "title": "Issued within (days)",
            "minimum": 1,
            "maximum": 365,
            "type": "integer",
            "description": "Only permits whose portal date falls in the last N days (1–365). EnerGov portals filter on the issued date; Accela Citizen Access general search filters on the record (application) date, so on ACA this is \"applied within\". Applied server-side on every portal, so narrow windows are fast and cheap.",
            "default": 30
          },
          "permitTypes": {
            "title": "Permit type keywords (optional)",
            "type": "array",
            "description": "Keep only permits whose type or work class contains one of these words, case-insensitive (for example \"electrical\", \"roof\", \"solar\", \"demolition\", \"residential\"). Each portal uses its own type vocabulary, so prefer generic words. Applied client-side after the date filter.",
            "items": {
              "type": "string"
            }
          },
          "keyword": {
            "title": "Work description keyword (optional)",
            "type": "string",
            "description": "Keep only permits whose description (or type) contains this text, case-insensitive (for example \"solar\", \"re-roof\", \"kitchen\", \"ADU\"). EnerGov applies it server-side on the description; Accela applies it client-side."
          },
          "minEstimatedCost": {
            "title": "Minimum valuation (USD, optional)",
            "minimum": 0,
            "type": "integer",
            "description": "Drop permits whose declared job value / valuation is below this amount. Valuation is only known when includeDetails is on; permits with no published value are kept (estimatedCost is null)."
          },
          "maxResultsPerJurisdiction": {
            "title": "Max permits per jurisdiction",
            "minimum": 1,
            "maximum": 20000,
            "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": 500
          },
          "includeDetails": {
            "title": "Fetch permit details",
            "type": "boolean",
            "description": "Open every permit's detail record or page to add valuation (estimatedCost), contractor and license, owner, applicant and parcel number. One extra request per permit, charged as a permit-detail-fetched event; roughly 1 s per permit per portal. Off for the daily Store test.",
            "default": false
          },
          "onlyNewSinceLastRun": {
            "title": "Only new permits since last run",
            "type": "boolean",
            "description": "Monitor mode for schedules: remember the permit ids 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. Details are fetched only for new permits.",
            "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": "accela-energov-permit-scraper-state"
          },
          "includeRaw": {
            "title": "Include raw source record",
            "type": "boolean",
            "description": "Attach the untouched portal row (and detail, when fetched) as \"raw\" on every permit, so you can read portal-specific fields the normalized schema does not carry. Roughly doubles dataset size.",
            "default": false
          },
          "accelaAppId": {
            "title": "Accela developer app id (optional)",
            "type": "string",
            "description": "Optional app id from a free Accela developer-portal app. When set, Accela jurisdictions are queried through the official Construct API in its anonymous mode (JSON, includes addresses, parcels, professionals, owners) instead of the Citizen Access page. Agencies that do not allow anonymous API access return an error item; remove the id to use the page engine again. 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}