Washington Contractor Licenses (L&I) with Bond & Insurance avatar

Washington Contractor Licenses (L&I) with Bond & Insurance

Pricing

$3.00 / 1,000 contractor licence records

Go to Apify Store
Washington Contractor Licenses (L&I) with Bond & Insurance

Washington Contractor Licenses (L&I) with Bond & Insurance

Washington State contractor licences from the official L&I registry: business name, licence, address, phone, UBI, specialty and status. Find newly licensed contractors or current insurance-policy and dated surety-bond renewals. Optional principals, bond, insurance and signer joins.

Pricing

$3.00 / 1,000 contractor licence records

Rating

0.0

(0)

Developer

JS Tech Solutions

JS Tech Solutions

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

19 days ago

Last modified

Share

Washington Contractor Licenses: L&I Registry with Principals, Bond & Insurance

Pulls the Washington State contractor licence registry published by the Department of Labor & Industries (L&I) on data.wa.gov into clean JSON records: business name, licence number and type, mailing address, phone, UBI, business type, specialties, effective and expiration dates, status and suspend date, primary principal. Optionally joins the four L&I addenda on licence number, so every record can also carry its principals (owners), bond (surety firm, amount, expiration, cancellation, impairment), insurance (carrier, policy, amount, expiration, agency) and authorized signers.

This is the same registry behind L&I's "Verify a contractor" lookup, read from the state's open-data API rather than scraped from the website, so it does not break when the site changes and it returns thousands of licences per run instead of one lookup at a time. Filter by effective or expiration date, status, city, ZIP, state, licence type, specialty, business name, licence number or UBI.

Who uses this data

  • Building-material, equipment and tool suppliers opening accounts with newly licensed contractors the week they get licensed (the default run), by city, ZIP or specialty.
  • Surety and insurance agents working renewal leads: licences expiring next quarter, bonds with a cancellation on file, policies expiring, all with the contractor's phone and principal name.
  • Subcontractor marketplaces, GCs and construction lead-gen building or refreshing a vetted contractor list, filtered to Active, by trade (electrical, plumbing, roofing, HVAC, concrete) and territory.
  • Lenders, property managers and homeowners' platforms checking that a contractor is currently Active, bonded and insured before engagement.
  • Researchers and journalists tracking contractor formation, churn, suspensions and out-of-state entrants.

What you get

One dataset item per licence, most recently effective first. A real item from {"join": ["principals", "bond", "insurance"], "maxResults": 3}, run 2026-08-23, untouched except that bonds and insurancePolicies (the full arrays) are elided for length; each contains the same object shown under currentBond and currentInsurance:

{
"licenseNumber": "AARDVGC741N1",
"businessName": "AARDVARK GUTTER CLEANING",
"licenseType": "CC",
"licenseTypeDescription": "CONSTRUCTION CONTRACTOR",
"statusCode": "A",
"status": "ACTIVE",
"suspendDate": null,
"licenseEffectiveDate": "2026-08-21",
"licenseExpirationDate": "2028-08-21",
"daysUntilExpiration": 729,
"address1": "PO Box 8025",
"address2": null,
"city": "MOSCOW",
"state": "ID",
"zip": "83843",
"zip5": "83843",
"phone": "208-596-2905",
"businessType": "I",
"businessTypeDescription": "Individual",
"specialtyCode1": "01",
"specialtyDescription1": "GENERAL",
"specialtyCode2": null,
"specialtyDescription2": null,
"ubi": "603396918",
"primaryPrincipalName": "Wilder, David Olley",
"principals": [
{ "name": "Wilder, David Olley", "startDate": "2026-08-21", "endDate": null }
],
"currentBond": {
"firm": "Nationwide Mutual Ins Co",
"accountId": "7901345789",
"amount": 30000,
"receivedByLniDate": "2026-08-21",
"effectiveDate": "2026-08-21",
"expirationDate": null,
"untilCanceled": true,
"cancelDate": null,
"impaired": false,
"impairedDate": null
},
"currentInsurance": {
"company": "Scottsdale Ins Co",
"policyNumber": "CPS8458126",
"amount": 1000000,
"effectiveDate": "2026-07-01",
"expirationDate": "2027-07-01",
"cancelDate": null,
"agencyName": null,
"lastUpdatedDate": "2026-08-21"
},
"sourceDataset": "m8qx-ubtq",
"sourceDatasetTitle": "L&I Contractor License Data - General",
"source": "https://data.wa.gov/resource/m8qx-ubtq.json",
"datasetPage": "https://data.wa.gov/d/m8qx-ubtq",
"attribution": "Washington State Department of Labor & Industries",
"sourcePublishedAt": "2026-08-23T14:34:25.000Z",
"fetchedAt": "2026-08-23T16:37:41.038Z"
}

Join fields appear only when that join is requested, so an un-joined run has a flat, stable column set. With bond joined, bonds is every bond L&I has on file for the licence (history included) and currentBond is the one in force on the run date: no cancellation dated on or before that day, not past its expiration, most recently effective, or null if none. insurancePolicies and currentInsurance work the same way. principals carries owners with start and end dates; authorizedSigners carries the people named to sign permits or affidavits, with their role.

L&I publishes bond expiration as text: a date, or the literal "Until Canceled". That is delivered as an ISO expirationDate plus an untilCanceled flag. All other dates are ISO 8601 calendar dates. daysUntilExpiration is counted from the run date and goes negative for expired licences. phone is formatted 208-596-2905 when L&I published ten digits. zip5 is the five-digit ZIP; zip is as published (sometimes nine digits). Text fields are delivered as L&I published them, so city can read SEATTLE on one licence and Seattle on another; the city, state, specialty and businessName filters are case-insensitive. Records are deduplicated on licence number, which L&I's own dataset notes call the unique identifier.

Input

Everything is optional. Run it with no input and you get the 100 most recently effective Active licences from the last 30 days: the new-contractor feed.

FieldTypeDefaultNotes
effectiveWithinDaysinteger30Licences effective in the last N days. 0 disables the window and searches the whole registry. Ignored when an effective-date range, a licence number or a UBI is given.
effectiveDateFrom / effectiveDateToISO date-Explicit effective-date range; replaces the N-day window.
expirationDateFrom / expirationDateToISO date-Licences expiring in this range. Renewal leads.
statusenumactiveactive, expired, suspended, outOfBusiness, inactive, reLicensed, or any.
licenseTypeenumanyCC construction, EC electrical, PC plumbing, LC elevator.
specialtystring-An L&I specialty code (01 GENERAL, CB PAINTING/WALLCOVERING, CD ROOFING, BI CONCRETE, BW LANDSCAPING, SM HVAC/R, SK floor covering, HM HANDYMAN) or a word from the description (ROOFING). Matches either specialty slot. % and _ are rejected.
citystring-Case-insensitive exact match on the address city, e.g. Seattle, Spokane, Vancouver, Tacoma. The registry has no county column.
zipstring-ZIP prefix: 981 for Seattle-area ZIPs, 98101 for one ZIP.
statestring-Two-letter state of the mailing address. The registry includes out-of-state contractors licensed in Washington (3,090 Active in OR, 1,156 in ID on 2026-08-23).
businessNamestring-Case-insensitive substring on the business name. % and _ are rejected.
licenseNumberstring-One licence exactly, e.g. 04CONCL862CR. Disables the N-day window.
ubistring-Nine-digit Washington UBI. A UBI can carry several licences. Disables the N-day window.
joinarray[]Any of principals, bond, insurance, signers. Each join adds two health-check requests on its source plus at least one request per 100 licences. Joined rows ride inside the licence record and are not charged separately.
maxResultsinteger1001 to 50000. This is your cost cap: you pay per delivered record.
includeRawbooleanfalseAttach a raw object with the untouched data.wa.gov rows under their L&I column names.

Every filter is evaluated by data.wa.gov, not after download, so a narrow run is fast and cheap.

Example inputs

New contractors this week, with owner and bond, for account opening (supplier):

{
"effectiveWithinDays": 7,
"join": ["principals", "bond"],
"maxResults": 500
}

Active licences expiring in the next quarter, with current bond and insurance (surety or insurance agent; 5,234 Active licences expire between 2026-09-22 and 2026-12-21 as of 2026-08-23):

{
"effectiveWithinDays": 0,
"expirationDateFrom": "2026-09-22",
"expirationDateTo": "2026-12-21",
"join": ["bond", "insurance"],
"maxResults": 6000
}

Every active roofing contractor in the Seattle ZIPs (marketplace or GC):

{
"effectiveWithinDays": 0,
"specialty": "ROOFING",
"zip": "981",
"maxResults": 1000
}

One contractor, full file (pre-engagement check):

{
"licenseNumber": "04CONCL862CR",
"status": "any",
"join": ["principals", "bond", "insurance", "signers"],
"includeRaw": true
}

Pricing

$0.003 per record; you pay only for records delivered. One charge per dataset item, nothing else. Joined principals, bonds, policies and signers are part of the record, not extra items. Set maxResults and you have set your bill: 100 records is $0.30, and a run delivers up to 50,000 records (about $150 at list price); to retrieve more than that, for example all 56,306 Active licences, split the job by date range or ZIP prefix across runs. A search that matches nothing is free.

Data source, refresh and licence

Records come from five Socrata (SODA) datasets published by the Washington State Department of Labor & Industries on data.wa.gov. Row counts read live on 2026-08-23:

DatasetIDRowsUsed for
L&I Contractor License Data - Generalm8qx-ubtq120,000 licences (56,306 Active)every record
L&I Contractor License - Principal Data4xk5-x9j6250,811 rows across 146,654 licencesjoin: principals
L&I Contractor License Data - Bondbzff-4fmt176,491 rows across 82,416 licencesjoin: bond
L&I Contractor License Data - Insuranceciwg-agsx76,779 rows across 70,720 licencesjoin: insurance
L&I Contractor Authorized Signer Datas7ge-wicw10,428 rows across 8,310 licencesjoin: signers

Refresh: the General dataset's own notes say "L&I Contractor Contractor Data is updated thee times per day: 7:30 a.m., 12:15 p.m., 5:15 p.m." (typos in the original); the Insurance dataset carries the same three-times-daily note, and the Principal and Signer datasets state a daily 7:30 a.m. posting. All five datasets showed a rowsUpdatedAt of 2026-08-23 when read that day. Every record carries sourcePublishedAt, the General dataset's own publication timestamp, so you can see how fresh the copy you were served is. 665 Active licences had an effective date in the 30 days to 2026-08-23, and the newest effective date was 2026-08-21.

Licence: the General and Principal datasets carry the licence "Open Data Commons Public Domain Dedication and License" (PDDL, terms) in their own Socrata metadata; the Insurance and Signer datasets carry "Public Domain"; the Bond dataset's metadata carries no licence field (all read 2026-08-23). All five state the attribution "Labor & Industries" and link to L&I's public Verify a Contractor service as their source.

This Actor is not affiliated with or endorsed by the Washington State Department of Labor & Industries. Attribution on every record: "Washington State Department of Labor & Industries".

The Actor reads the public SODA endpoints with a descriptive User-Agent (jserle-apify-actor/wa-contractor-license-registry), sends requests one at a time with the 1-second Crawl-delay from the host's robots.txt (which does not disallow /resource/*), uses no app token, and caches nothing between runs. A default run makes four requests; each join adds two health-check requests (an unfiltered count and a five-row sample that must carry every column the normalizer reads) plus at least one request per 100 licences; a run that spans more than one page of 1,000 licences adds one recount request at the end.

Limitations

  • The General dataset holds exactly 120,000 rows, a round figure, and its notes say a UBI may carry multiple records. Whether L&I caps the export is not stated in the metadata; the dataset spans effective dates from 1935 to 2026-08-21 and every status, so it is not a recent-only slice.
  • No county. L&I publishes city, state and ZIP. Use zip prefixes or a list of cities for a territory.
  • Joins are a snapshot of what L&I has on file. Every requested join source is checked before use (row count above a floor, required columns present on an unfiltered sample), so an emptied or renamed addendum fails the run rather than delivering licences with empty joins; a licence with genuinely no bond or policy on file gets an empty array. A new licence normally has its principal, bond and insurance rows within the same day: of the 25 newest Active licences on 2026-08-23, 25 had principal rows, 25 had a bond row and 24 had an insurance row. Signer rows exist for only 8,310 licences, and 65% of signer rows carry no signer name; nameless rows are skipped, so authorizedSigners is empty for most licences.
  • Bond and insurance history is included, not just the current instrument. currentBond and currentInsurance pick the one in force on the run date; use the arrays for cancellations, impairments and lapses.
  • Phone and principal are as registered with L&I. 53 of 120,000 licences have no phone and 286 have no primary principal; those fields are null.
  • A filter that matches nothing returns zero records and succeeds. That is a valid, free answer. The run only fails when the source itself is broken, and then it exits non-zero having pushed nothing and charged nothing: when a dataset (the registry or any requested join) stops publishing a column the normalizer reads or reports an implausibly small row count, when the registry returns no rows to the default query, returns fewer rows than data.wa.gov's own count for the same filter, shifts under a multi-page walk (the same licence on two pages, or a different count after paging than before; L&I rewrites the dataset three times a day, so re-run), or when a monetized run cannot read its charge allowance. Individual malformed rows are skipped and counted in the run summary rather than delivered.

FAQ

How do I do a Washington contractor license lookup in bulk?

Set effectiveWithinDays: 0, status: "any" and whatever narrows it (city, ZIP, specialty, name), or pass licenseNumber or ubi for one contractor. Every record carries the L&I licence number, UBI, status, effective and expiration dates.

Can I check whether a Washington contractor is bonded and insured?

Yes. Add join: ["bond", "insurance"]. currentBond and currentInsurance are the instruments in force on the run date, with firm, amount and expiration; bonds and insurancePolicies carry the history including cancellations and impaired bonds.

How do I get a list of newly licensed contractors in Washington?

That is the default run: Active licences effective in the last 30 days, newest first. Set effectiveWithinDays: 7 and schedule the Actor weekly for a rolling new-contractor feed.

Can I find contractors whose licence or bond is about to expire?

Use expirationDateFrom and expirationDateTo with effectiveWithinDays: 0 for licence renewals, and join: ["bond", "insurance"] to read currentBond.expirationDate and currentInsurance.expirationDate on the same records.

Does it cover electricians and plumbers as well as general contractors?

Yes. The registry holds construction (CC), electrical (EC), plumbing (PC) and elevator (LC) contractor licences; filter with licenseType.

Who are the owners of a Washington contractor?

join: ["principals"] attaches every principal L&I has on file with start and end dates; primaryPrincipalName is on every record without a join.

Other datasets by the same author, all pay-per-record with source, refresh cadence and licence stated on each listing:

Public procurement and RFP feeds

Nursing home and long-term care data

Medicare provider enrollment data

Developer and AI test data