# US Contractor License Lookup: FL, TX, NY, WA, OR, CT, CO, MD (`spriggs-data/us-contractor-license-lookup`) Actor

Verify contractor licenses and build trade-contractor lead lists from 12 official state & city license databases (Florida DBPR, Texas TDLR, WA L\&I, Oregon CCB, NY, NYC DOB, Connecticut, Colorado...). Search by name or license #, filter by trade, city, ZIP, status, expiring soon or newly licensed.

- **URL**: https://apify.com/spriggs-data/us-contractor-license-lookup.md
- **Developed by:** [Thomas Spriggs](https://apify.com/spriggs-data) (community)
- **Categories:** Lead generation, Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.30 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 License Lookup: FL, TX, NY, WA, OR, CT, CO, MD

**Verify contractor licenses** and **build trade-contractor lead lists** from **12 official state and city license databases** in one normalized dataset, now including **Florida (about 114,000 active DBPR construction and electrical licenses)**.
Search by **contractor name** or **license number**, or list every licensed **electrician, plumber, HVAC, roofer or general contractor** in a city or ZIP code.
Find **licenses expiring soon** (renewal, bonding and insurance leads) and **newly licensed contractors** (new-business leads).
No login, no API keys, no browser automation: every record comes from a government's own open-data API (Socrata SODA) or official public-records download file, so runs are fast and cheap.

### Sources (12 official datasets)

| Key | State | Agency / dataset | What's in it |
|---|---|---|---|
| `wa-lni` | WA | Washington L\&I Contractor License Data | All construction, electrical, plumbing and elevator contractors (about 160k incl. expired), with specialty (roofing, HVAC, painting...), principal, UBI, phone. |
| `or-ccb` | OR | Oregon Construction Contractors Board, Active Licenses | About 56k active contractors with **bond company/amount and insurance company/amount + expiry dates**, county, phone. |
| `or-bcd` | OR | Oregon Building Codes Division | Electrical, plumbing, boiler and elevator trade licenses (businesses and individuals). |
| `tx-tdlr` | TX | Texas TDLR All Licenses | A/C contractors and technicians, electrical contractors, master/journeyman electricians, sign electricians, appliance installers, elevator contractors, water-well drillers. |
| `ny-registry` | NY | NY State DOL Contractor Registry | Public-work contractors with **compliance flags**: debarred, outstanding wage assessments, labor/tax or safety violations, workers' comp, MWBE. |
| `nyc-dob` | NY | NYC Department of Buildings License Info | General contractors, electrical contractors/firms, master plumbers, fire suppression, riggers, site safety etc., with business email and phone. |
| `nyc-hic` | NY | NYC DCWP Issued Licenses | Home Improvement Contractor licenses, with borough, BIN/BBL and coordinates. |
| `ct-dcp` | CT | Connecticut DCP State Licenses and Credentials | Home improvement, new home construction, major contractor, electrical, plumbing, heating/cooling, sheet metal, fire protection, elevator, glass. |
| `co-dora` | CO | Colorado DORA Professional and Occupational Licenses | Electrical contractors, master/journeyman electricians, residential wiremen, plumbing contractors, master/journeyworker/residential plumbers. |
| `md-montgomery` | MD | Montgomery County MD New Home Builders | Building contractor licenses with applicant, phone and coordinates. |
| `fl-dbpr-construction` | FL | Florida DBPR Construction Industry Licensing Board, licensee file | About 97,600 active certified and registered contractors: general, building, residential, roofing, A/C (commercial/residential/service), mechanical, plumbing, pool/spa, sheet metal, solar, underground utility, specialty (drywall, glazing, gas line, pool decking...). Qualifier name, DBA, address, county, original license date, expiry. |
| `fl-dbpr-electrical` | FL | Florida DBPR Electrical Contractors' Licensing Board, licensee file | About 16,900 active electrical contractors, electrical specialty (elevator, sign, limited energy, lighting) and alarm system contractors. |

Every record carries `sourceUrl` (the official dataset) and, where the agency has one, `verifyUrl` (the agency's own lookup page) so you can double-check.

### What you can do with it

- **Contractor license verification / due diligence:** check that a roofer, electrician or builder is licensed and active before you hire, pay or subcontract. Paste a list of names or license numbers; each result says which search it matched (`matchedQuery`).
- **Lead generation for suppliers, insurers, sureties, software and financing companies:** every active electrical contractor in Houston, every roofer in Spokane, every plumbing contractor in Denver.
- **Renewal / insurance / bonding leads:** `expiringWithinDays: 60` returns licenses about to expire, with bond and insurer details for Oregon.
- **New-business leads:** `issuedAfter: "2026-09-01"` returns contractors licensed since that date. Florida alone licensed about 1,400 new construction and electrical contractors between Sep 1 and Oct 20, 2026.
- **Pair it with permits:** look up the contractor on a building permit from our [US Building Permits API](https://apify.com/spriggs-data/us-building-permits) to see whether they are licensed, active and bonded.

### Input

| Field | What it does |
|---|---|
| `names` | Business, DBA or person names. Every word must appear in the same name field (case-insensitive; LLC/Inc/Co ignored), so `smith roofing` finds `SMITH & SONS ROOFING LLC`. |
| `licenseNumbers` | Exact license / certificate numbers (e.g. WA `ECOSTSC758NN`, CT `HIC.0631057`, TX `19400`, FL `CCC056803`). License numbers are not unique across agencies, so check `licenseState` and `licenseType`. |
| `states` / `sources` | Which datasets to search. Empty = all 12. |
| `trades` | `general`, `home_improvement`, `electrical`, `plumbing`, `hvac`, `roofing`, `elevator`, `fire_protection`, `glass_windows_siding`, `concrete_masonry`, `carpentry_finish`, `landscaping`, `excavation_demolition`, `solar`, `pool_spa`, `sign`, `lead_mold_asbestos`, `appliance`, `alarm_security`, `public_works`, `home_builder`. |
| `licenseTypeContains` | Free-text match on the license type, e.g. `Master Electrician`. |
| `cities`, `zipCodes` | Licensee business city (exact) and ZIP (5 digits or a prefix like `981`). |
| `status` | `active` (default) or `any` (include expired, suspended, revoked: useful for due diligence). |
| `expiringWithinDays` | Only licenses expiring in the next N days. |
| `issuedAfter` | Only licenses first issued / registered on or after this date (YYYY-MM-DD). Washington has no original-issue date, so its current license effective date is used (renewals included). Florida uses the original licensure date. |
| `maxItems`, `maxItemsPerSource` | Caps on records saved and charged. |

#### Example inputs

Verify a list of contractors in every state:

```json
{ "names": ["smith roofing", "arete construction"], "status": "any" }
```

All active roofing contractors in Spokane, WA:

```json
{ "states": ["WA"], "trades": ["roofing"], "cities": ["Spokane"], "maxItems": 500 }
```

Electrical licenses expiring in the next 45 days in Texas, Oregon and Connecticut:

```json
{ "states": ["TX", "OR", "CT"], "trades": ["electrical"], "expiringWithinDays": 45 }
```

Newly licensed contractors since September 1 (all sources that publish an issue date):

```json
{ "issuedAfter": "2026-09-01", "maxItemsPerSource": 200 }
```

Look up license numbers:

```json
{ "licenseNumbers": ["HIC.0631057", "ECOSTSC758NN", "CCC056803"], "status": "any" }
```

New Florida roofing contractors in Tampa licensed this year:

```json
{ "states": ["FL"], "trades": ["roofing"], "cities": ["Tampa"], "issuedAfter": "2026-01-01" }
```

### Output

One dataset item per license record, same schema for every source (fields an agency doesn't publish are `null`). Real record from Oregon CCB:

```json
{
  "sourceKey": "or-ccb",
  "agency": "Oregon Construction Contractors Board (CCB)",
  "licenseState": "OR",
  "licenseNumber": "112932",
  "licenseCode": "LBPR",
  "licenseType": "Lead Based Paint Renovation Contractor",
  "businessName": "COOPER MOUNTAIN ROOFING INC",
  "issueDate": "2024-07-24",
  "expirationDate": "2027-07-31",
  "daysUntilExpiration": 285,
  "isActive": true,
  "address": "7490 SW BRIDGEPORT RD",
  "city": "PORTLAND", "state": "OR", "zip": "97224", "county": "Clackamas",
  "phone": "5033037180",
  "trades": ["lead_mold_asbestos"],
  "verifyUrl": "https://search.ccb.state.or.us/search/",
  "sourceUrl": "https://data.oregon.gov/d/g77e-6bhs",
  "matchedQuery": "roofing"
}
```

Other fields: `personName` (principal / owner / RMI / individual licensee), `dba`, `businessType`, `status`, `effectiveDate`, `specialties`, `email` (NYC DOB), `lat`/`lon`, `bondCompany`/`bondAmount`/`insuranceCompany`/`insuranceAmount` (+ expiry dates, Oregon CCB), and `extra` with source-specific fields (WA UBI and suspension date; NY registry compliance flags; CT status reason; NYC BIN/BBL; Florida primary/secondary status, class code and county code). Florida records also carry `dataAsOf`, the date of the DBPR file they came from. A `RUN_SUMMARY` record in the key-value store lists saved/scanned counts per source.

Export as JSON, CSV, Excel, or pull it through the Apify API, Zapier, Make, n8n or the Apify MCP server for AI agents.

### Pricing

Pay per result: **$2 per 1,000 license records** on the Free plan, cheaper on paid plans, plus a tiny start fee. Filters run inside the government API, so you only pay for records you asked for. Use `maxItems` to cap any run.

### Limits and notes

- Data is exactly what the agencies publish, refreshed on each agency's own schedule (in October 2026 most datasets had been updated within the past week; Texas TDLR and NYC DCWP within the past 2–3 months). Always confirm critical decisions on the agency's own lookup page (`verifyUrl`).
- Texas TDLR publishes **no address for individual licensees and A/C contractors**, so city/ZIP filters only match Texas records that have a business or mailing address. Name and license-number search work for all of them.
- Oregon CCB is an active-only file; Oregon BCD is active-only too. Montgomery County MD has no status column, so "active" means "not expired".
- **Florida:** DBPR publishes its licensee files as free public-records downloads (Chapter 119, Florida Statutes), refreshed by DBPR. DBPR's download server refuses cloud IP addresses, so when a run can't reach it directly the actor reads a copy of the same official file that we refresh from DBPR regularly; each Florida record shows the file date in `dataAsOf`. In Florida the license belongs to the individual qualifier (`personName`); the company is in `businessName`/`dba` when DBPR has one. Status `Inactive (license current, not practicing)` means the license is current but the holder can't contract right now; it counts as not active. Florida files exclude null-and-void and delinquent licenses, so `status: any` can't find those.
- More states (IL, CA, AZ...) are planned where the state publishes an official bulk dataset. Request one in the Issues tab.
- Read-only public records; no personal data beyond what the licensing agency publishes.

### FAQ

**Is this legal?** Yes. Every source is an official government open-data portal with a public API intended for reuse.

**Why not California CSLB?** It doesn't publish a bulk open-data API; scraping its lookup site is slower and fragile. We add states only when there's an official dataset or official public-records file (that's how Florida DBPR was added in October 2026).

**Can I monitor a list of contractors?** Yes: save your input as a Task and schedule it daily or weekly. Compare `status` and `expirationDate` between runs.

### Related Spriggs Data actors

- **[US Building Permits API: Construction, Roofing & Solar Leads](https://apify.com/spriggs-data/us-building-permits)**: newly issued building permits from 35 official city and county portals (Chicago, NYC, LA, Boston, Philadelphia, Austin, Seattle...), with contractor names where the city publishes them. Check those contractors here.
- **[Bluesky Scraper: Posts, Profiles, Followers & Likers](https://apify.com/spriggs-data/bluesky-scraper)**: search Bluesky posts and export followers, likers and replies. No login.

*Built and maintained by Spriggs Data.*

# Actor input Schema

## `names` (type: `array`):

Search by business, DBA or principal/owner name. Every word must appear (case-insensitive; LLC/Inc/Co are ignored), so 'smith roofing' finds 'SMITH & SONS ROOFING LLC'. One search per name; each result carries the matching name in matchedQuery. Leave empty to list all licenses matching the other filters.

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

Exact license / certificate numbers to verify (e.g. WA 'ECOSTSC758NN', CT 'HIC.0631057', TX '19400', FL 'CCC056803').

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

Which state datasets to search. Leave empty (and Sources empty) to search all states.

## `sources` (type: `array`):

Pick individual datasets instead of (or in addition to) whole states.

## `trades` (type: `array`):

Only licenses in these trades (classified from the official license type / specialty).

## `licenseTypeContains` (type: `array`):

Free-text match on the license type, e.g. 'Master Electrician' or 'Residential General'.

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

Business city of the licensee (exact name, case-insensitive), e.g. 'Seattle', 'Houston'.

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

Business ZIP (5 digits, or a 3-digit prefix like '981').

## `status` (type: `string`):

Active only, or every status (useful for due-diligence checks).

## `expiringWithinDays` (type: `integer`):

Only licenses whose expiration date is in the next N days: renewal / insurance / bonding leads.

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

YYYY-MM-DD. Only licenses first issued / registered on or after this date: new-business leads. Sources without an issue date are skipped.

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

Hard cap on records saved (and charged) per run.

## `maxItemsPerSource` (type: `integer`):

Cap per dataset, so one big state does not use the whole budget.

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

Adds the untouched original row under 'raw'.

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

Optional free token from any Socrata portal for higher rate limits. Not required.

## Actor input object example

```json
{
  "names": [
    "electric"
  ],
  "states": [
    "WA",
    "OR",
    "TX"
  ],
  "status": "active",
  "maxItems": 30,
  "maxItemsPerSource": 10,
  "includeRaw": false
}
```

# Actor output Schema

## `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 = {
    "names": [
        "electric"
    ],
    "states": [
        "WA",
        "OR",
        "TX"
    ],
    "maxItems": 30,
    "maxItemsPerSource": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("spriggs-data/us-contractor-license-lookup").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 = {
    "names": ["electric"],
    "states": [
        "WA",
        "OR",
        "TX",
    ],
    "maxItems": 30,
    "maxItemsPerSource": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("spriggs-data/us-contractor-license-lookup").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 '{
  "names": [
    "electric"
  ],
  "states": [
    "WA",
    "OR",
    "TX"
  ],
  "maxItems": 30,
  "maxItemsPerSource": 10
}' |
apify call spriggs-data/us-contractor-license-lookup --silent --output-dataset

```

## MCP server setup

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

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/MoUW2HtAYZcfvZDQU/builds/n0QeqSnA7bI2enCMC/openapi.json
