# US Contractor Licenses: WA, OR, TX & CT License Lookup (`cprussin/us-contractor-licenses`) Actor

Contractor licenses from official state open data (WA, OR, TX, CT) in one schema: business, license number, type, status, dates, address, phone, principal, bond and insurance. Filter by state, status, trade, city or ZIP. Delta mode returns new licensees. $2 per 1,000.

- **URL**: https://apify.com/cprussin/us-contractor-licenses.md
- **Developed by:** [Connor Prussin](https://apify.com/cprussin) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 license records

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

## US Contractor Licenses: multi-state contractor license lookup and new-licensee feed

**US Contractor Licenses** pulls contractor license records from official state open-data portals and returns them in **one normalized schema**. One run covers **Washington, Oregon, Texas and Connecticut**: business name, license number, license type and specialty, status, issue and expiration dates, address, phone, principal, and (Oregon) surety bond and liability insurance.

- ✅ **4 states, one schema.** No more stitching together four different state license lookups.
- ✅ **Official public-domain data.** Every record comes from a state government Socrata open-data portal (public domain / ODC-PDDL), with a link to the exact source row.
- ✅ **New-licensee feed:** set `issuedAfter` to get only contractors licensed since your last run.
- ✅ Filter by state, active status, trade (electrical, plumbing, HVAC, home improvement...), city or ZIP. Filters run on the state's server, so runs are fast and cheap.
- ✅ No login, CAPTCHA or proxy. You pay per license returned.

### Start in one minute

Click **Start** with the prefilled input:

```json
{
  "states": ["WA", "OR", "TX", "CT"],
  "licenseStatus": "active",
  "maxItems": 100
}
```

You get: up to 100 active contractor licenses across WA, OR, TX and CT, with `businessName`, `licenseNumber`, `licenseType`, `status`, `expirationDate`, `address`, `phone` and `sourceUrl`.

**Cost:** up to $0.20: 100 licenses × $0.002, plus the $0.00005 actor-start fee.

### Use with an AI assistant

Connect the [Apify MCP server](https://mcp.apify.com) to Claude, ChatGPT, Cursor or any MCP client (`https://mcp.apify.com?tools=cprussin/us-contractor-licenses` loads only this actor), then paste:

```text
Use the Apify actor cprussin/us-contractor-licenses to list 50 active electrical contractors in Seattle, WA with license number, expiration date and phone.
```

### Recipes

#### New contractors licensed this month

Schedule weekly and move `issuedAfter` forward each time (Texas publishes no issue date and is skipped in this mode).

```json
{
  "states": ["WA", "OR", "CT"],
  "issuedAfter": "2026-10-01",
  "maxItems": 500
}
```

#### Electricians and plumbers in one metro

```json
{
  "states": ["WA"],
  "licenseTypes": ["electrical", "plumbing"],
  "zipCodes": ["981"],
  "maxItems": 200
}
```

#### Oregon contractors with bond and insurance details

```json
{
  "states": ["OR"],
  "cities": ["Portland"],
  "licenseTypes": ["residential"],
  "maxItems": 100
}
```

#### Verify a license status (all statuses)

```json
{
  "states": ["WA"],
  "licenseStatus": "all",
  "cities": ["Spokane"],
  "licenseTypes": ["roofing"],
  "maxItems": 50
}
```

### Who uses contractor license data?

- **Building-supply, tool and equipment sellers** reach newly licensed contractors before they pick suppliers.
- **Contractor insurance, surety bond and workers' comp agents** contact new licensees and those with expiring coverage.
- **Home-services marketplaces and lead-gen platforms** verify that pros are licensed and active.
- **Software vendors** (field service, estimating, invoicing) build prospect lists by trade and region.
- **Compliance and procurement teams** check license status and expiration before hiring a contractor.

### How does it work?

1. Pick states and filters (status, trade keywords, city, ZIP, issue date).
2. The actor queries each state's official Socrata SODA API (`/resource/<id>.json`) with SoQL filters, so only matching rows are downloaded. It identifies itself honestly and waits at least 1 second between requests to each portal, as their robots.txt asks.
3. It maps every state into the same schema and interleaves states, so even a small `maxItems` covers all of them.

### Which states are covered?

| State | Dataset                                                                  | Publisher                                     | What's included                                                                                               |
| ----- | ------------------------------------------------------------------------ | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| WA    | [L\&I Contractor License Data - General](https://data.wa.gov/d/m8qx-ubtq) | Washington Department of Labor & Industries   | Construction, electrical, plumbing and elevator contractors, all statuses. Specialty, phone, principal.       |
| OR    | [CCB Active Licenses](https://data.oregon.gov/d/g77e-6bhs)               | Oregon Construction Contractors Board         | Active licenses, one item per endorsement. Bond and insurance company and amount, county, phone, RMI.         |
| TX    | [TDLR - All Licenses](https://data.texas.gov/d/7358-krk7)                | Texas Department of Licensing and Regulation  | Contractor license types (A/C, electrical, electrical sign, elevator, appliance installation). No issue date. |
| CT    | [State Licenses and Credentials](https://data.ct.gov/d/ngch-56tr)        | Connecticut Department of Consumer Protection | Contractor credentials: home improvement, new home, major, electrical, plumbing, HVAC, sheet metal and more.  |

### Input

| Field           | Description                                                                    | Example                     |
| --------------- | ------------------------------------------------------------------------------ | --------------------------- |
| `states`        | States to search (empty = all)                                                 | `["WA", "OR"]`              |
| `licenseStatus` | `active` (default) or `all`                                                    | `"all"`                     |
| `licenseTypes`  | License type or specialty contains any of these words                          | `["electrical", "roofing"]` |
| `cities`        | Exact city names of the business address (case-insensitive)                    | `["Seattle", "Portland"]`   |
| `zipCodes`      | ZIP codes or 3-4 digit prefixes                                                | `["981", "97201"]`          |
| `issuedAfter`   | Delta mode: only licenses issued on or after this date. TX is skipped when set | `"2026-10-01"`              |
| `maxItems`      | Maximum licenses to return across all states                                   | `100`                       |
| `includeRaw`    | Add the original source row as `raw`                                           | `false`                     |

### Output

One dataset item per license:

```json
{
  "state": "WA",
  "businessName": "ANDALUSIAN FENCE & LNDSCPN LLC",
  "licenseNumber": "ANDALFL748PT",
  "licenseType": "CONSTRUCTION CONTRACTOR",
  "licenseTypeCode": "CC",
  "specialty": "GENERAL",
  "status": "ACTIVE",
  "active": true,
  "issueDate": "2026-10-30",
  "expirationDate": "2028-10-30",
  "address": "15316 77TH AVE NE",
  "city": "ARLINGTON",
  "addressState": "WA",
  "zip": "98223",
  "county": null,
  "phone": "2067391615",
  "principalName": "GUZMAN MONTES, OSCAR SAUL",
  "bondCompany": null,
  "bondAmount": null,
  "insuranceCompany": null,
  "insuranceAmount": null,
  "sourceDataset": "data.wa.gov/m8qx-ubtq (L&I Contractor License Data - General)",
  "sourceUrl": "https://data.wa.gov/resource/m8qx-ubtq.json?%24where=contractorlicensenumber+%3D+%27ANDALFL748PT%27"
}
```

**Field notes**

- `state` is the licensing state; `addressState` is the state of the business address (out-of-state contractors are common).
- `issueDate`: WA = start of the current license term; OR = registration date; CT = issue date; TX = not published.
- `status` is the state's own label. `active` is a normalized boolean (TX: derived from the expiration date; CT: `ACTIVE*` or `APPROVED` statuses).
- `bondCompany`, `bondAmount`, `insuranceCompany` and `insuranceAmount` are published by Oregon only.
- Fields a state doesn't publish are `null`.

### Pricing

This actor is priced **per result** (pay-per-event):

| Event                                    | Price      |
| ---------------------------------------- | ---------- |
| License record (one item in the dataset) | **$0.002** |

1,000 licenses cost $2.00. If you set a **maximum cost per run**, the actor stops cleanly when it reaches that limit.

### FAQ

**Is this data official and free to reuse?** Yes. All four datasets are published by state agencies on their open-data portals under public-domain terms (public domain or ODC-PDDL). `sourceUrl` links to the exact source row.

**How fresh is it?** The portals refresh these datasets daily to weekly.

**Can I add my state?** Many states publish contractor licenses on Socrata portals; adding one is a small change, so ask in the Issues tab.

**Disclaimer:** This actor is not affiliated with any state government. Always confirm license status with the issuing agency before relying on it, and follow marketing laws (CAN-SPAM, TCPA, state rules) when contacting businesses.

### Related actors

- [New Business Registrations](https://apify.com/cprussin/new-business-registrations?fpr=to54nm): Newly registered LLCs and corporations from official state registries.
- [Federal Recompete Radar](https://apify.com/cprussin/federal-recompete-radar?fpr=to54nm): US federal contracts nearing expiry, with incumbent and value.

# Actor input Schema

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

States to search. Leave empty for all supported states.

## `licenseStatus` (type: `string`):

Active licenses only, or every status the state publishes (expired, suspended, out of business...). Oregon publishes active licenses only.

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

Only licenses whose type or specialty contains any of these words, e.g. electrical, plumbing, roofing, home improvement, residential.

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

Exact city names of the business address, case-insensitive, e.g. Seattle, Portland, Austin.

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

5-digit ZIP codes or 3-4 digit prefixes, e.g. 98101 or 981.

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

Delta mode: only licenses issued (WA: current term started) on or after this date (YYYY-MM-DD). Texas publishes no issue date and is skipped when this is set.

## `maxItems` (type: `integer`):

Maximum number of licenses to return across all states. Each result is billed as one event.

## `includeRaw` (type: `boolean`):

Add the original dataset row as `raw` to each item.

## Actor input object example

```json
{
  "states": [
    "WA",
    "OR",
    "TX",
    "CT"
  ],
  "licenseStatus": "active",
  "maxItems": 100,
  "includeRaw": false
}
```

# Actor output Schema

## `results` (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",
        "OR",
        "TX",
        "CT"
    ],
    "licenseStatus": "active",
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("cprussin/us-contractor-licenses").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",
        "OR",
        "TX",
        "CT",
    ],
    "licenseStatus": "active",
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("cprussin/us-contractor-licenses").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",
    "OR",
    "TX",
    "CT"
  ],
  "licenseStatus": "active",
  "maxItems": 100
}' |
apify call cprussin/us-contractor-licenses --silent --output-dataset

```

## MCP server setup

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

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/JFqsEMrZ5RPXAf0rK/builds/JBC62DIkCW9dljhxP/openapi.json
