# Contractor License Search – New Contractor Leads WA OR TX NY (`gazidev/contractor-license-search`) Actor

Search official state contractor and trade license registries (Washington L\&I, Oregon CCB, Texas TDLR, New York DOL): business name, owner, trade, license status, issue and expiry dates, address and phone. New-license leads and license verification. $1.50 per 1,000 licenses.

- **URL**: https://apify.com/gazidev/contractor-license-search.md
- **Developed by:** [Cemal Atakli](https://apify.com/gazidev) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 licenses

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Contractor License Search – New Contractor Leads WA OR TX NY

Search **official state contractor and trade license registries** in one schema: business name, owner or principal, trade/specialty, license status, issue and expiry dates, address, phone, and (Oregon) bond and insurance details.

Use it to **find newly licensed contractors** (fresh leads for suppliers, insurers, software and marketing agencies), **verify a contractor's license** before hiring, or build lists of active roofers, electricians, plumbers, HVAC and general contractors by city, ZIP or county.

Data comes from the states' own open-data portals (Socrata APIs). No scraping, no login.

**$1.50 per 1,000 licenses.** You pay only for records saved.

### Registries

| Code | Registry | Records | What you get |
|---|---|---|---|
| `WA` | Washington L\&I – Contractor License Data | ~160k (76k active) | All construction trades (general, roofing, painting, HVAC, plumbing, electrical contractors...), issue date, phone, address, principal name, UBI |
| `OR` | Oregon CCB – Active Licenses | ~57k active | Residential/commercial general and specialty contractors, original registration date, phone, address, **bond and liability insurance company, amount and expiry** |
| `TX` | Texas TDLR – All Licenses | ~970k | A/C contractors and technicians, electricians, electrical contractors, appliance installers, well drillers, tow operators, salons and barber shops... Expiry date and county. **Contractor and individual records have no address or phone in the public data**; business establishments (salons, barber shops, schools) do. No issue date. |
| `NY` | New York DOL – Contractor Registry Certificate | ~15k | Contractors registered for public work: business type, issue/expiry date, address, phone, MWBE and debarment flags |

### Input examples

New roofing and general contractors in Washington in the last 30 days, with a phone number:

```json
{
  "states": ["WA"],
  "licenseTypes": ["roofing", "general"],
  "issuedWithinDays": 30,
  "onlyWithPhone": true
}
```

Oregon residential contractors in Multnomah County (Portland) whose liability insurance details you want:

```json
{
  "states": ["OR"],
  "licenseTypes": ["Residential General"],
  "counties": ["Multnomah"]
}
```

Texas A/C contractors in Travis County:

```json
{ "states": ["TX"], "licenseTypes": ["A/C Contractor"], "counties": ["Travis"] }
```

Verify licenses:

```json
{ "states": ["WA"], "licenseNumbers": ["AMBEREL740OQ"], "activeOnly": false }
```

`licenseTypes` matches any part of the license type or specialty text (`electric` matches Electrical Contractor and Master Electrician).

### Output

Sample (Washington, new license):

```json
{
  "registryState": "WA",
  "licenseNumber": "AMBEREL740OQ",
  "businessName": "AMBERCREST ELECTRICAL LLC",
  "ownerName": "BUTOK, DANIEL",
  "licenseType": "ELECTRICAL CONTRACTOR",
  "specialty": "RESIDENTIAL",
  "businessType": "Limited Liability Company",
  "status": "ACTIVE",
  "issuedDate": "2026-10-19",
  "expirationDate": "2028-10-19",
  "address": "522 W RIVERSIDE AVE STE N",
  "city": "SPOKANE",
  "state": "WA",
  "zip": "99201",
  "phone": "(360) 488-8659",
  "ubi": "606277030",
  "source": "https://data.wa.gov/d/m8qx-ubtq"
}
```

Oregon rows add `county`, `bondCompany`, `bondAmount`, `bondExpirationDate`, `insuranceCompany`, `insuranceAmount`, `insuranceExpirationDate`. New York rows add `mwbeOwned` and `debarred`. Fields a registry does not publish are `null`.

### New-contractor monitoring

Turn on **Only new records**, set `issuedWithinDays` (for example 14) and schedule the Actor weekly. Each run returns only licenses you have not received before (tracked per **State key**).

### Pricing

Pay per event: **$0.0015 per license saved** ($1.50 per 1,000), plus a tiny start fee. Set **Max licenses** or a maximum cost per run; the run stops cleanly at that limit.

### Notes

- Data is as current as each state's portal (WA, TX and NY update daily; OR at least monthly).
- Oregon's registry contains active licenses only.
- `issuedWithinDays` uses the license effective date (WA), issue date (NY) or original registration date (OR). Texas publishes no issue date, so Texas is skipped when a date filter is set.
- Always confirm a license on the state's official lookup before relying on it.

### Data sources and terms

Washington State Department of Labor & Industries (data.wa.gov, ODC Public Domain), Oregon Construction Contractors Board (data.oregon.gov, public domain), Texas Department of Licensing and Regulation (data.texas.gov), New York State Department of Labor (data.ny.gov). This Actor is not affiliated with or endorsed by these agencies.

### Related Actors

- [Building Permits Search – US City Construction Leads](https://apify.com/gazidev/building-permits-search)
- [US Business Entity Search & New LLC Leads](https://apify.com/gazidev/us-business-entity-leads)
- [SAM.gov Contract Opportunities – Federal Bids & RFP Alerts](https://apify.com/gazidev/sam-gov-contract-opportunities)

# Actor input Schema

## `states` (type: `array`):

Which official license registries to search.

## `licenseTypes` (type: `array`):

Match license type or specialty text, e.g. `roofing`, `plumbing`, `electric`, `HVAC`, `A/C Contractor`, `Residential General`. Empty = all.

## `issuedWithinDays` (type: `integer`):

New-contractor leads. WA, NY (issue date) and OR (original registration date). Texas has no issue date and is skipped when this is set.

## `issuedAfter` (type: `string`):

YYYY-MM-DD. Overrides *issued in the last N days*.

## `cities` (type: `array`):

Exact city names, e.g. `Seattle`, `Portland`, `Houston`.

## `zipCodes` (type: `array`):

E.g. `98101` or `981` for the whole area.

## `counties` (type: `array`):

County names, e.g. `Multnomah`, `Harris`.

## `nameContains` (type: `string`):

Search by company or principal name.

## `licenseNumbers` (type: `array`):

Verify specific licenses (up to 500 per state). When used, other filters are ignored.

## `activeOnly` (type: `boolean`):

Skip expired, suspended and out-of-business licenses.

## `onlyWithPhone` (type: `boolean`):

Skip records without a phone.

## `onlyNew` (type: `boolean`):

Skip licenses returned by earlier runs with the same *State key*. Schedule weekly for a new-contractor feed.

## `stateKey` (type: `string`):

Separate 'already seen' lists for different searches.

## `socrataAppToken` (type: `string`):

Optional free token for higher rate limits on very large exports.

## `maxResults` (type: `integer`):

Stop after this many records (0 = all matching). You pay per license saved.

## Actor input object example

```json
{
  "states": [
    "WA"
  ],
  "activeOnly": true,
  "onlyWithPhone": false,
  "onlyNew": false,
  "stateKey": "default",
  "maxResults": 20
}
```

# Actor output Schema

## `licenses` (type: `string`):

No description

## `results` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "states": [
        "WA"
    ],
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("gazidev/contractor-license-search").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "states": ["WA"],
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("gazidev/contractor-license-search").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "states": [
    "WA"
  ],
  "maxResults": 20
}' |
apify call gazidev/contractor-license-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gazidev/contractor-license-search"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/rQrihbZCal4K7RBzy/builds/nHkNjwWjkKheB2v44/openapi.json
