Florida Contractor License Scraper — DBPR Records avatar

Florida Contractor License Scraper — DBPR Records

Pricing

$4.00 / 1,000 per license record returneds

Go to Apify Store
Florida Contractor License Scraper — DBPR Records

Florida Contractor License Scraper — DBPR Records

Licensed Florida construction contractors from the official DBPR public records: name, full address, city, ZIP, license number and type, status, issue and expiry dates. 250,000+ licensees, or switch to the applicant file for phone numbers. Filter by license type, city or ZIP.

Pricing

$4.00 / 1,000 per license record returneds

Rating

0.0

(0)

Developer

Scrapers Delight

Scrapers Delight

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

16 days ago

Last modified

Share

Licensed Florida construction contractors from the state's own public-records extracts: name, full street address, city, ZIP, license number and type, status, issue and expiry dates.

Certified general, building, roofing, plumbing, HVAC, pool and specialty contractors, plus business qualifiers. Filter by license type, city or ZIP.

Two record sets — pick the one you need

DBPR publishes these as separate files and they carry different fields. This Actor exposes both through one schema rather than silently merging them.

sourceRowsHas phoneHas license status & expiry
licensed (default) — the contractor roster250,000+
applicants — license applicants104,35976%

If you need to call people, use applicants. If you need verified license status, numbers and renewal dates, use licensed. The roster genuinely contains no phone column — this Actor will not pretend otherwise.

Example — licensed

{
"source": "licensed", "isApplicant": false,
"licenseNumber": "CBC006231",
"licenseTypeCode": "CBC",
"name": "WALTERS, DENNIS D",
"businessName": "BUILDING CONCEPTS OF TAMPA BAY, LLC",
"address1": "6635 GLENCOE DRIVE",
"city": "TAMPA", "state": "FL", "zip": "33617", "countyCode": "39",
"statusCode": "C", "status": "Current", "isCurrent": true,
"effectiveDate": "2024-09-16",
"expirationDate": "2026-08-31", "daysUntilExpiry": 12
}

Field fill — measured, not promised

Every record carries all 23 keys in both modes (a field the source does not have comes back null, never missing). Counts below are from live runs on 2026-08-19: 3,414 licensed rows and 300 applicants rows. The roster file is ordered by license type, so the licensed sample is CBC and CGC; where a field's fill differs sharply between the two, both numbers are given. QB (business qualifier) rows do not follow this table — see the section right below it.

FieldlicensedapplicantsNote
name100%100%roster stores LAST, FIRST M; applicants are joined FIRST MIDDLE LAST SUFFIX
businessName72%the DBA / qualifying company on the licence. Absent from the applicant file
licenseNumber100% †applicants have not been issued one yet
licenseTypeCode100%100%roster uses CBC; applicants use numeric 0605
licenseTypeName100%the roster file ships the code only, no spelled-out name
phone76%the roster genuinely has no phone column; use applicants to call people
address1 / city / zip98%98%blank on the ~2% of records DBPR holds no address for
countyCode96%98%DBPR's numeric county code
address27%8%suite/apt line — sparse in the source itself, not a scraping gap
statusCode / status / isCurrent100%the applicant file carries no status column
originalIssueDate86%DBPR leaves it blank on older records — 98% of CBC, 67% of CGC
effectiveDate / expirationDate / daysUntilExpiry100% †"
state, source, isApplicant, sourceUrl, scrapedAt100%100%

Dashes are structural: those columns do not exist in that DBPR file. Verified 2026-08-18 by dumping every raw column of both extracts (22 columns in the roster, 15 in the applicant file).

QB (business qualifier) rows are a different animal — read this before you filter on QB

The licensed numbers above are measured on individual certified licences. QB rows are business registrations, and DBPR's roster carries no licence number and no expiry for them. Measured 2026-08-20 on a 6,000-row run covering CAC CCC CFC CRC CPC SCC QB across Miami, Orlando, Tampa and Jacksonville:

Field6 certified types (n=1,701)QB (n=4,299)
licenseNumber100% (1,701 distinct)0% — DBPR issues none on these rows
expirationDate / daysUntilExpiry100%0% — no renewal date in the file
originalIssueDate98.7%100%
effectiveDate99.9%100%
businessName84.4%6.9% — on a QB row the company is in name
address1 / city / zip / countyCode100%100%
statusCode / status / isCurrent100%100%

So: want licence numbers and renewal dates → do not include QB. Want the contracting companies with a mailing address → QB is exactly the set you want, and the company name is in name. (Coverage on CGC / CBC is the certified-type shape above, except originalIssueDate, which runs 98% on CBC and 67% on CGC — the 86% in the table.)

License type codes

QB business qualifier (a company registration — no licence number, no expiry) · CGC certified general · CBC certified building · CAC air conditioning · CCC roofing · CFC plumbing · CRC residential · CPC pool · SCC specialty · FRO

(The applicant file uses numeric codes instead — 0605 = Certified General Contractor.)

Reliability note — why this needs a residential proxy

DBPR's download host sits behind Cloudflare, so this Actor needs a proxy — and the US country pin matters as much as the residential tier. Re-measured 2026-08-17, 12 fresh sessions per lane:

RouteResult
No proxy / plain datacenter403 "Just a moment…"
Apify residential, no country pin2/12 — Cloudflare flags most of the pool
Apify residential + US + pinned session12/12 · 200 text/csv

The Actor defaults to RESIDENTIAL / United States with a fresh pinned session per request. It pulls the 48 MB roster as six parallel HTTP Range chunks on six independent exit IPs (measured 7.1 s for the whole file, versus 15–55 s and one outright failure for a single whole-file GET), and each chunk is retried on its own fresh exit — so one slow or blocked IP costs a single ~25 s chunk retry instead of the whole run. If DBPR ever stops honouring Range, it falls back to a whole-file GET that retries up to 8 times, each on a new exit. Leave the proxy country set to United States unless you have a reason not to — dropping the pin is what makes downloads fail.

If Cloudflare happens to challenge every exit tried, the run ends successfully with zero records and a status message asking you to re-run — it never fails hard and you are never billed for rows you did not receive.

The Actor also sizes itself to whatever run timeout you set: it will not start a download it cannot finish, and on a short timeout with a very large maxItems it returns partial data plus a status message rather than being killed mid-write. The roster file is 48 MB, so if you want the whole 250,000-row set give the run at least 10 minutes. The unwalled sibling host www.myfloridalicense.com serves the search form but 404s on these files.

What this Actor deliberately does not pull

cilb_certified.csv is 708 MB / ~4.1 million rows and looks like the obvious prize. It isn't a license roster — it's the continuing-education transcript, one row per course per licensee, with the same license number repeating dozens of times. Billing you per row for that would be billing you for duplicates. cilb_registered.csv (28 MB) is the same shape. Neither is used.

Pricing

$0.004 per record ($4 per 1,000).

Public records published by the Florida Department of Business & Professional Regulation. You are responsible for complying with DBPR's terms and with how you use the data.