How-to
How to run Arkansas Contractor Directory & Leads Scraper (ACLB)
Step-by-step: the exact input, what each field does, and the rows that come back from AR ACLB.
You sell to contractors in Arkansas and you want a call list for one county and one trade: every licensed roofer in Pulaski County, say, with a phone number and an email. The Arkansas Contractors Licensing Board (ACLB) has all of it, split across two places. Its advanced search filters by county and by any of 141 trades, but shows no email and has no export button. Its free nightly roster, latestroster.csv, has email for 12,655 of the 12,935 Arkansas-address rows, but it is one 18,290-row statewide file whose trade column you cannot split cleanly. This actor runs the search and joins each result to the roster, so one run returns the filtered list with the contact columns attached.
What you’ll need
Nothing but an Apify account. The actor talks to AR ACLB directly.
No API key, no proxy and no CAPTCHA. ACLB’s site at aclb2.arkansas.gov answers plain requests, and the proxy setting ships switched off. The only cost is the $0.002 per contractor returned.
Step 1 — Open the actor
Open Arkansas Contractor Directory & Leads Scraper (ACLB) 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 |
|---|---|---|---|
listOptionsOnly | boolean | no | If true, skip the scrape and return the 75 Arkansas counties plus every trade the Arkansas Contractors Licensing Board (ACLB) licenses, with its code. Free, not charged. Use it… |
trade | string | no | An ACLB trade (specialty or classification), by name or code, e.g. ‘Roofing’, ‘Plumbing’, ‘Residential Builder’, ‘s_1899’. A word from the name works too: ‘roof’ finds Roofing… |
trades | array | no | Several trades in ONE run, e.g. Roofing and Plumbing and Concrete. Combined with ‘Trade’ if you fill both. Every trade is searched in every county, and a contractor holding two… (default []) |
county | string | no | Arkansas county, e.g. ‘Pulaski’, ‘Benton County’, ‘saint francis’. Case, punctuation and a trailing ‘County’ do not matter. Leave it empty with a trade set to search all of… |
counties | array | no | Several counties in ONE run, e.g. Pulaski and Faulkner and Saline. Combined with ‘County’ if you fill both. (default []) |
validOnly | boolean | no | Return only contractors whose licence ACLB lists as valid (a few show ‘Call ACLB to confirm’). Turn off to include expired and invalid licences too. (default True) |
workType | string | no | Commercial licences, residential licences, or both. (default all) |
maxResults | integer | no | Cap on the contractors returned PER county + trade search, not per run, so adding counties can never silently truncate the ones later in the list. Leave empty to return every… |
Two fields decide the list. trade takes a trade name, a word from one, or an ACLB code: “Roofing”, “roof” and “s_1899” all resolve to the same trade, and “roof” deliberately does not match Fireproofing or Waterproofing. If you are unsure of a name, run once with listOptionsOnly switched on; it returns all 75 counties and 141 trades for free. county accepts “Pulaski”, “pulaski county” or “Saint Francis”. Leave county empty and set a trade to search the whole state; leave trade empty to get every contractor in the county.
A working input:
{
"county": "Pulaski",
"trade": "Roofing"
}
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.
The input above returned 129 contractors when we ran it on 2026-09-28, and the scraping itself took 6.7 seconds (timed outside Apify; a platform run adds container start-up on top). A whole county with no trade filter is bigger: Benton County came back with 1,387 contractors in 9.5 seconds of scraping. If a run returns nothing but county and trade names, the actor did not recognise one of your inputs and the log line says which; those option rows are free. If ACLB itself does not answer, you get one free row with a notice saying so, never an empty dataset that looks like “no contractors here”.
Step 4 — Read the output
Each run returns a labelled table, not raw JSON:
Every row looks like this — a real row from a real run:
{
"business_name": "KETCHER AND COMPANY, INC.",
"email": "kristy@ketcherandco.com",
"phone": "501-372-5216",
"fax": "501-372-0949",
"address": "PO BOX 5271",
"city": "NORTH LITTLE ROCK",
"county": "Pulaski",
"zip_code": "72119",
"state": "AR",
"officers": "President: Henry Ketcher, Vice President: Hank Ketcher III, President: Henry H Ketcher III",
"dba": null,
"business_structure": "Corporation",
"license_type": "Commercial",
"status": "Valid",
"expiration_date": "06/30/2027",
"classifications": "Roofing, Roof Decks, Roofing Sheet Metal",
"bid_limit": "UNLIMITED",
"aclb_id": "2247",
"license_number": "0006000627",
"requested_county": "Pulaski",
"requested_trade": "Roofing, Roof Decks, Roofing Sheet Metal",
"source_url": "http://aclb2.arkansas.gov/clbsearch.php"
}
| Field | Example value | Meaning |
|---|---|---|
business_name | KETCHER AND COMPANY, INC. | Contractor name as licensed by ACLB |
email | kristy@ketcherandco.com | Email on file in ACLB’s nightly roster (null when ACLB has none on file) |
phone | 501-372-5216 | Phone number on file with ACLB |
fax | 501-372-0949 | Fax number, when listed |
address | PO BOX 5271 | Mailing street address (often a PO box) |
city | NORTH LITTLE ROCK | Mailing city |
county | Pulaski | Arkansas county of the mailing address — the canonical name when you searched by county, ACLB’s own spelling on a statewide search |
zip_code | 72119 | Mailing ZIP code |
Most people come for email and phone. In the Pulaski roofing run, 117 of 129 rows had an email and all 129 had a phone. When email is null, ACLB has no email on file for that firm, or the firm was missing from that night’s roster. Two other quirks come from ACLB itself. The address is the mailing address, and 16 of those 129 roofers list a PO box. For residential licences, license_number holds only a month-and-year suffix such as “1226”, so use aclb_id as the identifier.
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.002 per contractor returned, plus Apify’s own platform usage. The Pulaski roofing run above is 129 rows, so $0.26. The Benton and Washington residential-builder list is 664 rows, so $1.33. Discovery Mode, unrecognised inputs and notice rows cost nothing. A contractor who matches two of your searches is returned and charged once.
Where the data comes from
This reads AR ACLB directly. The target is Legacy PHP - the ACLB advanced-search form POST (County + specialty code) returning one unpaged results table. No hidden state, no tokens. Every night a canary runs this actor against that live source and diffs the result against a frozen fixture — what “verified” means.
ACLB’s County field is a loose text match across every state’s licensees, so a search for “Washington” also returns firms in Washington County, Oregon; the actor keeps only Arkansas addresses in exactly the county you asked for. The same county is spelled three ways in ACLB’s records (73 “St Francis”, 3 “Saint Francis”, 1 “St. Francis”), and the actor merges them. Email and officers come from the nightly roster, matched by ACLB ID; if you only ever want the whole state once, download that file yourself, because it is free.
See it used
Build a Pulaski County Roofing Contractor List walks through one county and one trade, 129 roofers, for a materials rep. List Residential Builders in Northwest Arkansas runs two counties in one go and gets 664 builders.
If you already have a contractor’s name or licence number and only need to check that one licence, Arkansas Contractor License Lookup & Verify is the smaller tool. For the same trade-by-county list in California, use California Contractor Directory by Trade & County.
Last updated 2026-09-28