Seattle Building Permits Scraper avatar

Seattle Building Permits Scraper

Pricing

from $3.00 / 1,000 results

Go to Apify Store
Seattle Building Permits Scraper

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

Crawler Bros

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

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

FieldDescription
recordNumberThe permit/record number, e.g. 7156800-EL
permitTypePermit/record type label, e.g. Electrical Permit: Over the Counter
statusCurrent record status, e.g. Issued, Completed, In Process
createdDateDate the record was created (ISO YYYY-MM-DD)
expirationDatePermit expiration date, if applicable (ISO YYYY-MM-DD)
addressStreet address of the permitted work, when on file
descriptionProject description / scope of work
detailUrlDirect link to the permit's detail page on the portal
recordIdPortal-internal composite ID (stable unique key)
sourceUrlCanonical 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
recordTypeAlways "permit"
scrapedAtUTC 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

FieldTypeDefaultDescription
createDateFromstring2015-01-01Only include permits created on/after this date (YYYY-MM-DD)
createDateTostringtodayOnly include permits created on/before this date (YYYY-MM-DD)
recordNumberstringExact/partial permit number to look up
permitTypeselectanyOne of the 54 official Seattle permit/record types
recordStatusesarray (select)anyKeep only these statuses (e.g. Issued, Completed)
addressNumberLow / addressNumberHighintegerStreet number range
streetDirectionPrefixselectanyN / S / E / W / NE / NW / SE / SW
streetNamestringStreet name only, e.g. FREMONT
streetSuffixTypeselectanyAVE, ST, BLVD, … (20 official types)
streetDirectionSuffixselectanyDirectional suffix after the street type
fetchDetailsbooleanfalseAlso open each permit's detail page for contractor/parcel data (slower)
maxItemsinteger50Max 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.