# Ohio Contractor License Lookup: HVAC, Electrical, Plumbing (`spriggs-data/ohio-contractor-license-lookup`) Actor

Look up and export Ohio OCILB commercial contractor licenses from the state's own eLicense roster, current to the day: ~12,400 electrical, HVAC, plumbing, hydronics & refrigeration contractors with qualifier name, company, address, county, phone. Filter by trade, county, city, ZIP or expiring.

- **URL**: https://apify.com/spriggs-data/ohio-contractor-license-lookup.md
- **Developed by:** [Thomas Spriggs](https://apify.com/spriggs-data) (community)
- **Categories:** Lead generation, Real estate
- **Security:** Limited permissions
- **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

## Ohio Contractor License Lookup (OCILB): HVAC, Electrical & Plumbing Contractors

Look up, verify and export **Ohio commercial contractor licenses** straight from the **Ohio Construction Industry Licensing Board (OCILB)'s own eLicense roster**, current to the day: about **12,400 active licenses** in the 5 trades Ohio licenses at state level: **electrical (EL), HVAC (HV), plumbing (PL), hydronics (HY) and refrigeration (RE)**. Each record has the **qualifying individual's name**, company, address, **county**, **phone** (about two thirds of records), email (a few percent), effective and expiration dates and an "in renewal" flag.

- **Verify** contractors by license number (`HV.10704`) or by company or qualifier name, in bulk.
- **Export lead lists**: every licensed HVAC contractor in Franklin County, every electrical contractor in Cleveland, every plumber in a ZIP range, with the qualifier's name and phone.
- **Renewal, continuing-education, insurance and bonding leads**: licenses expiring in the next N days.

No login, no browser, no CAPTCHA: the actor generates OCILB's public roster (the same *Generate Roster → CSV* download anyone can use on the Ohio eLicense Center) at run time, so a statewide run takes a few seconds and costs a fraction of a cent in compute.

### Input

| Field | What it does |
|---|---|
| `names` | Company or qualifying-individual names. Every word must appear in the same name (case-insensitive; LLC/Inc/Co ignored). |
| `licenseNumbers` | OCILB license numbers to verify, e.g. `HV.10704`, `EL.12345`. Numbers that match nothing are listed in the run summary (`licenseNumbersNotFound`). |
| `trades` | `electrical`, `hvac` (HV, HY, RE) and `plumbing` (PL, HY). |
| `licenseTypeContains` | License type codes or names: `EL`, `HV`, `PL`, `HY`, `RE`, `Refrigeration`. |
| `counties`, `cities`, `zipCodes` | Company-address county (`Franklin`, `Cuyahoga County`), city (exact) and ZIP (5 digits or a prefix like `441`). |
| `expiringWithinDays` | Only licenses expiring in the next N days. |
| `maxItems` | Cap on records saved and charged (default 100). |

#### Examples

Every licensed HVAC contractor in Franklin County (Columbus area):

```json
{ "trades": ["hvac"], "counties": ["Franklin"], "maxItems": 2000 }
```

Electrical contractors in Cleveland:

```json
{ "trades": ["electrical"], "cities": ["Cleveland"] }
```

Verify a list of license numbers:

```json
{ "licenseNumbers": ["HV.10704", "EL.12345"] }
```

Plumbing contractors in Hamilton County (Cincinnati) whose license expires within 90 days:

```json
{ "trades": ["plumbing"], "counties": ["Hamilton"], "expiringWithinDays": 90 }
```

### Output

One record per license. Real record (October 2026):

```json
{
  "licenseNumber": "HV.10704",
  "licenseCode": "HV",
  "licenseType": "HVAC Contractor",
  "businessName": "DOOLEY HEATING & AIR CONDITIONING",
  "personName": "BRIAN P DOOLEY",
  "status": "Active In Renewal",
  "effectiveDate": "2026-01-01",
  "expirationDate": "2026-12-31",
  "daysUntilExpiration": 64,
  "address": "2010 Zettler Rd", "city": "Columbus", "state": "OH", "zip": "43232-3834", "county": "Franklin",
  "phone": "6142789944",
  "trades": ["hvac"],
  "extra": { "licenseeState": "OH", "licenseeCounty": "Franklin", "inRenewal": true },
  "dataAsOf": "2026-10-28",
  "verifyUrl": "https://elicense4.com.ohio.gov/Lookup/LicenseLookup.aspx"
}
```

`personName` is the licensed qualifying individual for the company. A `RUN_SUMMARY` record in the key-value store shows how many roster rows were scanned and saved and any license numbers that weren't found.

Export as JSON, CSV or Excel, or use it from the Apify API, Zapier, Make, n8n or the Apify MCP server for AI agents. Save an input as a Task and schedule it to catch licenses about to expire every week.

### 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 before anything is saved, so you only pay for the records you asked for. `maxItems` caps every run.

### Data and limits

- **Source:** Ohio eLicense Center, OCILB roster download (Ohio public record, free). Pulled live on every run; `dataAsOf` is the run date. A run stops with an error rather than returning a partial roster if OCILB's download comes back truncated.
- **Ohio licenses only these 5 commercial trades at state level.** Residential contractors, roofers, general contractors and home-improvement contractors are registered by cities and counties, not OCILB, so they aren't in this data.
- The roster lists **active licenses only** (including licenses in renewal) and has no original issue date, so there's no "newly licensed since" filter. Check `verifyUrl` (Ohio's own lookup) for expired licenses and disciplinary history.
- Names and addresses are exactly as OCILB publishes them. This is public licensing data; use it in line with Ohio and US law (including telemarketing and anti-spam rules).
- Not affiliated with or endorsed by OCILB or the State of Ohio.

### Need other states?

**[US Contractor License Lookup](https://apify.com/spriggs-data/us-contractor-license-lookup)** searches 14 official databases in one run: Ohio plus California CSLB, Florida DBPR, Texas TDLR, Washington L\&I, Oregon CCB/BCD, New York, NYC, Connecticut, Colorado and Maryland. For California only, with owner/officer names and bonds, see **[California Contractor License Lookup (CSLB)](https://apify.com/spriggs-data/california-contractor-license-lookup)**. For Florida only, see **[Florida Contractor License Lookup (DBPR): Roofing, HVAC, Pool](https://apify.com/spriggs-data/florida-contractor-license-lookup)**.

### Related Spriggs Data actors

- **[US Building Permits API: Construction, Roofing & Solar Leads](https://apify.com/spriggs-data/us-building-permits)**: new building permits from 42 official city and county portals, with contractor names to check here.
- **[Bluesky Scraper](https://apify.com/spriggs-data/bluesky-scraper)** and **[Mastodon & Lemmy Scraper](https://apify.com/spriggs-data/fediverse-scraper)**: public social posts and profiles, no login.

*Built and maintained by Spriggs Data.*

# Actor input Schema

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

Company or qualifying-individual names. Every word must appear in the same name (case-insensitive; LLC/Inc/Co ignored): 'dooley heating' finds 'DOOLEY HEATING & AIR CONDITIONING'. Leave empty to list contractors by the filters below.

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

OCILB license numbers to verify, e.g. 'HV.10704', 'EL.12345' (the prefix is the trade: EL, HV, PL, HY, RE).

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

Only contractors licensed in these trades. Ohio licenses 5 commercial trades at state level: electrical (EL), HVAC (HV), plumbing (PL), hydronics (HY, counted as HVAC and plumbing) and refrigeration (RE, counted as HVAC).

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

OCILB license type codes or names, e.g. 'EL', 'HV', 'PL', 'HY', 'RE', 'Refrigeration'. Matches any one of them.

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

Company city (exact name, case-insensitive), e.g. 'Columbus', 'Cleveland', 'Cincinnati'.

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

Ohio county of the company address, e.g. 'Franklin', 'Cuyahoga', 'Hamilton'.

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

Company ZIP (5 digits, or a prefix like '432').

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

Only licenses whose expiration date is in the next N days: renewal, CE-course, insurance and bonding leads.

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

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

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

Adds the untouched original roster row under 'raw'.

## Actor input object example

```json
{
  "names": [],
  "trades": [
    "hvac"
  ],
  "counties": [
    "Franklin"
  ],
  "maxItems": 30,
  "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": [],
    "trades": [
        "hvac"
    ],
    "counties": [
        "Franklin"
    ],
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("spriggs-data/ohio-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": [],
    "trades": ["hvac"],
    "counties": ["Franklin"],
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("spriggs-data/ohio-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": [],
  "trades": [
    "hvac"
  ],
  "counties": [
    "Franklin"
  ],
  "maxItems": 30
}' |
apify call spriggs-data/ohio-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/ohio-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/wMukr4tcWefChzpTq/builds/Q3pgYUj412frsIRrb/openapi.json
