# Florida Roofing Contractor Directory & Leads (DBPR) (`scrapebench/florida-roofing-contractor-directory-leads-scraper`) Actor

Export every DBPR-licensed Florida roofing contractor — firm, qualifier, licence #, status, expiry, address, city, ZIP and county — statewide or by county.

- **URL**: https://apify.com/scrapebench/florida-roofing-contractor-directory-leads-scraper.md
- **Developed by:** [ScrapeBench](https://apify.com/scrapebench) (community)
- **Categories:** Lead generation
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.002 / roofing contractor record

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Florida Roofing Contractor Directory & Leads (DBPR)

### Pain points

- DBPR's licence search shows at most 50 results a page, so a statewide list of active roofers is about 200 pages of clicking and copying.
- DBPR's own bulk file is a 47 MB, header-less CSV of 262,832 licences across every construction trade, with status and county stored as codes — not a roofer list you can open.
- Roofing sales and supply teams need to know which roofers are actually licensed and active today, not a list bought months ago.

### What we solve

- Reads DBPR's free daily construction-licence file in one pass and keeps only the two roofing licences: CCC Certified and RC Registered Roofing Contractor.
- Decodes DBPR's status and county codes into plain words (Current, Active; Miami-Dade) and dates into ISO format.
- Filter by county, city, licence type and status in one run — statewide export up to 100,000 rows.
- Flags addresses of record that are PO boxes, so you can split mailers from door-knocking lists.

### Summary

Export every DBPR-licensed Florida roofing contractor in one run. On 2026-10-14 DBPR's file listed 9,856 active roofing licences (9,387 Certified CCC + 469 Registered RC) and 10,905 in all published statuses. Each row gives the firm, the licensed qualifier, licence number, status, original licensure and expiration dates, and the address of record with city, ZIP and county. Pick counties or run statewide. The file has no phone or email column, so this actor returns neither.

### Who it's for

- Roofing material suppliers and distributors building territory prospect lists
- Sales reps selling software, insurance, financing or equipment to roofing contractors
- General contractors and property managers finding licensed roofing subs by county
- Storm-response and restoration companies sizing the licensed roofer pool in a region
- Compliance teams checking roofing licence status and expiry at scale

### 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:

```json
{
  "counties": [
    "Miami-Dade"
  ],
  "licenseTypes": [
    "CCC",
    "RC"
  ],
  "statuses": [
    "active"
  ],
  "maxResults": 2000
}
```

See **Inputs** below for every available field.

### What you get

One row per record:

| Field | Description |
|---|---|
| `business_name` | Firm the licence is qualified under (DBPR's 'doing business as' name); the qualifier's own name when no firm is listed |
| `person_name` | Licensed qualifier, as DBPR writes it (LAST, FIRST MIDDLE) |
| `license_number` | DBPR licence number, e.g. CCC1338052 or RC0065048 (unique per row) |
| `license_code` | CCC or RC |
| `license_type` | Certified Roofing Contractor or Registered Roofing Contractor |
| `status` | DBPR primary + secondary status, e.g. 'Current, Active', 'Current, Inactive', 'Suspended, Active' |
| `issue_date` | Original licensure date (ISO) |
| `effective_date` | Effective date of the current licence record (ISO) |
| `expiration_date` | Expiration date (ISO) |
| `address` | Address of record (street or PO box); null on 2% of active rows |
| `po_box` | True when the address of record is a PO box |
| `city` | City of the address of record |
| `address_state` | State of the address of record (most FL; 701 active licensees live out of state) |
| `zip_code` | ZIP or ZIP+4 |
| `county` | Florida county, or 'Out of State' / 'Foreign' |
| `county_code` | DBPR's county code |
| `phone` | Not in DBPR's file; always null |
| `source_url` | DBPR's construction-licence file the row was read from |

Sample:

```json
{
  "state": "FL",
  "license_number": "RC0065048",
  "license_code": "RC",
  "license_type": "Registered Roofing Contractor",
  "business_name": "CREST ENTERPRISES AND LAND DEVELOPMENT INC",
  "person_name": "MEDINA, MOSES C",
  "status": "Current, Active",
  "issue_date": "1992-04-27",
  "effective_date": "2013-09-24",
  "expiration_date": "2027-08-31",
  "address": "106 TRADE CIRCLE W, SUITE B",
  "po_box": false,
  "city": "PORT ST JOE",
  "address_state": "FL",
  "zip_code": "32456",
  "county": "Gulf",
  "county_code": "33",
  "phone": null,
  "matched_by": "statewide_file",
  "source_url": "https://www2.myfloridalicense.com/sto/file_download/extracts/CONSTRUCTIONLICENSE_1.csv"
}
```

### Inputs

| Field | Required | Type | Default | Description |
|---|---|---|---|---|
| `counties` | no | array | `[]` | Florida counties to export, e.g. 'Miami-Dade', 'Hillsborough', 'St. Johns'. Case, punctuation and a trailing 'County' do not matter; 'Dade' and DBPR's two-digit county codes work too. Leave empty for all of Florida (plus licensees with an out-of-state address). A name that is not a Florida county is dropped and logged; if none is recognised the run returns one free notice instead of widening to the whole state. |
| `cities` | no | array | `[]` | Optional: keep only licensees whose address city is one of these (exact city name, case-insensitive, e.g. 'Jacksonville', 'Cape Coral'). Leave empty for every city. |
| `licenseTypes` | no | array | `["CCC", "RC"]` | CCC = Certified Roofing Contractor (may work anywhere in Florida), RC = Registered Roofing Contractor (limited to the local jurisdictions where they hold a competency card). Default: both. |
| `statuses` | no | array | `["active"]` | active (current or on probation, and active — allowed to contract), inactive, suspended, or all. Default: active. DBPR's file leaves out null & void, delinquent and involuntarily inactive licences, so 'all' means every roofing licence DBPR still publishes. |
| `maxResults` | no | integer | `500` | Cap on the rows returned for the whole run (this is one statewide export, not a per-county search). Florida has about 9,900 active roofing licences, so 10000 returns all of them. Default 500. |
| `proxyConfiguration` | no | object | `{"useApifyProxy": true}` | Used only to download DBPR's licence file, and only if the direct download is refused. Apify datacenter is the default; residential would bill ~47 MB of traffic per run. |

### Pricing (Pay Per Event)

You pay per result (`dataset-item`) — **no charge for empty runs**. Example: **1101 active Miami-Dade roofing licences** at *$0.002/result* ≈ **$2.20**.

Measured 2026-10-14: all 9,856 active Florida roofing licences statewide cost about $19.71. Free marker rows (no match, unusable input, source outage, max charge reached) are never charged. Apify platform usage is billed separately per your plan.

### Use cases

- Supplier prospecting — a distributor exports every active roofer in Lee and Collier counties before a territory push.
- Direct mail — a marketer pulls a statewide list and uses the po_box flag to split mail-only addresses from storefronts.
- Subcontractor vetting — a GC confirms a roofing sub holds an active CCC licence and when it expires.
- Market sizing — an analyst counts active Certified vs Registered roofers by county before opening a branch.

### Why this actor

- Official source: DBPR's own daily licence file, read at run time — not a resold copy.
- One run covers the whole state; county, city, type and status filters run in memory, so a statewide export takes no longer than one county (9,856 rows in under 2 seconds, measured from a workstation 2026-10-14).
- Codes decoded for you: status, county and dates come out in plain words and ISO format.

### Limitations & updates

Covers DBPR roofing licences only (CCC and RC). No phone or email (not in DBPR's file). The address is DBPR's address of record: 425 active licences (4%) list a PO box and 202 (2%) list no address. 701 active licensees have an out-of-state address and 326 have no county code. The licensee in DBPR's file is the qualifying individual; one qualifier can hold several licences, each a separate row. DBPR refuses the download from Apify's container IP, so the file comes through Apify's datacenter proxy (the default) and a run spends about four minutes downloading it (213 s on 2026-10-14). Data refreshes daily as DBPR rebuilds its file; counts measured 2026-10-14.

### FAQ

**Where does the data come from?**

The Florida Department of Business and Professional Regulation (DBPR) publishes a free daily file of every construction licence on its Construction Industry public-records page. The actor downloads that file at run time and keeps the roofing licences.

**Which licences are included?**

The two Florida roofing licences: CCC Certified Roofing Contractor (may work anywhere in the state) and RC Registered Roofing Contractor (limited to the local jurisdictions where they hold a competency card). Other trades are not served by this actor.

**Is there a phone number or email?**

No. DBPR's file has no phone or email column. You get the firm, qualifier and address of record (98% of active rows have one).

**How many rows can I get?**

Up to 100,000 per run. On 2026-10-14 there were 9,856 active roofing licences statewide (1,101 in Miami-Dade, 886 in Broward, 588 in Palm Beach) and 10,905 in all published statuses.

**How current is it?**

DBPR rebuilds the file daily (the 2026-10-14 copy was dated that morning). Each run downloads the current file.

**What does 'active' mean here?**

DBPR primary status Current or Probation with secondary status Active. 'inactive' and 'suspended' are separate filter values, and 'all' returns every roofing licence in the file. DBPR leaves null & void, delinquent and involuntarily inactive licences out of the file entirely.

**How am I charged?**

Per row returned. A run that finds nothing, an unusable filter, or a source outage returns one free notice row and costs nothing beyond Apify platform usage.

### Which actor to choose

Part of the roofing contractor data suite:

- **Illinois Roofing Contractor Directory & Leads Scraper (IDFPR)** — You want the same roofing contractor list for Illinois (IDFPR).

### Guides & use cases

Written up on **[scrapebench.dev](https://scrapebench.dev)** — the bench that runs and verifies this actor against the live source every night:

- **How-to:** [How to run Florida Roofing Contractor Directory & Leads (DBPR)](https://scrapebench.dev/guides/how-to-florida-roofing-contractor-directory-leads-scraper/)
- **Use case:** [Export Every Active Florida Roofing Contractor (DBPR)](https://scrapebench.dev/use-cases/florida-active-roofing-contractors-statewide/)

More actors, coverage and nightly verification results: **[scrapebench.dev](https://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](https://apify.com/scrapebench/florida-roofing-contractor-directory-leads-scraper/api/mcp) 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:

> "Export the active roofing contractors in Miami-Dade County, Florida."

Miami-Dade returned 1,101 active licences on 2026-10-14 (about $2.20); leave the county out for the whole state. Runs started this way bill exactly like any other run.

# Actor input Schema

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

Florida counties to export, e.g. 'Miami-Dade', 'Hillsborough', 'St. Johns'. Case, punctuation and a trailing 'County' do not matter; 'Dade' and DBPR's two-digit county codes work too. Leave empty for all of Florida (plus licensees with an out-of-state address). A name that is not a Florida county is dropped and logged; if none is recognised the run returns one free notice instead of widening to the whole state.

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

Optional: keep only licensees whose address city is one of these (exact city name, case-insensitive, e.g. 'Jacksonville', 'Cape Coral'). Leave empty for every city.

## `licenseTypes` (type: `array`):

CCC = Certified Roofing Contractor (may work anywhere in Florida), RC = Registered Roofing Contractor (limited to the local jurisdictions where they hold a competency card). Default: both.

## `statuses` (type: `array`):

active (current or on probation, and active — allowed to contract), inactive, suspended, or all. Default: active. DBPR's file leaves out null & void, delinquent and involuntarily inactive licences, so 'all' means every roofing licence DBPR still publishes.

## `maxResults` (type: `integer`):

Cap on the rows returned for the whole run (this is one statewide export, not a per-county search). Florida has about 9,900 active roofing licences, so 10000 returns all of them. Default 500.

## `proxyConfiguration` (type: `object`):

Used only to download DBPR's licence file, and only if the direct download is refused. Apify datacenter is the default; residential would bill ~47 MB of traffic per run.

## Actor input object example

```json
{
  "counties": [],
  "cities": [],
  "licenseTypes": [
    "CCC",
    "RC"
  ],
  "statuses": [
    "active"
  ],
  "maxResults": 500,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

One row per roofing licence.

# 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 = {
    "counties": [],
    "licenseTypes": [
        "CCC",
        "RC"
    ],
    "statuses": [
        "active"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapebench/florida-roofing-contractor-directory-leads-scraper").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 = {
    "counties": [],
    "licenseTypes": [
        "CCC",
        "RC",
    ],
    "statuses": ["active"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapebench/florida-roofing-contractor-directory-leads-scraper").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 '{
  "counties": [],
  "licenseTypes": [
    "CCC",
    "RC"
  ],
  "statuses": [
    "active"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapebench/florida-roofing-contractor-directory-leads-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapebench/florida-roofing-contractor-directory-leads-scraper"
        }
    }
}
```

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/JFBpu7de1RvW6KjEI/builds/AcJJw7gwczDfsXo0J/openapi.json
