WA Contractor License Scraper (L&I Status Lookup) avatar

WA Contractor License Scraper (L&I Status Lookup)

Pricing

from $1.60 / 1,000 licence delivereds

Go to Apify Store
WA Contractor License Scraper (L&I Status Lookup)

WA Contractor License Scraper (L&I Status Lookup)

Washington State L&I contractor license database: JSON records with number, business name (registered entities), type, class, specialty, status, dates, city, UBI. Filter by number or status. Lookup, bulk export or incremental runs. For contractor vetting and compliance. No personal contact fields.

Pricing

from $1.60 / 1,000 licence delivereds

Rating

0.0

(0)

Developer

Steadfetch

Steadfetch

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 hours ago

Last modified

Share

Tested daily. Last verified: 2026-10-30

Look up contractor, liquor and professional licence records from official US state open-data sources. Built by Steadfetch: web data that does not break.

What it does

The Actor reads three keyless public Socrata datasets and returns one JSON item per row in a unified multi-state schema:

  • Washington contractor licences - the L&I Contractor License Data - General dataset (data.wa.gov, resource m8qx-ubtq), unchanged since v1.
  • New York liquor licences - the Current Liquor Authority Active Licenses dataset (data.ny.gov, resource 9s3h-dpkz, about 60,000 active licences, refreshed daily).
  • Washington professional licence transactions - the DOL Professional License Transactions dataset (data.wa.gov, resource ixni-jq78), aggregate counts of original, renewal and reinstatement transactions by programme, licence type, county and date.

Every item carries state (source jurisdiction: wa or ny) and family (contractor, liquor or professional), so results from all sources can be mixed, filtered and joined downstream.

  • Filters: state and family selection, text search on holder or licence-type names, date range, and the v1 WA filters (exact licence number, status).
  • Incremental delta runs: the default mode delivers only new or changed rows for the same filter scope. Changed rows keep their original firstSeen and get lastChanged, so you can detect licence updates daily.
  • Full bulk export: fetchAll: true re-reads the selected datasets.
  • Normalized output: dates become YYYY-MM-DD, missing values become null, and the WA specialty is a nested { code, name } object.
  • Schema validation: every item is validated against .actor/dataset_schema.json before it reaches the dataset. An invalid item fails the run.
  • No charge for noise: invalid rows, duplicates, personal-data-excluded rows and rows already delivered unchanged by a previous incremental run are never pushed, so they are never billed.

Privacy: business records only

The sources contain personal columns. This Actor never selects them from the APIs, so they are never downloaded, stored or published.

  • WA contractor: businessName is published only for registered entity types (LLC, corporation, partnership, LLP, joint venture, association, trust); for individual licences it is null. The principal name, phone, street address and ZIP columns are never requested.
  • NY liquor: the dataset has no entity-type flag, so the Actor publishes a row only when the licence holder is confirmed as an organization by a corporate marker in the legal name. Sole-proprietor rows (about 3% of the dataset, including chains without a legal suffix) are excluded entirely instead of risking a natural person's data. ZIP and georeference columns are never selected.
  • WA professional: the source is aggregate counts only - no licence holder exists in it.
  • The output schema is closed (additionalProperties: false): a row with any extra field, including a personal one, is rejected before it can be pushed.

Source, licence and access

  • WA contractor: L&I Contractor License Data - General, Open Data Commons PDDL (public domain).
  • NY liquor: Current Liquor Authority Active Licenses, published by the New York State Liquor Authority on the official state open-data portal (Open NY program).
  • WA professional: Professional License Transactions, Open Data Commons ODbL. The Actor names the Washington State Department of Licensing as the source and ships the source's own records, so the license terms are honoured with attribution and licensing notice.
  • robots.txt: read on 2026-10-25 for both portals. User-agent: * declares Crawl-delay: 1 on both hosts; filter URLs under /browse and /catalog are disallowed. The Actor only calls the exact /resource/<id>.json endpoints, waits at least 1000 ms between requests and revalidates every redirect destination against the same allowlist. Full details in the repository's docs/legal-gate.md.
  • Not included: the NMLS registry (nmlsconsumeraccess.org) blocks automated access with 403 + CAPTCHA and is excluded on purpose.

Input

FieldTypeDefaultDescription
statesarrayallSource states to query: ny, wa. Empty means all sources.
familiesarrayallFamilies to query: contractor, liquor, professional. Empty means all.
licenseNumberstring-Optional exact WA contractor licence number. When set (or when status is set), only the WA contractor source is queried, as in v1.
statusenum-Optional WA contractor status: ACTIVE, INACTIVE, EXPIRED, SUSPENDED. Other source statuses are returned when no filter is set.
qstring-Optional case-insensitive text filter on holder or licence-type names (never on personal columns).
dateFrom / dateTodate-Optional range on the source's effective/transaction date (dateTo is exclusive).
maxResultsinteger 1-5000-Total row cap across all selected sources, split evenly between them (the first sources take the remainder). Overrides maxRows when set.
maxRowsinteger 1-5000100Legacy v1 total row cap (default 100, split evenly across sources). Ignored when maxResults is set.
fetchAllbooleanfalsetrue fetches the full selected datasets, ignoring row caps and the delta state.
strictSchemabooleantrueFail the run when an item fails schema validation. Keep enabled.

Minimum input

Every field is optional. This is the smallest real input that runs:

{}

With {} the Actor returns up to 100 rows split evenly across the three sources and bills about 0.20 USD. Raise maxResults for larger extracts.

A single-licence WA lookup (v1 compatible):

{
"licenseNumber": "WHIDBIT745PO"
}

New York liquor licences only:

{
"states": ["ny"],
"families": ["liquor"],
"maxResults": 1000
}

Example output

A New York liquor licence:

{
"url": "https://data.ny.gov/resource/9s3h-dpkz.json?licensepermitid=0032-23-139868",
"title": "OSPREYS DOMINION VINEYARDS LTD",
"scrapedAt": "2026-10-25T02:00:00.000Z",
"state": "ny",
"family": "liquor",
"licenseNumber": "0032-23-139868",
"businessName": "OSPREYS DOMINION VINEYARDS LTD",
"businessType": null,
"licenseType": "Farm winery",
"licenseClass": "0032",
"specialty": null,
"status": "active",
"issuedAt": "2023-05-01",
"firstSeen": "2026-10-25T02:00:00.000Z",
"lastChanged": null,
"premisesAddress": "44075 MAIN RD, PECONIC",
"county": "Suffolk",
"businessState": null,
"effectiveDate": "2023-05-01",
"expirationDate": "2026-04-30",
"city": "PECONIC",
"ubi": null,
"programType": null,
"transactionType": null,
"transactionCount": null,
"transactionDate": null,
"sourceUrl": "https://data.ny.gov/d/9s3h-dpkz"
}

A WA contractor licence keeps the v1 fields (licenseNumber, businessName, specialty, effectiveDate, ubi, ...) and adds state: "wa", family: "contractor" and the delta fields. A WA professional aggregate row has licenseNumber: null, status: null and carries programType, transactionType, transactionCount and transactionDate.

Schema note (v0.2): the state field now holds the source jurisdiction (wa/ny). The WA licence holder's address state, previously published in state, moved to businessState so the unified schema stays closed and explicit.

Output fields

FieldTypeSource
urlURIpublic Socrata API URL for this record (envelope)
titlestring or nullbusiness name for entities; licence number; record label for aggregates
scrapedAtdate-timerun timestamp (envelope)
statestringsource jurisdiction: wa or ny
familystringcontractor, liquor or professional
licenseNumberstring or nulllicence number; null for aggregate rows
businessNamestring or nullholder name, only for confirmed organizations
businessTypestring or nullWA contractor businesstypecodedesc
licenseTypestring or nulllicence type or class description
licenseClassstring or nullclass code
specialtyobject or nullWA contractor specialtycode1 + specialtycode1desc as { code, name }
statusstring or nulllicence status; null for aggregates
issuedAtdate or nulloriginal issue date (NY)
firstSeendate-timefirst run that delivered the row
lastChangeddate-time or nullrun in which the row content changed
premisesAddressstring or nulllicensed premises, address and city (NY)
countystring or nullpremises county (NY) or aggregate county (WA professional)
businessStatestring or nullWA holder address state (v1 state semantics); licensees' state for WA professional aggregates
effectiveDate / expirationDatedate or nulllicence dates
citystring or nullholder or premises city
ubistring or nullWA Unified Business Identifier
programType / transactionType / transactionCount / transactionDatesee dataset schemaWA professional aggregate dimensions and count

Incremental runs and delta detection

  • fetchAll: false (default): each source persists what it has delivered for the current filter scope. A later run delivers only rows that are new or whose content changed (row content hash). New rows get firstSeen = this run, lastChanged = null; changed rows keep the original firstSeen and get lastChanged = this run. Unchanged rows are skipped and billed nothing.
  • fetchAll: true: a full export. It ignores the persisted state and returns the complete current selection with firstSeen = this run and lastChanged = null.

The scope is the pair of filters you use (v1: licenseNumber + status; multi-state: states + families + q + dates). Change any filter to start a separate incremental series.

Limitation, stated honestly: for the WA contractor source the dedupe key is still licence number + effective date, as in v1: a status-only change of an existing licence is not re-emitted incrementally - use fetchAll: true to re-read it. The NY and WA professional sources use a full row-content hash, so any change in the source row is detected.

Pricing

Pay-per-event, with the two synthetic platform events only:

EventWhen it firesPrice
apify-actor-startOnce per run start (includes the first 5 s of compute for free)0.00005 USD
apify-default-dataset-itemOne row saved to the dataset: a WA contractor licence, a NY liquor licence or a WA professional transaction record0.002 USD = 2.00 USD per 1,000 results

One row = one charged result, never a page or a retry. The price is unchanged from v0.1.

Works on the Apify free plan - about 2,499 rows for the $5 monthly credit ((5.00 USD - 0.00005 USD run-start) / 0.002 USD per row).

Cost per 1,000 results

Measured locally on 2026-10-22 over 5,000 real WA contractor rows: extraction plus schema validation took 151 ms (30.3 ms per 1,000 rows) with zero schema rejections. The two new sources use the same JSON + validation pipeline, so the per-row cost stays in the same range (see docs/measurements.md).

The real cost driver is the robots-mandated 1 s delay between page requests: a full 161,000-row WA scan makes about 33 requests, so roughly 33 s of wall time. Even with a deliberately conservative allowance for compute, dataset writes and data transfer, the total stays below 0.001 USD per 1,000 results - a gross margin above 99% at the 2.00 USD price. The first paid run will confirm the billed figure.

FAQ

Do I need an API key? No. All three Socrata resources are public and keyless.

Does it scrape the website? No. It calls the official JSON APIs, which is faster and cheaper than rendering the web front ends.

Can I get personal contact data? No. The Actor never requests principal name, phone, street address or ZIP columns for WA contractor licences; it excludes every NY row whose holder is not a confirmed organization; and the WA professional source is aggregate counts only. The goal is business licence data, not people.

Which fields exist per family? WA contractor rows fill the v1 fields (licence number, business name, specialty, UBI, dates). NY liquor rows fill licenseNumber, businessName, premisesAddress, county, licenseType and the licence dates. WA professional rows carry programType, transactionType, transactionCount and transactionDate, with licenseNumber, businessName and status null. All rows always carry state, family, firstSeen and lastChanged.

How do I monitor new licences every day? Run incrementally (default) with your filters. You pay only for rows that are new or changed; unchanged days cost nothing.

Why did my NY run return fewer rows than the source has? The Actor excludes rows whose holder cannot be confirmed as an organization (sole proprietors) to keep natural persons' data out of the output. That is about 3% of the NY dataset.

How do I re-extract everything? Run with fetchAll: true. This is a paid bulk export of the selected datasets.

Why did my second incremental run return zero rows? Because the scope was already fully delivered and nothing changed. That is the intended behaviour and it costs nothing.

Maintenance

tested daily. Steadfetch runs a catalog test every day against the live APIs, validates the output against the published schema and turns failures into issues in the repository. The sources are stable government Socrata datasets, and the Actor has no browser, proxy or anti-bot dependency.