# Florida Contractor Directory & Leads Scraper (`muhammadafzal/florida-dbpr-contractor-directory`) Actor

Search official Florida DBPR construction licenses by contractor type, status, name, license number, city, county, and public mailing address. Verified free-plan runs return at most five records; paid and agentic-paid runs can request more.

- **URL**: https://apify.com/muhammadafzal/florida-dbpr-contractor-directory.md
- **Developed by:** [Muhammad Afzal](https://apify.com/muhammadafzal) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 florida contractor records

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Florida Contractor Directory & Leads Scraper (DBPR)

Search and export official Florida Department of Business and Professional Regulation (DBPR) Construction Industry contractor records for license verification, compliance research, territory planning, and address-based lead lists.

The Actor reads DBPR's weekly public construction-license extract, filters records during a streaming scan, validates each result, removes duplicates, and writes a clean dataset ready for CSV, Excel, JSON, API, or automation workflows.

**Free-plan limit:** verified Apify free-plan users can receive at most 5 contractor records per run. Paid and agentic-paid runs can use the requested `maxResults` limit. When the free cap is reached, the Actor finishes gracefully and explains that an upgrade is required for more results.

### What it extracts

| Field | Description |
|---|---|
| licenseNumber | Display license number such as CGC012345 |
| licenseTypeCode, licenseType | DBPR occupation code and decoded contractor category |
| licenseeName | Licensed person or entity |
| businessName | DBPR doing-business-as or qualified business name, when present |
| status, isCurrent | Normalized status and best-effort current flag |
| primaryStatus, secondaryStatus | Original decoded DBPR status values |
| originalLicensureDate, effectiveDate, expirationDate | Normalized YYYY-MM-DD dates |
| addressLine1–3, city, state, postalCode | Public mailing-address fields |
| county, countyCode | County decoded from DBPR's two-digit code |
| fullAddress | Convenience address assembled from source fields |
| sourceUrl, sourceLastModifiedAt, scrapedAt | Record provenance and freshness metadata |

DBPR's construction-license extract does **not** contain phone numbers, email addresses, websites, social profiles, or inferred contacts. This Actor never fabricates those fields. “Leads” means licensed contractor and business records with public mailing addresses.

### When to use it

- Build a list of active general, building, residential, roofing, HVAC, plumbing, pool, solar, utility, mechanical, sheet-metal, or specialty contractors.
- Find contractor businesses in a Florida city or county.
- Verify a known set of DBPR construction license numbers against the weekly extract.
- Segment licensees by category, status, expiration date, geography, or presence of a business name.
- Feed normalized records into CRM review, compliance, procurement, market research, or mail outreach workflows.

Do not use this Actor as a substitute for real-time legal verification, complaints or discipline research, local permit research, or electrical-contractor coverage. DBPR says the bulk file is refreshed weekly and may be delayed by maintenance. The construction download excludes null-and-void, delinquent, and involuntarily inactive records. Florida electrical contractors are published in a separate DBPR board file.

### Input

| Input | Default | Purpose |
|---|---:|---|
| searchTerms | empty | Partial match against name, business, license, city, or address |
| licenseNumbers | empty | Exact display license numbers |
| cities | Miami | Case-insensitive exact city matches |
| counties | empty | Florida county names or DBPR two-digit county codes |
| licenseTypes | CGC | Construction occupation codes; clear to include all |
| statuses | active | Normalized statuses; clear to include all |
| onlyBusinessLeads | true | Require a DBPR business name |
| maxResults | 100 | Unique output cap, from 1 to 50,000; verified free users receive at most 5 |
| useBrowserFallback | true | Use a browser session when HTTP access is challenged |
| proxyConfiguration | Apify Proxy | Consistent proxy settings for the DBPR source session |

Filters across different fields use AND logic. Multiple values inside the same field use OR logic. For example, cities Miami and Tampa with license type CGC returns general contractors in either city.

#### City lead-list example

```json
{
  "cities": ["Tampa"],
  "licenseTypes": ["CGC", "CBC", "CRC"],
  "statuses": ["active"],
  "onlyBusinessLeads": true,
  "maxResults": 250,
  "useBrowserFallback": true,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

#### License verification example

```json
{
  "licenseNumbers": ["CGC012345", "CCC022222"],
  "cities": [],
  "licenseTypes": [],
  "statuses": [],
  "onlyBusinessLeads": false,
  "maxResults": 10
}
```

#### Run through the Apify API

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_USERNAME~florida-dbpr-contractor-directory/runs" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cities":["Orlando"],"licenseTypes":["CCC"],"statuses":["active"],"onlyBusinessLeads":true,"maxResults":100}'
```

Read results from the run's default dataset or use the results link in the Actor output schema. Read OUTPUT from the default key-value store for the outcome class, scan count, filters, source route, source freshness, warnings, and caveats.

### Output example

```json
{
  "licenseNumber": "CGC012345",
  "rawLicenseNumber": "0012345",
  "licenseTypeCode": "CGC",
  "licenseType": "Certified General Contractor",
  "licenseeName": "DOE, ALEX",
  "businessName": "DOE BUILDERS LLC",
  "isBusinessLead": true,
  "status": "active",
  "isCurrent": true,
  "expirationDate": "2030-08-31",
  "addressLine1": "100 MAIN ST",
  "city": "MIAMI",
  "state": "FL",
  "postalCode": "33101",
  "county": "Miami-Dade",
  "countyCode": "23",
  "fullAddress": "100 MAIN ST, MIAMI, FL, 33101",
  "sourceUrl": "https://www2.myfloridalicense.com/sto/file_download/extracts/CONSTRUCTIONLICENSE_1.csv",
  "scrapedAt": "2026-09-12T08:00:00.000Z"
}
```

### Pricing

This Actor uses pay per event with platform usage included.

| Event | Price |
|---|---:|
| Actor start | $0.005 per run |
| Florida contractor record | $0.002 per dataset item |

A 1-record verification costs about **$0.007**. A 100-record lead list costs about **$0.205**. Apify applies the run's maximum charge limit. The Actor writes only validated, deduplicated records, and the dataset-item event is charged automatically only when a record is delivered.

Verified Apify free-plan runs are capped at 5 delivered records per run. The cap is enforced in addition to `maxResults` and the run's maximum-charge limit; paid and agentic-paid users are not clamped by this free-plan rule. Agentic payment requests without an Apify account are treated as non-free when the platform does not provide a free-plan signal.

### Reliability and failure behavior

The source-access ladder is deliberately bounded:

1. Try a direct HTTP download.
2. Retry through the configured, session-consistent proxy.
3. If enabled, open DBPR's official public-records page in a real browser and download the linked file with the same session.

DBPR currently uses a Cloudflare managed browser check. The Actor does not solve or bypass CAPTCHAs or other access controls. If all permitted routes are challenged, the run writes a BLOCKED OUTPUT summary, returns no fabricated records, and applies no dataset-item charges. Valid filters with no matches produce an EMPTY summary. Bad input produces a REJECTED summary before source work.

### Data scope and responsible use

The source is an official Florida public-record download provided under Chapter 119, Florida Statutes. Use personal and address data lawfully. Respect marketing, privacy, suppression-list, fair-housing, anti-discrimination, and communications rules that apply to your workflow.

The data is limited to DBPR Construction Industry records in the downloaded snapshot. A missing record is not proof that a person or business is unlicensed: other DBPR boards, local governments, and other authorization systems may apply. For time-sensitive decisions, verify the record in DBPR's live license search or contact DBPR.

For support, open an issue from the Actor page and include the run ID, expected filter, and OUTPUT status. Do not include private API tokens or unrelated personal data.

# Actor input Schema

## `searchTerms` (type: `array`):

Use this to find text in a licensee name, business name, license number, city, or address. Enter up to 20 partial terms, for example roofing or builders. A record matches when any term is present. Leave empty for no keyword filter.

## `licenseNumbers` (type: `array`):

Use this for exact license verification or a known list, for example CGC012345. Spaces and hyphens are ignored. Enter up to 100 values. This searches the weekly construction extract, not every DBPR board or local license system.

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

Use this to build a city-level contractor list. Values are case-insensitive exact city matches, for example Miami or Tampa. Enter up to 50 cities. Leave empty to include every city.

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

Use this to filter Florida counties by name or DBPR two-digit county code, for example Miami-Dade or 23. Enter up to 50 values. This is the public mailing-address county, not proof of a contractor's service area.

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

Use this to select DBPR Construction Industry occupation codes. Defaults to certified general contractors (CGC). Select one or more types, or clear all to include every construction type in the extract.

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

Use this to keep normalized DBPR statuses. Defaults to active licenses. Clear all to include every status present in the weekly extract. Expired is derived from a past expiration date on an otherwise current record.

## `onlyBusinessLeads` (type: `boolean`):

Use this for company-focused prospecting. When enabled, individual license records without a DBPR doing-business-as name are excluded. This does not add phone, email, website, or inferred contact data.

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

Use this to cap delivered and billable dataset records. Verified Apify free-plan users receive at most 5 records per run; paid users can request 1–50,000. The Actor stops after this many unique matches. Default 100.

## `useBrowserFallback` (type: `boolean`):

Use this when DBPR blocks the cheaper HTTP download with its managed browser check. Enabled by default. It runs a real browser but never solves or bypasses a CAPTCHA.

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

Use this when DBPR restricts the current IP route. Apify Proxy settings apply consistently to the source session. The default uses Apify Proxy; choose a US residential group only when your plan supports it.

## Actor input object example

```json
{
  "searchTerms": [],
  "licenseNumbers": [],
  "cities": [
    "Miami"
  ],
  "counties": [],
  "licenseTypes": [
    "CGC"
  ],
  "statuses": [
    "active"
  ],
  "onlyBusinessLeads": true,
  "maxResults": 100,
  "useBrowserFallback": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Schema-validated Florida DBPR contractor records.

## `dataset` (type: `string`):

Default dataset API endpoint.

## `output` (type: `string`):

Outcome, counts, filters, warnings, source route, and caveats.

# 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 = {
    "cities": [
        "Miami"
    ],
    "licenseTypes": [
        "CGC"
    ],
    "statuses": [
        "active"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("muhammadafzal/florida-dbpr-contractor-directory").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 = {
    "cities": ["Miami"],
    "licenseTypes": ["CGC"],
    "statuses": ["active"],
}

# Run the Actor and wait for it to finish
run = client.actor("muhammadafzal/florida-dbpr-contractor-directory").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 '{
  "cities": [
    "Miami"
  ],
  "licenseTypes": [
    "CGC"
  ],
  "statuses": [
    "active"
  ]
}' |
apify call muhammadafzal/florida-dbpr-contractor-directory --silent --output-dataset

```

## MCP server setup

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

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/N3jXnSpwh7xSxICtS/builds/o9mmqBGTGLpAfi6bb/openapi.json
