Washington L&I Contractor & License Scraper
Pricing
from $1.50 / 1,000 results
Washington L&I Contractor & License Scraper
Scrape Washington State L&I contractor licenses with insurance, bond and principal data from data.wa.gov Socrata API. Joins 4 datasets: General + Insurance + Bond + Principal by license number. Filter by status, specialty, city and date. No auth, no proxy, no browser.
Pricing
from $1.50 / 1,000 results
Rating
0.0
(0)
Developer
Haketa
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Washington L&I Contractor & License Scraper — General, Specialty, Bond, Insurance & Principal Data Extractor
The most complete Washington State Department of Labor & Industries (L&I) contractor data extraction tool on Apify. Pull every registered Construction, Electrical, and General Contractor in Washington — joined live with liability insurance, surety bond, and principal-owner records from
data.wa.gov— structured, filtered, and ready for compliance, bidding, lead-gen, underwriting, and risk-analytics workflows.
What This Actor Does
The Washington L&I Contractor & License Scraper is a production-ready Apify Actor that extracts the complete public contractor licensing record set from the Washington State Department of Labor & Industries (L&I) — the state regulator that registers every Construction Contractor (CC), Electrical Contractor (EC), and General Contractor (GC) doing business in Washington.
Instead of scraping the slow HTML lookup tool at secure.lni.wa.gov/verify, this actor talks directly to L&I's Socrata SODA Open Data API on data.wa.gov and joins four official datasets by contractor license number in a single run:
- General license dataset (
m8qx-ubtq) — business name, license type, status, address, UBI, specialty codes, effective/expiration/suspend dates, primary principal - Insurance dataset (
ciwg-agsx) — carrier, policy number, coverage amount, effective/expiration/cancel dates, agency name - Surety bond dataset (
bzff-4fmt) — bond firm, bond amount, impairment status, effective/expiration/cancel dates - Principal/officer dataset (
4xk5-x9j6) — current owners and officers of record
Every output row is a fully joined contractor profile: who they are, what they're licensed to do, where they operate, who insures and bonds them, who runs the company, and whether the registration is currently in good standing. No headless browser. No CAPTCHA. No login. No proxy.
Why scrape L&I yourself when this exists?
Washington L&I's verification portal (secure.lni.wa.gov/verify) is the consumer-facing lookup most teams discover first — and quickly hit a wall:
- The verify page enforces single-record JavaScript-rendered lookups, not bulk export
- Insurance, bond, and principal data live on separate sub-pages with their own DOM structures
- Specialty codes (
01,02,BW,EL,RO...) are rendered with descriptions in tooltips, not stable attributes - Pagination of search results breaks on >500 hits — the page silently truncates
- Suspend/expiration dates are formatted inconsistently across categories
- L&I rotates anti-scrape headers and occasionally rate-limits IPs hammering the verify form
- Bond impairment status — critical for risk scoring — only appears on a tertiary detail tab
- The Socrata API exists, but four datasets joined manually is hours of SoQL plumbing
- No incremental update endpoint — you must re-pull and diff to detect changes
- Raw Socrata field names (
contractorlicensetypecodedesc,bondimpaireddate) are painful to query directly
This actor solves all of that. It hits the Socrata API, batches IN() lookups across the three enrichment datasets, joins by contractorlicensenumber, normalises field names, formats dates as ISO YYYY-MM-DD, and pushes one flat JSON record per contractor.
Quick Start
One-Click Run
- Click "Try for free" on the Apify Store page
- Default input scrapes the most recent 100 ACTIVE Washington contractors with full insurance + bond + principal enrichment
- Hit Start — first results stream in within seconds
- Download the dataset as JSON, CSV, Excel, XML, or HTML directly from the Apify UI
API Run (Python)
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("haketa/washington-li-contractor-license-scraper").call(run_input={"statuses": ["ACTIVE"],"licenseTypes": ["GC", "CC"],"specialties": ["01"],"cities": ["SEATTLE", "BELLEVUE", "TACOMA"],"maxRecords": 2000,"pageSize": 1000,})for record in client.dataset(run["defaultDatasetId"]).iterate_items():print(record["licenseNumber"], record["businessName"], record["status"],record["city"], record["insuranceCompany"], record["bondFirm"])
API Run (Node.js / TypeScript)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('haketa/washington-li-contractor-license-scraper').call({statuses: ['ACTIVE'],licenseTypes: ['EC'],cities: ['SPOKANE', 'VANCOUVER'],effectiveAfter: '2023-01-01',maxRecords: 5000,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(`Got ${items.length} active electrical contractors in Spokane & Vancouver, WA`);
API Run (cURL)
curl -X POST "https://api.apify.com/v2/acts/haketa~washington-li-contractor-license-scraper/runs?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"statuses": ["ACTIVE", "SUSPENDED"],"licenseTypes": ["CC"],"cities": ["SEATTLE"],"enrichBond": true,"enrichInsurance": true,"maxRecords": 500}'
How It Works
The actor uses Washington's Socrata SODA Open Data API (data.wa.gov/resource/<id>.json) — the same backend that powers the official Open Data portal — and joins four datasets by contractorlicensenumber in process.
Source endpoints
| Step | Dataset | Socrata ID | Purpose |
|---|---|---|---|
| 1 | General | m8qx-ubtq | Core license record — business, address, specialty, status |
| 2 | Insurance | ciwg-agsx | Liability insurance — carrier, policy number, coverage |
| 3 | Bond | bzff-4fmt | Surety bond — firm, amount, impairment status |
| 4 | Principal | 4xk5-x9j6 | Owners / officers of record |
All four endpoints live under https://data.wa.gov/resource/ and respond with newline-delimited JSON via $select, $where, $limit, $offset, and $order SoQL parameters.
Engineering details
- Direct HTTPS with
got-scraping— no Puppeteer, no Playwright, no headless browser overhead - SoQL WHERE pushdown — status, specialty, license type, city, and date filters execute server-side so the wire only carries matching rows
- Count-then-paginate — actor calls
count(*)first to size the run and respectsmaxRecordscleanly - Chunked enrichment joins — license numbers batch into groups of 100 for
IN(...)SoQL clauses (URL-length safe) - Latest-wins de-duplication — if a contractor has multiple insurance/bond records, the most recent by effective date wins
- Active-principal filter — only principals with no
enddateare aggregated into theprincipalsfield - ISO date normalisation — every date trimmed to
YYYY-MM-DD - Polite pacing — configurable
requestDelay(default 200ms) keeps you well within Socrata's anonymous quotas - Deterministic, idempotent output —
ORDER BY licenseeffectivedate DESC; eachlicenseNumberemitted at most once per run
Input Parameters
{"statuses": ["ACTIVE"],"specialties": ["01"],"licenseTypes": ["GC", "CC"],"cities": ["SEATTLE", "BELLEVUE"],"effectiveAfter": "2023-01-01","effectiveBefore": "","enrichInsurance": true,"enrichBond": true,"enrichPrincipal": true,"maxRecords": 2000,"pageSize": 1000,"requestDelay": 200}
Parameter reference
| Parameter | Type | Default | Description |
|---|---|---|---|
statuses | array<string> | ["ACTIVE"] | License status filter. Values: ACTIVE, EXPIRED, SUSPENDED, RE-LICENSED, CANCELLED. Empty array = all statuses. Case-insensitive. |
specialties | array<string> | [] | Specialty code filter on specialtycode1. Common values: 01 General, 02 Electrical, 03 Plumbing, 04 HVAC, BW Bridge/Water, CB Painting, DP Demolition, EL Elevator, RO Roofing. Empty = all specialties. |
licenseTypes | array<string> | [] | License type code: CC (Construction Contractor), EC (Electrical Contractor), GC (General Contractor). Empty = all. |
cities | array<string> | [] | City filter, case-insensitive. Examples: ["SEATTLE", "TACOMA", "SPOKANE"]. Empty = no city filter. |
effectiveAfter | string | "" | Only include licenses with licenseeffectivedate >= YYYY-MM-DD. Empty = no lower bound. |
effectiveBefore | string | "" | Only include licenses with licenseeffectivedate <= YYYY-MM-DD. Empty = no upper bound. |
enrichInsurance | boolean | true | Join Insurance dataset. Set false to skip for faster runs. |
enrichBond | boolean | true | Join Bond dataset (firm, amount, impaired status). |
enrichPrincipal | boolean | true | Join Principal dataset (owners/officers). |
maxRecords | integer | 100 | Hard cap on total General-dataset records. 0 = unlimited. |
pageSize | integer | 100 | Records per Socrata page. Min 100, max 50000. Sweet spot 1000–5000. |
requestDelay | integer | 200 | Milliseconds between API calls. 0 = no delay (only safe with a Socrata app token). |
Output Schema
Every record is a flat JSON object with the same shape regardless of enrichment toggles — fields you didn't request are simply null. This keeps downstream ingestion (BigQuery, Postgres, Snowflake, Salesforce upserts) free of per-row branching.
Core license fields (always present)
| Field | Type | Description |
|---|---|---|
businessName | string | Legal business name as registered with L&I |
licenseNumber | string | L&I contractor license number — primary join key across all four datasets |
licenseTypeCode | string | CC, EC, or GC |
licenseTypeDesc | string | Human-readable license type, e.g. Construction Contractor |
status | string | Normalised status string — ACTIVE, EXPIRED, SUSPENDED, RE-LICENSED, CANCELLED |
statusCode | string | L&I numeric status code |
address | string | Primary mailing/business address (line 1) |
city | string | City as registered |
state | string | Two-letter US state |
zip | string | ZIP / ZIP+4 |
phone | string | Registered contractor phone |
ubi | string | Washington Unified Business Identifier (9-digit cross-agency ID) |
businessType | string | Entity type description (e.g. Corporation, LLC, Sole Proprietor) |
specialty1 | string | Primary specialty code |
specialty1Desc | string | Primary specialty description |
specialty2 | string | Secondary specialty code (if any) |
specialty2Desc | string | Secondary specialty description (if any) |
primaryPrincipal | string | Primary principal name from General dataset |
licenseEffectiveDate | string | License effective date (YYYY-MM-DD) |
licenseExpirationDate | string | License expiration date (YYYY-MM-DD) |
suspendDate | string | Date license was suspended, if applicable |
scrapedAt | string | ISO-8601 timestamp of extraction |
Insurance fields (when enrichInsurance: true)
| Field | Type | Description |
|---|---|---|
insuranceCompany | string | Carrier name (e.g. ZURICH AMERICAN INSURANCE COMPANY) |
insurancePolicyNo | string | Policy number on file with L&I |
insuranceAmount | string | Coverage amount (in USD, as reported) |
insuranceExpiration | string | Policy expiration date (YYYY-MM-DD) |
insuranceAgency | string | Producing agency name |
Bond fields (when enrichBond: true)
| Field | Type | Description |
|---|---|---|
bondFirm | string | Surety firm issuing the bond |
bondAmount | string | Bond face amount (typically $6,000 / $12,000 / higher for specialty) |
bondExpiration | string | Bond expiration date (YYYY-MM-DD) |
bondImpaired | string | Yes / No — whether the bond is currently impaired by claim |
Principal fields (when enrichPrincipal: true)
| Field | Type | Description |
|---|---|---|
principals | string | Semicolon-delimited list of currently-active owners/officers |
Example: Active GC in Seattle with full enrichment
{"businessName": "EVERGREEN HORIZON BUILDERS LLC","licenseNumber": "EVERGHB999AA","licenseTypeCode": "GC","licenseTypeDesc": "General Contractor","status": "ACTIVE","statusCode": "01","address": "1500 1ST AVE S","city": "SEATTLE","state": "WA","zip": "98134","phone": "2065550199","ubi": "604999999","businessType": "Limited Liability Company","specialty1": "01","specialty1Desc": "General","specialty2": null,"primaryPrincipal": "DOE, JANE A","licenseEffectiveDate": "2022-04-12","licenseExpirationDate": "2026-04-12","suspendDate": null,"insuranceCompany": "ZURICH AMERICAN INSURANCE COMPANY","insurancePolicyNo": "GLP-0099887","insuranceAmount": "1000000","insuranceExpiration": "2026-09-30","insuranceAgency": "NORTHWEST RISK PARTNERS","bondFirm": "MERCHANTS BONDING COMPANY","bondAmount": "12000","bondExpiration": "2026-04-12","bondImpaired": "No","principals": "DOE, JANE A; DOE, JOHN B","scrapedAt": "2026-05-16T09:00:00.000Z"}
Example: Suspended Construction Contractor with impaired bond
{"businessName": "SAMPLE TACOMA REMODELERS INC","licenseNumber": "SAMPTRI222BB","licenseTypeCode": "CC","status": "SUSPENDED","city": "TACOMA","state": "WA","zip": "98444","phone": "2535550155","ubi": "603111222","businessType": "Corporation","specialty1": "01","specialty1Desc": "General","specialty2": "RO","specialty2Desc": "Roofing","primaryPrincipal": "SAMPLE, ROBERT","licenseEffectiveDate": "2019-06-01","licenseExpirationDate": "2025-06-01","suspendDate": "2024-11-20","insuranceCompany": null,"bondFirm": "OLD REPUBLIC SURETY COMPANY","bondAmount": "12000","bondExpiration": "2025-06-01","bondImpaired": "Yes","principals": "SAMPLE, ROBERT","scrapedAt": "2026-05-16T09:00:00.000Z"}
Reference Tables
License status values
| Status | Meaning |
|---|---|
ACTIVE | License current, in good standing — may legally bid and contract |
EXPIRED | Past expiration date — may not contract until renewed |
SUSPENDED | Suspended by L&I (often for impaired bond, unpaid taxes, or violation) |
RE-LICENSED | Previously cancelled / expired and subsequently re-issued |
CANCELLED | Voluntarily cancelled or terminated |
Use
statuses: ["ACTIVE"]for bid-ready lists; includeSUSPENDEDandEXPIREDwhen monitoring compliance risk.
License type codes
| Code | Description | Typical Use |
|---|---|---|
GC | General Contractor | Full-scope general construction — most commercial GCs |
CC | Construction Contractor | Registered construction contractor (broadest category) |
EC | Electrical Contractor | Holds an EC license under Chapter 19.28 RCW (separate from CC/GC) |
Specialty codes (most common)
| Code | Specialty |
|---|---|
01 | General |
02 | Electrical |
03 | Plumbing |
04 | HVAC / Heating, Ventilation, and Air Conditioning |
BW | Bridge / Water |
CB | Painting |
DP | Demolition |
EL | Elevator |
RO | Roofing |
SI | Sign Erection |
LA | Landscaping |
MA | Masonry |
Specialty codes are filtered against
specialtycode1(primary specialty). A contractor'sspecialty2field is still returned so you can post-filter on secondary specialties downstream.
Use Cases
Construction Lead Generation & Sales Prospecting
Building-material suppliers, equipment dealers, construction SaaS vendors (Procore, Buildertrend, CompanyCam), and trade associations use this dataset to:
- Build hyper-targeted prospect lists of every ACTIVE General Contractor in Seattle, Tacoma, or any WA metro
- Segment by specialty — pull only roofers (
RO), electricians (02/EC), or HVAC (04) for trade-specific campaigns - Filter on
licenseEffectiveDateto surface brand-new entrants who haven't been pitched yet - Enrich existing CRM accounts with current UBI, principal owner names, and contact phone numbers
- Route territory by ZIP — King County, Pierce County, Snohomish County reps each get clean splits
Subcontractor Vetting & GC Bid Compliance
General contractors, owner's reps, and construction managers vetting subcontractors before issuing an RFQ or executing a subcontract use this dataset to:
- Verify license status is
ACTIVEon the day of bid award — required by RCW 18.27 - Confirm bond is in place and not impaired (
bondImpaired = "No") - Validate insurance is current by checking
insuranceExpirationagainst the project schedule - Match
specialty1/specialty2against the scope of work being subcontracted - Cross-reference principals to detect related entities (e.g. a previously-suspended entity reincorporated under a new name)
Insurance Underwriting & Surety Risk Modeling
Commercial GL carriers and surety bond underwriters writing WA contractor business use the dataset to:
- Pre-fill quote applications with verified UBI, business type, principal names, and prior carrier
- Detect bond churn — frequent
bondFirmchanges can signal underlying claim activity - Flag impaired bonds (
bondImpaired = "Yes") for portfolio review and renewal decisions - Track new license issuances as fresh underwriting opportunities
- Build loss-frequency models by correlating
SUSPENDEDpopulations to specialty and metro
Compliance, Procurement & Public Works Verification
Public agencies, municipal procurement offices, school districts (OSPI), and Sound Transit / WSDOT prime contractors use this dataset to:
- Verify prime and sub registration before issuing contracts under RCW 39.06
- Maintain audit-ready snapshots with timestamped
scrapedAtfields proving when verification ran - Catch suspension events within 24 hours by running daily diffs
- Replace manual L&I verify-page lookups that cost hours of clerical time per bid cycle
- Document due diligence for state auditor, federal grant, and DBE/MWBE compliance
Legal, Litigation & Investigative Use
Construction-defect attorneys, plaintiff's firms, journalists, and consumer-protection investigators use the dataset to:
- Confirm a contractor was licensed on the date of contracting — RCW 18.27.080 bars unlicensed-contractor lawsuits
- Pull current insurance carrier + policy number for tender of defense
- Identify the surety on file when filing a claim against the bond
- Surface contractors with histories of suspension (
status = "SUSPENDED"joined withsuspendDate) - Map principal-owner overlap across multiple license records to expose serial-bad-actor schemes
Real Estate Development & Project Origination
Developers, GCs, and real-estate investors profile contractor density and capacity by submarket:
- Identify experienced specialty subs in Bellevue, Kirkland, or Redmond before mobilizing on a new project
- Spot capacity constraints by counting active GCs per ZIP relative to permit volume
- Track new entrants as potential bid candidates on small-/medium-tier work
- Quantify bond-class coverage (small-residential bonds vs commercial-grade) by region
Recruiting, Workforce & Academic Research
Construction recruiters, trade-staffing firms, apprenticeship coordinators, and labor economists use the dataset to:
- Build employer lists by specialty and metro for outbound sourcing
- Estimate market hiring capacity by ACTIVE-contractor count by specialty
- Target signage (
SI), elevator (EL), and specialty trades that suffer chronic labor shortages - Study small-business formation by tracking new license issuances over time
- Quantify regulatory enforcement — suspension rates by region, specialty, and license type
Sample Queries & Recipes
Recipe 1: Every active GC in Seattle, with bond + insurance
{"statuses": ["ACTIVE"],"licenseTypes": ["GC"],"cities": ["SEATTLE"],"enrichInsurance": true,"enrichBond": true,"enrichPrincipal": true,"maxRecords": 0}
Recipe 2: All roofers (RO) across Western Washington
{"statuses": ["ACTIVE"],"specialties": ["RO"],"cities": ["SEATTLE", "BELLEVUE", "TACOMA", "EVERETT", "RENTON", "KENT"],"enrichBond": true,"maxRecords": 2000}
Recipe 3: Suspended contractors (compliance dashboard)
{"statuses": ["SUSPENDED"],"enrichBond": true,"enrichPrincipal": true,"maxRecords": 0}
Then post-filter: risky = [r for r in records if r["bondImpaired"] == "Yes"]
Recipe 4: Newly-licensed electrical contractors in 2025
{"statuses": ["ACTIVE"],"licenseTypes": ["EC"],"effectiveAfter": "2025-01-01","enrichInsurance": true,"enrichBond": true}
Recipe 5: Spokane HVAC + plumbing prospect list
{"statuses": ["ACTIVE"],"specialties": ["03", "04"],"cities": ["SPOKANE", "SPOKANE VALLEY"],"enrichPrincipal": true,"maxRecords": 1000}
Recipe 6: Statewide CC + GC firms, no enrichment (fastest bulk pull / sanity test)
{"statuses": ["ACTIVE"],"licenseTypes": ["CC", "GC"],"enrichInsurance": false,"enrichBond": false,"enrichPrincipal": false,"pageSize": 5000,"maxRecords": 0}
For a 50-record sanity test, drop
licenseTypesand setmaxRecords: 50with all enrichments off.
Integration Examples
Google Sheets (via Apify Integration)
- Set up an Apify schedule running this actor nightly at 03:00 PST
- Add the "Export to Google Sheets" integration to the schedule
- Each morning your Sheet has a fresh snapshot of every ACTIVE WA contractor you care about
Make.com / Zapier / n8n
Use the Apify connector on any major automation platform to trigger downstream workflows on new ACTIVE licenses (diff today vs yesterday), status transitions (ACTIVE -> SUSPENDED -> Slack ping), bond expirations within 30 days (renewal task in HubSpot), and insurance lapses (alert risk coordinator).
Power BI / Tableau / Looker
Connect Apify's REST dataset endpoint as a data source. Build dashboards covering active contractor count by metro and specialty, suspension rate by license type, bond-impairment heatmap by ZIP, insurance-carrier market share, and new-license issuance velocity by quarter.
Postgres / Snowflake / BigQuery
Use the Apify webhook integration to POST run results directly to your warehouse ingest endpoint after each scheduled run. Key on licenseNumber as primary, ubi as secondary join to other WA state datasets.
Salesforce / HubSpot CRM Enrichment
Trigger an Apify run nightly, then upsert against Account records keyed on licenseNumber or ubi. Status change events automatically create Tasks. Use the principal-owner field to populate Contact records for direct-decision-maker outreach.
Slack / Microsoft Teams Webhooks
Wire the Apify webhook integration to your channel URL. Useful templates: "X new ACTIVE GCs licensed in King County this week", "Contractor suspended today", "Bond impaired: <businessName>".
Major Washington Markets at a Glance
| Metro Area | Population | Construction Significance |
|---|---|---|
| Seattle | 750K (4.0M MSA) | Largest concentration of commercial GCs; Amazon/Microsoft tech-corridor build-outs |
| Tacoma | 220K | Port-of-Tacoma logistics build, JBLM-adjacent residential, infrastructure |
| Spokane | 230K | Inland Northwest hub; medical, education, multifamily |
| Bellevue | 150K | Eastside tech-driven high-rise residential and Class-A office |
| Vancouver | 200K | Portland-metro overflow; cross-river residential and warehouse |
| Kent | 135K | Industrial / warehouse / logistics build (Kent Valley) |
| Everett | 110K | Boeing aerospace supply chain, Light Rail extension |
| Renton | 105K | Boeing 737 plant, Southport mixed-use, residential |
| Bellingham / Yakima / Tri-Cities / Olympia | 50–95K each | Secondary markets — agriculture, Hanford, capitol public works, cross-border |
Cost & Performance
| Metric | Value |
|---|---|
| Engine | Socrata SODA API over HTTPS — no browser |
| Runtime (100 records, full enrichment) | 5–15 seconds |
| Runtime (5,000 records, full enrichment) | 60–180 seconds |
| Runtime (unfiltered statewide bulk) | varies — depends on enrichment toggles and pageSize |
| Cost per typical run | Pay-per-event — typically a small fraction of a Compute Unit |
| Pricing model | Pay-per-event (transparent per-record pricing) |
| Data freshness | Live at run time — Socrata mirrors L&I updates on regular cadence |
| Auth required | None (Socrata public API; app token optional for higher quotas) |
| Proxy required | None |
| Concurrency | Safe to run multiple parallel filtered configurations |
| Memory footprint | 512 MB sufficient for typical runs; 4096 MB max recommended for full-state with enrichment |
Compliance, Privacy & Legal Notes
- Public data only — every field originates from datasets L&I publishes at data.wa.gov under Washington's Public Records Act (RCW 42.56)
- No SSNs, DOBs, or financial account numbers are present in the source data
- Principal names are public on every WA contractor registration; insurance and bond amounts are required public disclosures under RCW 18.27
- Address data is the registered business address — not personal residence (except sole proprietors who use a home address voluntarily)
- CAN-SPAM, TCPA, GDPR/CCPA compliance for downstream marketing use is the data consumer's responsibility
- No web-scraping of
secure.lni.wa.gov— this actor uses the official Socrata API atdata.wa.gov, published explicitly for programmatic consumption. Respect Socrata's API terms and L&I's data policies.
Important: This dataset must not be used for unlawful purposes including identity theft, contractor harassment, or impersonation. It is intended for legitimate compliance, sales, underwriting, journalism, and research workflows.
Frequently Asked Questions
How fresh is the data?
Live at run time. The Socrata API mirrors Washington L&I's contractor registration system on a regular cadence (typically near-daily for status changes, weekly for full refreshes).
How many records will I get?
Washington has tens of thousands of registered contractors across CC, EC, and GC categories. The exact count depends on your filter combination. Set maxRecords: 0 for no cap, or sample with maxRecords: 50 first to size your run.
Does this scraper require login or API keys?
No. The Socrata SODA API on data.wa.gov is public and requires no authentication. You only need an Apify account. If you have a Socrata app token and want higher per-IP quotas, you can fork the actor and add it as a header.
Does this work for other states?
This actor is Washington-specific. We maintain separate Apify actors for other state licensing boards — see Related Actors below.
Can I use this for license verification at scale?
Yes. Many GCs and underwriting desks run this actor daily, diff against yesterday's run, and trigger Slack/email alerts on status transitions or bondImpaired flips. Apify schedules make this fully automated.
Are contractor emails included?
No. L&I does not publish contractor email addresses in the public Socrata datasets. Phone numbers and mailing addresses are included.
Can I filter by bond amount or insurance coverage?
The actor returns those fields — apply numeric filters in your downstream pipeline (SQL WHERE bond_amount >= 50000, Python comprehension, Sheets filter). Socrata SoQL filtering on those fields is not exposed as an actor input today.
What's the difference between CC, EC, and GC?
CC (Construction Contractor) is the broadest registration under RCW 18.27. GC (General Contractor) is the subtype for general-construction prime contractors. EC (Electrical Contractor) is a separate license under Chapter 19.28 RCW administered by L&I's Electrical Section. A single firm may hold both — they appear as separate records keyed by separate license numbers.
What does bondImpaired = "Yes" mean?
A bond is "impaired" when claims have been filed against it and partially or fully drawn down its face value. L&I treats impaired bonds as a compliance trigger — a contractor with an impaired bond cannot legally bid new work until the bond is restored.
Why might insuranceCompany be null even though the contractor is ACTIVE?
Either the Insurance dataset enrichment was disabled (enrichInsurance: false), the contractor's insurance record hasn't been refreshed on data.wa.gov yet, or the contractor is in a category that doesn't require L&I to track insurance. For mission-critical verification, also check L&I's secure.lni.wa.gov/verify page for the same UBI.
Does the actor deduplicate?
Yes. Each licenseNumber is emitted at most once per run. For enrichment, the latest-effective-date insurance and bond record is selected per contractor; older history is not preserved in the output (use historical Apify dataset archives for diffing).
What's the UBI field for?
The Washington Unified Business Identifier is a state-wide cross-agency ID. It joins L&I contractor data to Department of Revenue tax records, Secretary of State business filings, and Department of Employment Security wage records.
Can I get historical snapshots of past license states?
Not directly — this actor returns current state. To build a history, schedule the actor daily and archive each Apify dataset run.
Does the actor work on the Apify Free Plan?
Yes — full functionality. A typical filtered run with full enrichment fits comfortably inside free-tier Compute Units.
Can I run this on a schedule, and which export formats are supported?
Yes — use Apify's built-in Scheduler for any cron expression. Exports: JSON, CSV, Excel (XLSX), HTML, XML, RSS, and JSON Lines — directly from the dataset view or API.
Does the dataset include cancelled/expired contractors?
Yes — set statuses: ["ACTIVE", "EXPIRED", "SUSPENDED", "RE-LICENSED", "CANCELLED"] (or an empty array) to include them. Useful for historical analysis, churn studies, and reconciliation passes.
Related Apify Actors by Haketa
If you need licensing data from other US states or related regulatory bodies, check these complementary actors:
- Arizona ROC Contractor License Scraper — every AZ Registrar of Contractors record
- NC Licensing Board for General Contractors Scraper — North Carolina GCs
- Colorado Professional License Scraper — CO DORA licensed professionals
- Virginia DPOR Professional License Scraper — VA regulated occupations
- Minnesota DLI Professional License Scraper — MN Department of Labor & Industry
- California DCA Professional License Scraper — California DCA license boards
- Ohio eLicense Scraper — Ohio professional license registry
- Illinois IDFPR License Scraper — Illinois licensed professionals
- Texas Pharmacy License Scraper — TSBP pharmacist + pharmacy records
- SAM.gov Federal Contractor Entity Scraper — federal procurement registrations
- BBB Business Scraper — Better Business Bureau profiles, ratings, and complaints
Comparison vs. Alternatives
| Approach | Setup time | Joined datasets | Data freshness | Cost (5K records) | Bond + insurance | Audit log |
|---|---|---|---|---|---|---|
| This actor | < 1 minute | 4 joined | Live | pay-per-event (typically <$0.05) | Built-in | Automatic |
secure.lni.wa.gov/verify manual | 30s per lookup | 1 per page | Live | Free + labor | Manual tabs | None |
| Custom Socrata script | 4–8 hours dev | DIY join | Live | Free + infra | DIY | DIY |
| Paid contractor-data API | Hours setup | Varies | Real-time | $300–1500+/mo | Sometimes | |
| L&I public-records request | Days | All | Stale | Variable | Yes |
Why Pay-Per-Event Pricing?
Most data scrapers either bill a flat monthly subscription (you pay even if you don't run) or per-Compute-Unit (hard to predict). This actor uses pay-per-event pricing, which means:
- You only pay when the actor runs
- Charges scale with how much data you actually consume
- Transparent, line-item billing inside Apify
- No monthly minimums
- Free to evaluate — sample with
maxRecords: 50for pennies
Changelog
| Version | Date | Notes |
|---|---|---|
| 1.0.0 | 2026-05 | Initial public release — Socrata SODA API, 4-dataset join (General + Insurance + Bond + Principal), specialty + city + status + date filters, pay-per-event pricing |
Keywords
Washington L&I scraper · Washington contractor license lookup · WA L&I contractor data · Seattle contractor verification · L&I bond status · WA contractor infraction data · Washington general specialty contractor lookup · data.wa.gov Socrata contractor API · WA Department of Labor and Industries scraper · WA construction contractor data extraction · Washington general contractor database · Washington electrical contractor registry · Washington roofing contractor list · WA HVAC contractor data · WA plumbing contractor lookup · UBI lookup Washington · Washington surety bond lookup · WA contractor insurance verification · Washington contractor compliance API · Seattle GC lead generation · Tacoma contractor list · Spokane contractor lookup · Bellevue subcontractor verification · Vancouver WA contractor data · Everett construction contractor data · Kent WA roofing contractor data · Renton WA HVAC contractor leads · Washington contractor CRM enrichment · WA construction industry data · L&I license verification automation · WA contractor B2B leads · Washington construction prospecting · WA contractor underwriting data · contractor bond impaired lookup · Washington L&I open data scraper · Apify Washington contractor actor · WA construction defect attorney data · WA contractor due diligence · L&I principal owner lookup · Washington contractor recruiting data · WA subcontractor vetting · Washington construction permit cross reference
Support
- Bug reports: Use the Issues tab on the Apify Store page
- Feature requests: Same place — please describe your use case so we can prioritise
- Direct contact: Through the Apify developer profile
If this actor saves you time on Washington contractor data, a 5-star rating on the Apify Store helps other compliance, construction, and underwriting teams discover it. Thank you!