Virginia Contractor Directory & Leads Scraper (DPOR)
Pricing
$0.002 / contractor record
Virginia Contractor Directory & Leads Scraper (DPOR)
Every licensed Virginia contractor in a county, city or ZIP, by trade — business name, email, mailing address, licence class, trades and expiry — from DPOR's Board for Contractors licence lists.
Pricing
$0.002 / contractor record
Rating
0.0
(0)
Developer
ScrapeBench
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Pain points
- DPOR publishes its contractor licences as free tab-delimited files, but one per licence class and statewide (53,779 rows across six files on 2026-10-06), with no county column, so a county list means geocoding every ZIP yourself.
- Trades are bare codes in one space-separated column (RBC, H/H, ROC, HIC — 57 of them), so finding every roofer means knowing that roofing is 'ROC' and splitting the column first.
- The certificate number repeats across licence types (53,302 distinct numbers over 53,779 rows), a stray tab inside the business name shifts every later column on 22 rows, and 10,556 rows have an out-of-state address.
What we solve
- Pick a county, independent city, mailing city or ZIP and a trade by name, and get every licensed contractor that matches in one run, with email and mailing address, ready for a CRM.
- Reads DPOR's own licence files, repairs the shifted rows, labels every trade code with its name from the Board for Contractors regulations, and keeps Virginia addresses only unless you ask otherwise.
- Identifies each licence by DPOR occupation plus certificate number, so two licences that share a certificate number are never merged.
Summary
Build a contractor prospect list for any part of Virginia in one run. Choose a county or independent city (Fairfax County, Richmond city, Loudoun), a mailing city or a ZIP code, and a trade by name — Roofing, Electrical, Plumbing, HVAC, Home Improvement, Residential Building, any trade DPOR's Board for Contractors licenses — and get back every contractor that matches: business or individual name, email, mailing address, city, ZIP, county, licence class (A, B or C), every trade the licence covers with its name, certification date and expiry date. The data is DPOR's own licence lists, downloaded fresh on every run. Leave the place empty to search a trade across all of Virginia, or leave the trade empty for every contractor in the place. Pay only per contractor returned.
Who it's for
- Sales teams selling tools, materials, equipment or software to contractors in a Virginia territory
- Insurance and bonding agents prospecting for contractor accounts by county or ZIP
- General contractors building a subcontractor shortlist by trade before bidding
- Market researchers sizing licensed trade coverage across Virginia counties and cities
How to use
Set the input, run the actor, and collect results from the run's dataset (export to JSON/CSV/Excel, or pull via the Apify API). Example input:
{"county": "Fairfax County","trade": "Roofing"}
See Inputs below for every available field.
What you get
One row per record:
| Field | Description |
|---|---|
business_name | Business name on the licence (null for a licence held by an individual) |
individual_name | Individual licensee's name, when the licence is held by a person |
email | Email on file with DPOR (null when none is on file) |
address | Mailing street address, including suite and PO box |
city | Mailing city |
zip_code | Mailing ZIP code (ZIP+4 when DPOR has it) |
address_state | State of the mailing address |
county | Virginia county or independent city, derived from the ZIP — approximate, see county_method |
county_method | zip_single (the ZIP lies in one county), zip_majority (the county holding most of the ZIP's land), unmapped (a PO-box ZIP with no area), or out_of_state |
license_class | A, B or C (or RETR for a residential tradesman) |
license_type | Class A Contractor, Class B Contractor, Class C Contractor or Residential Tradesman |
specialties | Every trade code on the licence, e.g. ROC, HIC, ELE |
specialty_labels | The same trades by name, e.g. Roofing, Home Improvement, Electrical |
certification_date | Date the licence was first issued (MM/DD/YYYY) |
expiration_date | Licence expiry date (MM/DD/YYYY) |
license_number | DPOR certificate number |
board_occupation | DPOR board and occupation code (2705 = contractor, 2701 = legacy Class A, 2709 = residential tradesman); with license_number it identifies the licence |
phone | Always null: DPOR does not publish a phone number |
requested_county | The county search that returned the row |
requested_trade | The trade search that returned the row |
source_url | The DPOR licence file the row came from |
Sample:
{"business_name": "FSR ROOFING CONTRACTOR INC","individual_name": null,"email": "fsrconstruction4u@gmail.com","address": "8300 OLD COURTHOUSE RD","city": "VIENNA","zip_code": "22182","address_state": "VA","county": "Fairfax County","county_method": "zip_single","license_class": "B","license_type": "Class B Contractor","specialties": ["ROC","HIC"],"specialty_labels": ["Roofing","Home Improvement"],"certification_date": "03/09/2004","expiration_date": "12/31/2027","license_number": "083272","board_occupation": "2705","phone": null,"requested_county": "Fairfax County","requested_trade": "Roofing","source_url": "https://www.dpor.virginia.gov/sites/default/files/Records%20and%20Documents/Regulant%20List/2705b__crnt.txt"}
Inputs
| Field | Required | Type | Default | Description |
|---|---|---|---|---|
listOptionsOnly | no | boolean | false | If true, skip the download and return Virginia's 95 counties and 38 independent cities plus every trade DPOR's Board for Contractors licenses, with its code. Free, not charged. |
trade | no | string | "Roofing" | A DPOR trade, by name or code, e.g. 'Roofing', 'Electrical', 'HVAC', 'Home Improvement', 'ROC'. A word from the name works too: 'roof' finds Roofing. Leave it empty to get every trade in the place. |
trades | no | array | ["Roofing", "Electrical"] | Several trades in ONE run, e.g. Roofing and Electrical. Combined with 'Trade' if you fill both. A contractor holding two of them is returned (and billed) once. |
county | no | string | "Fairfax County" | A Virginia county or independent city, e.g. 'Fairfax County', 'Richmond city', 'City of Fairfax', 'Loudoun'. Fairfax, Franklin, Richmond and Roanoke are each both a county and a city, so say which. APPROXIMATE: DPOR records no county, so it is derived from the mailing ZIP (each row's county_method says how). For an exact match use City or ZIP. An unrecognised name returns the free county and trade lists instead of failing. |
counties | no | array | [] | Several counties or independent cities in ONE run. Combined with 'County' if you fill both. |
city | no | string | — | The city on the licence's mailing address, e.g. 'Vienna', 'Virginia Beach'. Exact match, case-insensitive. |
cities | no | array | [] | Several mailing cities in ONE run, each searched separately. |
zip | no | string | — | A 5-digit ZIP code, matched exactly against the licence's mailing ZIP, e.g. '22182'. |
zips | no | array | [] | Several ZIP codes in ONE run, each searched separately. |
licenseClasses | no | array | ["A", "B", "C"] | Which DPOR licence classes to include: A, B, C, and RETR (residential tradesman). Only those files are downloaded. Default: A, B and C. |
inVirginiaOnly | no | boolean | true | Keep only licences with a Virginia mailing address. About 20% of DPOR's licences have an out-of-state address; turn this off to include them on a statewide trade search. |
maxResults | no | integer | — | Cap on the contractors returned PER place + trade search, not per run, so adding places can never silently truncate the ones later in the list. Leave empty to return every match. |
proxyConfiguration | no | object | {"useApifyProxy": false} | Optional. DPOR answers direct requests; enable a proxy only if runs come back with a 'blocked' notice. |
Pricing (Pay Per Event)
You pay per result (dataset-item) — no charge for empty runs. Example: 118 Fairfax County roofing contractors at $0.002/result ≈ $0.24.
Discovery Mode and unrecognised inputs return the free county and trade lists. Apify platform usage is billed separately.
Use cases
- Territory prospecting — pull every licensed roofer, electrician or home-improvement contractor in Fairfax County, Loudoun and Prince William and load the email list into your CRM.
- ZIP-level campaigns — list every licensed contractor in the ZIP codes your branch serves, an exact match on the mailing ZIP.
- Subcontractor sourcing — list every Class A or B contractor licensed for a trade near a project before you send bid invitations.
- List refresh — re-run monthly and compare expiry dates to spot licences that lapsed or renewed.
Why this actor
- Email on 94 of 118 Fairfax County roofers and 1,764 of 2,178 rows across six county-and-trade searches (measured 2026-10-06); 41,484 of DPOR's 53,779 licences carry one.
- Straight from DPOR's Board for Contractors licence lists, downloaded fresh on every run.
- Trades by name: every DPOR code is labelled from the Board for Contractors regulations, so 'Roofing' finds ROC and 'Electrical' finds ELE.
- City and ZIP filters are exact matches on the licence's mailing address; county is derived from the ZIP and every row says how.
- Pay per contractor returned; the county and trade lists are free.
Limitations & updates
Covers licences in DPOR's Board for Contractors regulant lists (current licences only). DPOR publishes no phone number. County is derived from the mailing ZIP and is approximate: a ZIP that crosses a county line is assigned to the county holding most of its land, PO-box ZIPs have no county, and a few small independent cities cannot be reached by a county search at all (the run says which ZIPs to use instead). City and ZIP filters match the mailing address exactly; a firm appears only under its mailing address, not where it works. Email is DPOR's own record and is missing on about a quarter of licences. If DPOR does not serve a file, the run returns a free row saying so instead of an empty dataset.
FAQ
Where does the data come from?
Virginia DPOR's public regulant lists — one tab-delimited file per licence class (Class A, B, C, legacy Class A, temporary and residential tradesman), published at dpor.virginia.gov/RegulantLists. They list current licences and were last refreshed 2026-10-05 when we checked. This actor downloads only the classes your run needs.
Is there a phone number?
No. DPOR's licence lists publish no phone number for any licence, so the phone field is always null. Email is on 41,484 of 53,779 licences (77%, 2026-10-06), and the mailing address and ZIP on every one.
How accurate is the county?
Approximate. DPOR records no county, so it is derived from the mailing ZIP with the Census Bureau's 2020 ZIP-to-county file. Of 43,223 Virginia-address licences, 24,189 have a ZIP that lies in one county (county_method zip_single), 18,652 a ZIP that crosses a county line, where we use the county holding most of the ZIP (zip_majority), and 382 a PO-box ZIP with no area (unmapped, never matched by a county search). If you need precision, use the city or ZIP filter, which are exact.
Why does 'Fairfax' not work as a county?
Fairfax, Franklin, Richmond and Roanoke are each both a county and an independent city in Virginia. Say 'Fairfax County' or 'Fairfax city' (or 'City of Fairfax'); a bare name returns the free county list rather than guessing. Some small independent cities, Fairfax city among them, cover no ZIP's majority, so a county search for them returns a free row naming the ZIPs to search instead.
How many contractors does a search return?
Counted 2026-10-06, all three classes: Fairfax County roofing 118, electrical 451, home improvement 1,575; Richmond city roofing 13, electrical 41, home improvement 144.
How do I name a trade?
By name ('Roofing', 'Electrical', 'HVAC', 'Home Improvement'), by a word from the name ('roof' finds Roofing), or by DPOR code ('ROC', 'H/H'). Turn on Discovery Mode to get every trade with its code, free.
What about out-of-state contractors?
10,556 of DPOR's licences have a mailing address outside Virginia. They are left out by default; turn off 'Virginia addresses only' to include them on a statewide trade search.
How am I charged?
One event per contractor returned ($0.002). A licence that matches two of your searches is returned and charged once. The county and trade lists, and any row explaining a source or input problem, are free.
Which actor to choose
Part of the contractor-data suite — pick the one that fits your goal:
- Virginia Contractor License Lookup (DPOR Bulk) — You have a contractor's name and want to check that one Virginia licence.
- California Contractor Directory by Trade & County (CSLB) — You need the same trade-by-county contractor list for California.
- Arkansas Contractor Directory & Leads Scraper (ACLB) — You need the same county-level directory for Arkansas, with phone numbers.
- Texas Contractor Directory & Leads Scraper (TDLR) — You need a county-scoped roster of Texas TDLR-licensed contractors.
- Alabama Commercial Contractor Directory & Leads (LBGC) — You need commercial contractors in an Alabama county, with phone and fax.
Guides & use cases
Written up on scrapebench.dev — the bench that runs and verifies this actor against the live source every night:
- How-to: How to run Virginia Contractor Directory & Leads Scraper (DPOR)
- Use case: Build a Fairfax County Roofing Contractor List
- Use case: Build a Richmond, VA HVAC and Electrical Contractor List
More actors, coverage and nightly verification results: scrapebench.dev
Works with AI assistants (MCP)
Callable as an MCP tool, so Claude, Cursor, VS Code Copilot and other MCP clients can run it directly. Grab the config from the MCP tab on this page — Apify hosts the server and keeps that snippet current, and OAuth signs you in on first connect, so no API token goes in your config file.
Then just ask:
"List the licensed roofing contractors in Fairfax County, Virginia, with their email addresses and mailing addresses."
County comes from the mailing ZIP; each row's county_method says whether that ZIP lies wholly in the county. Runs started this way bill exactly like any other run.