How-to
How to run Oklahoma Contractor License Lookup & List Scraper (CIB)
Step-by-step: the exact input, what each field does, and the rows that come back from the Oklahoma Construction Industries Board.
You want Oklahoma’s licensed electricians, plumbers or HVAC contractors as a table, or you need to check that a list of names really hold the licence they claim. The Construction Industries Board publishes all of it on one free search page, and for a single name that page is the right tool. For a list it gets slow: the board shows one trade per search, has no export button, and the plumbing trade alone comes back as 11,311 rows on a single web page (October 30, 2026).
What you’ll need
Nothing but an Apify account. Exports read a stored copy of the board’s roster, and name or number lookups search the board live from the run itself, so there is no API key, proxy or CAPTCHA solver to set up, and nothing extra to pay for.
Step 1 — Open the actor
Open Oklahoma Contractor License Lookup & List Scraper (CIB) on the Apify Store and press Try for free. The actor’s own page on this site lists its live health and pricing.
Step 2 — Fill in the input
| Field | Type | Required | What it does |
|---|---|---|---|
mode | string | no | export: no names, just filters; returns the whole matching list. lookup / verify: put person names (matched if contained in the person name) or licence numbers (exact) in… (default auto) |
query | string | no | A person’s name (or listing number) to look up live. Kept alongside ‘queries’ for saved tasks. |
queries | array | no | A person’s name (or listing number) to look up live. Several values in one run; combined with ‘query’. (default []) |
license_class | string | no | Only listings in this license_class. Kept alongside ‘license_classes’ for saved tasks. |
license_classes | array | no | Only listings in this license_class. Several values in one run; combined with ‘license_class’. (default []) |
status | string | no | Only listings in this status. Kept alongside ‘statuses’ for saved tasks. |
statuses | array | no | Only listings in this status. Several values in one run; combined with ‘status’. (default []) |
city | string | no | Only listings in this city. Kept alongside ‘cities’ for saved tasks. |
cities | array | no | Only listings in this city. Several values in one run; combined with ‘city’. (default []) |
categories | array | no | Only rows from this trade (one or more). Available: building-inspector, electrical, electrical-apprentice, home-inspector, mechanical, mechanical-apprentice, plumbing,… (default []) |
maxResults | integer | no | Per query in lookup mode; per run in export mode. (default 500) |
Two fields decide almost everything. status is the first: 204,195 of the 261,702 licences on the
board were Expired on October 30, 2026, most of them old apprentice registrations, so an export with no
status filter is mostly history. Set status to Active unless history is what you want. The second
is license_class, which takes Contractor, Journeyman, Apprentice or Inspector. The board licenses
people, not companies, so a contractor here is a person holding a contractor licence.
A working input:
{
"categories": [
"plumbing"
],
"license_class": "Contractor",
"status": "Active",
"maxResults": 500
}
For a lookup instead, set mode to lookup and put names (Smith, John) or licence numbers
(00196169) in queries. The board needs at least three letters of a last name.
Step 3 — Run it
Press Start. Rows are pushed to the dataset as they’re found, so the run log fills in as it works.
An export reads the stored copy and finishes quickly: the first customer run returned its 3 rows in
10 seconds, and a local test read all 1,692 active plumbing contractors from the copy in 1.2 seconds. A lookup
is slower, about 40 seconds per name or number, because each one is searched in all nine of the
board’s trades and the board limits how fast it can be searched. An empty export almost always means a
filter value is spelled differently from the board’s own words (Pending - CE Hours, not pending);
an empty lookup returns a free notice saying the board had no match.
Step 4 — Read the output
Each run returns a labelled table, not raw JSON:
Every row looks like this:
{
"listing_id": "00192177",
"name": "ALDER, ALEX A",
"city": "WILBURTON",
"country": "US",
"category": "Plumbing",
"categories": [
"Plumbing"
],
"source": "live",
"source_url": "https://okcibv7prod.glsuite.us/GLSuiteWeb/Clients/OKCIB/Public/LicenseeSearch/Posting.aspx?EntityID=1693095&LicenseID=1436877",
"extras": {
"license_type": "Plumbing Journeyman License",
"license_class": "Journeyman",
"status": "Active",
"citation": "No"
}
}
| Field | Example value | Meaning |
|---|---|---|
name | ALDER, ALEX A | Licence holder, as the board prints it: LAST, FIRST MIDDLE (always a person) |
listing_id | 00192177 | Licence number exactly as the board prints it, leading zeros included; not unique on its own |
extras.license_type | — | Licence type, e.g. Electrical Contractor License, Plumbing Journeyman License, Mechanical Apprentice Registration |
extras.license_class | — | Contractor, Journeyman, Apprentice or Inspector |
extras.status | — | Licence status: Active, Expired, Inactive, Pending - CE Hours, Tax, Withdrawn, Denied, Deceased, Completed |
extras.citation | — | Yes or No: whether the board shows a citation on the licence |
category | Plumbing | Trade: Electrical, Mechanical, Plumbing, their Apprentice trades, or an inspector trade |
city | WILBURTON | The holder’s city as the board lists it (no street, state or ZIP is published) |
Most people come for extras.status and listing_id. Treat the number with care: the board gives a
person one number across their licences, and old six-digit numbers were reused, so one 2026-10-30
search for 003019 returned five licences. The source_url is the board’s own verification page for
that exact licence, which is the safer thing to keep. City is the only place field, and 617 of the
261,702 rows have none.
Step 5 — Export it
Open the Dataset tab and export to CSV, JSON, or Excel — or pull the same rows from the API, which is what you want if this is going to run on a schedule.
What it costs
$0.004 per licence returned, and notices (no match, unknown trade, stale copy) are free. The 1,692 active plumbing contractors cost $6.77; a lookup that matches one person costs $0.004 per licence found. Apify bills platform usage separately under your own plan.
Where the data comes from
This reads the Oklahoma Construction Industries Board’s public licence search. Every night a canary runs this actor against that live source and diffs the result against a frozen fixture — what “verified” means.
The search sits behind a browser check, so a plain download tool gets a 403 instead of the page, and it answers one trade at a time with no filter for status, licence class or city. Name searches also show one licence per person unless a trade is chosen, which is why each lookup here runs once per trade.
See it used
Oklahoma Active Plumbing Contractors (CIB) builds the statewide list of 1,692 active plumbing contractors and says when the free search is enough instead.
Roofers are not in this board’s trade search; they register separately, and the Oklahoma roofing contractor directory covers them with phone and street address, which this board does not publish for trade licences.
Last updated 2026-10-30