Seattle Building Permits Scraper
Pricing
from $3.00 / 1,000 results
Seattle Building Permits Scraper
Scrape live building, trade, and land-use permit records from the City of Seattle's official permit portal. Filter by date range, permit type, status, and address.
Pricing
from $3.00 / 1,000 results
Rating
0.0
(0)
Developer
Crawler Bros
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Scrape live building, trade, and land-use permit records from the City of Seattle's official permit portal (services.seattle.gov — the Seattle Department of Construction & Inspections' public permit system). Search by date range, permit/record number, permit type, status, and street address, and export clean, structured permit data — no login, no cookies, no residential proxy required.
What this actor does
- Searches Seattle's live permit database — the same "Find Trade, Construction & Land Use Permit Records" tool the City publishes for the public, automated for bulk export.
- Filters on every axis the portal supports: creation-date range, exact/partial record number, permit type (54 official categories), record status, and street address (number range, direction prefix, name, type, direction suffix).
- Optional deep enrichment — turn on "Fetch permit detail pages" to also pull contractor name/address and parcel number straight from each permit's detail page.
- Always returns clean records — every field is real data scraped directly from the portal; empty/unavailable fields are simply omitted, never faked.
Output per permit record
| Field | Description |
|---|---|
recordNumber | The permit/record number, e.g. 7156800-EL |
permitType | Permit/record type label, e.g. Electrical Permit: Over the Counter |
status | Current record status, e.g. Issued, Completed, In Process |
createdDate | Date the record was created (ISO YYYY-MM-DD) |
expirationDate | Permit expiration date, if applicable (ISO YYYY-MM-DD) |
address | Street address of the permitted work, when on file |
description | Project description / scope of work |
detailUrl | Direct link to the permit's detail page on the portal |
recordId | Portal-internal composite ID (stable unique key) |
sourceUrl | Canonical URL for this record |
workLocationAddress | (fetchDetails only) Work location address from the detail page |
contractorName | (fetchDetails only) Contractor name on file |
contractorAddress | (fetchDetails only) Contractor's registered address |
contractorLicense | (fetchDetails only) Contractor's license number, when disclosed |
ownerName | (fetchDetails only) Property/business owner name on file, when disclosed |
ownerAddress | (fetchDetails only) Property/business owner's address, when disclosed |
parcelNumber | (fetchDetails only) Development site parcel number |
permitIssuedDate | (fetchDetails only) Date the permit was issued (ISO YYYY-MM-DD) |
applicationCompletedDate | (fetchDetails only) Date the application was completed (ISO YYYY-MM-DD) |
inspectionsCompletedDate | (fetchDetails only) Date all required inspections were completed (ISO YYYY-MM-DD) |
certificateOfOccupancyIssuedDate | (fetchDetails only) Date the certificate of occupancy was issued (ISO YYYY-MM-DD) |
projectValue | (fetchDetails only) Declared project value in USD, when on file |
totalIssuedValue | (fetchDetails only) Total issued construction valuation in USD |
totalIntakeValue | (fetchDetails only) Total intake (as-submitted) construction valuation in USD |
reviewLevel | (fetchDetails only) Plan review level, e.g. Field, Full + |
occupancyGroup | (fetchDetails only) Building occupancy classification, e.g. B Restaurant < 50 Occupants |
typeOfConstruction | (fetchDetails only) Building code construction type, e.g. Type IIB |
actionType | (fetchDetails only) Permit action type, e.g. Add/Alt, New |
recordType | Always "permit" |
scrapedAt | UTC timestamp of when the record was scraped |
Note: the applicationCompletedDate / projectValue / occupancyGroup-style fields above come from a generic per-permit-type "Application Information" section on the detail page, so which of them are present depends on the permit type — e.g. a Construction Permit exposes valuation and occupancy fields, while an Electrical Permit typically only exposes reviewLevel and permitIssuedDate. Fields the portal doesn't have data for are simply omitted, never returned as null.
Fields that aren't available for a given permit (e.g. a permit still In Process has no expirationDate) are simply left out of that record — you will never see null, "", or placeholder values.
Input
| Field | Type | Default | Description |
|---|---|---|---|
createDateFrom | string | 2015-01-01 | Only include permits created on/after this date (YYYY-MM-DD) |
createDateTo | string | today | Only include permits created on/before this date (YYYY-MM-DD) |
recordNumber | string | – | Exact/partial permit number to look up |
permitType | select | any | One of the 54 official Seattle permit/record types |
recordStatuses | array (select) | any | Keep only these statuses (e.g. Issued, Completed) |
addressNumberLow / addressNumberHigh | integer | – | Street number range |
streetDirectionPrefix | select | any | N / S / E / W / NE / NW / SE / SW |
streetName | string | – | Street name only, e.g. FREMONT |
streetSuffixType | select | any | AVE, ST, BLVD, … (20 official types) |
streetDirectionSuffix | select | any | Directional suffix after the street type |
fetchDetails | boolean | false | Also open each permit's detail page for contractor/parcel data (slower) |
maxItems | integer | 50 | Max permit records to return (1–1000) |
Example: recent electrical permits in a neighborhood
{"createDateFrom": "2026-01-01","streetName": "FREMONT","streetSuffixType": "AVE","recordStatuses": ["Issued"],"maxItems": 50}
Example: look up one specific permit
{"recordNumber": "7156800-EL","fetchDetails": true}
Example: all construction permits address-ranged and status-filtered
{"permitType": "DPDPermits/Building/Construction/NA","addressNumberLow": 100,"addressNumberHigh": 9999,"streetSuffixType": "AVE","recordStatuses": ["Issued", "In Process"],"maxItems": 200}
Use cases
- Market research — track construction and remodel activity by neighborhood or street.
- Lead generation — find newly issued permits and their contractors for sales outreach.
- Compliance & due diligence — verify a property's permit history before a transaction.
- Journalism & civic analysis — monitor development trends across Seattle.
- Contractor competitive intelligence — see which contractors are active on which permit types.
FAQ
Does this require a login or API key? No. The Seattle permit portal is a public government resource; this actor uses no cookies, no API keys, and no residential proxies.
How far back does the data go?
The portal's online records generally start around 2005; this actor's date filters default to 2015-01-01 onward for the most useful window. Use createDateFrom to reach further back — availability depends on what the portal has indexed.
Why do some permits have no address or description?
Certain record types (e.g. Upload Documents, Contractor Disclosure Form) are administrative sub-records that the portal itself doesn't attach an address or description to. This actor omits those fields rather than showing them blank.
What does "Fetch permit detail pages" add, and why is it off by default? It opens each result's individual detail page to extract contractor/owner name and address, license number, parcel number, construction valuation, key milestone dates (application completed, inspections completed, certificate of occupancy issued), and building classification fields (occupancy group, type of construction, action type) — whichever of these the portal has on file for that permit type. It roughly doubles run time because each record requires an extra page load, so it's opt-in.
Can I filter by permit status without knowing the exact spelling?
Yes — recordStatuses is a dropdown of every status value used across the portal (e.g. Issued, Completed, In Process, Withdrawn), so you never have to guess exact text.
Why don't Temporary Certificate (26TMP-*) records show up when I filter by status?
A handful of record types — Temporary Certificates and some administrative sub-records — render a genuinely blank Status cell on the portal itself. When recordStatuses is set, this actor excludes those status-less rows rather than guessing, so every record in a filtered result reliably has the status you asked for. Leave recordStatuses empty to include them alongside everything else.