{
  "openapi": "3.0.1",
  "info": {
    "title": "US Building Permits Scraper - 10 Cities, One Schema",
    "description": "Scrape US building permits from 10 city open-data portals into one clean schema. Contractor and applicant leads with address, valuation, and dates. Filter and export to CSV.",
    "version": "1.0",
    "x-build-id": "rO5fDcBFmbYId7e6b"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/maydit~us-building-permits-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-maydit-us-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/maydit~us-building-permits-scraper/runs": {
      "post": {
        "operationId": "runs-sync-maydit-us-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/maydit~us-building-permits-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-maydit-us-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",
        "properties": {
          "cities": {
            "title": "Supported city and county sources",
            "type": "array",
            "description": "Which city portals to scrape. Each selected city is queried separately and contributes up to \"Max results per city\" records, so picking just your service area is both faster and cheaper than the default of all 10. Leave empty to scrape all supported cities.",
            "items": {
              "type": "string",
              "enum": [
                "chicago",
                "san_francisco",
                "new_york",
                "austin",
                "seattle",
                "los_angeles",
                "baton_rouge",
                "cincinnati",
                "mesa",
                "marin_county"
              ],
              "enumTitles": [
                "Chicago, IL",
                "San Francisco, CA",
                "New York, NY",
                "Austin, TX",
                "Seattle, WA",
                "Los Angeles, CA",
                "Baton Rouge, LA",
                "Cincinnati, OH",
                "Mesa, AZ",
                "Marin County, CA"
              ]
            },
            "default": [
              "chicago",
              "san_francisco",
              "new_york",
              "austin",
              "seattle",
              "los_angeles",
              "baton_rouge",
              "cincinnati",
              "mesa",
              "marin_county"
            ]
          },
          "issuedSince": {
            "title": "Issued since",
            "type": "string",
            "description": "Only permits issued on or after this date (YYYY-MM-DD). Use this for recurring/monitoring runs, e.g. last 7 days."
          },
          "issuedUntil": {
            "title": "Issued until",
            "type": "string",
            "description": "Only permits issued on or before this date, format YYYY-MM-DD (e.g. 2026-06-30). Pair it with \"Issued since\" to pull one month; leave it empty to run right up to the latest data each city has published."
          },
          "permitTypeKeywords": {
            "title": "Permit type keywords",
            "type": "array",
            "description": "Only keep permits whose type/description/class contains one of these keywords (case-insensitive). E.g. 'solar', 'roof', 'pool', 'demolition'. Leave empty for all.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "minValuation": {
            "title": "Minimum declared job valuation (USD)",
            "type": "integer",
            "description": "Only keep permits whose reported job valuation is at or above this amount, e.g. 50000 for larger projects. Setting it also drops permits where the city published no valuation at all - most cities fill this in, but Austin publishes a job value on only about 15% of recent permits."
          },
          "onlyWithContractor": {
            "title": "Only permits with a contractor name",
            "type": "boolean",
            "description": "Keep only records that include a contractor or company name - best for lead generation, since a permit without a name is not a callable lead. Coverage varies by portal: San Francisco and Los Angeles publish no contractor at all, and Seattle fills it on under 10% of permits, so turning this on removes those cities from your results almost entirely.",
            "default": false
          },
          "maxResultsPerCity": {
            "title": "Maximum records per source",
            "minimum": 1,
            "type": "integer",
            "description": "Upper bound on permits returned per city per run - with 10 cities selected, 1000 here means up to 10,000 records. The run also stops after scanning 50,000 source rows per city, so a narrow keyword or valuation filter can return fewer than this cap even when more permits exist.",
            "default": 1000
          },
          "maxRunSeconds": {
            "title": "Run time budget (seconds)",
            "minimum": 30,
            "type": "integer",
            "description": "Wall-clock budget for this run, in seconds. When it is reached the Actor stops cleanly and finishes successfully with the rows it already collected, instead of being killed mid-run. Cities are fetched one after another, up to 50 pages each; a city not reached in time is reported in the run SUMMARY. Raise it (and the run timeout in Run options) for a deliberately large job.",
            "default": 240
          },
          "includeRaw": {
            "title": "Include raw source record",
            "type": "boolean",
            "description": "Attach the full original source record to each result under 'raw'. Increases output size.",
            "default": false
          },
          "socrataAppToken": {
            "title": "Socrata app token (optional)",
            "type": "string",
            "description": "Optional Socrata app token to raise API rate limits on large runs. Free to obtain from any Socrata portal. Not required for normal use."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}