# California CSLB Contractor License Scraper (`scrapers_lat/california-cslb-scraper`) Actor

Scrape licensed California contractor records from the CSLB public portal by classification and county. Extract license number, business name, status, trade classifications, issue and expiry dates, bond, workers comp, address, county and phone. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/scrapers_lat/california-cslb-scraper.md
- **Developed by:** [Scrapers Lat](https://apify.com/scrapers_lat) (community)
- **Categories:** Business, Lead generation, Automation
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $9.23 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

[![California CSLB Contractor License Scraper](https://scrapers.lat/banners/california-cslb-scraper.png)](https://console.apify.com/actors/GQD7jv7Fl99zBgf7X/input)

## California CSLB Contractor License Scraper

Here is one real result, with every field the actor returns:

```json
{
  "businessName": "EL DESIGN INC",
  "licenseNumber": "1090237",
  "status": "CLEAR",
  "url": "https://www.cslb.ca.gov/onlineservices/checklicenseII/LicenseDetail.aspx?LicNum=1090237",
  "businessType": "Corporation",
  "classifications": ["B", "C36"],
  "issueDate": "2022-04-19",
  "expireDate": "2028-04-30",
  "address": "185 GLENDALE BLVD",
  "city": "LOS ANGELES",
  "state": "CA",
  "zip": "90026",
  "county": "Los Angeles",
  "phone": "(213) 247 5025",
  "aiLeadScore": null,
  "aiLeadTemperature": null,
  "aiProfileSummary": null,
  "bondInfo": {
    "suretyCompany": "AMERICAN CONTRACTORS INDEMNITY COMPANY",
    "bondNumber": "100883043",
    "effectiveDate": "2024-08-19"
  },
  "workersComp": {
    "coverageType": "Exempt",
    "insuranceCompany": null,
    "policyNumber": null,
    "effectiveDate": null,
    "expirationDate": null
  },
  "observedAt": "2026-08-14T07:12:10.709Z",
  "error": null
}
```

The most complete California CSLB contractor license scraper available. It returns every field the CSLB public data export exposes for a licensed contractor (license number, business name and type, status, trade classifications, issue and expiry dates, full address, county and phone), plus the contractor bond and workers' compensation detail, and gives you classification and county filters to pull exactly the contractors you need.

**📥 [Input](https://apify.com/scrapers_lat/california-cslb-scraper/input-schema) · 📤 [Output](https://apify.com/scrapers_lat/california-cslb-scraper/output-schema) · 💰 [Pricing](https://apify.com/scrapers_lat/california-cslb-scraper/pricing) · ▶️ [Examples](https://apify.com/scrapers_lat/california-cslb-scraper/examples)**

![Apify](https://img.shields.io/badge/Platform-Apify-1CE1CE?logo=apify\&logoColor=white)
![Coverage](https://img.shields.io/badge/Coverage-California-blue)
![Output](https://img.shields.io/badge/Output-JSON%20%7C%20CSV%20%7C%20Excel-orange)
![Billing](https://img.shields.io/badge/Billing-Pay%20per%20result-brightgreen)

### Table of contents

- [What it does](#what-it-does)
- [Quickstart](#quickstart)
- [Input reference](#input-reference)
- [Output reference](#output-reference)
- [Example output record](#example-output-record)
- [Run via API and CLI](#run-via-api-and-cli)
- [Fetch results](#fetch-results)
- [Billing and limits](#billing-and-limits)
- [FAQ and troubleshooting](#faq-and-troubleshooting)

### What it does

The actor requests the CSLB public data export for the classifications and counties you select, parses the returned spreadsheet, and writes one normalized record per licensed contractor to the run's dataset. Each record carries the license number, business name and type, license status, trade classifications, issue and expiry dates, full address with county, and the phone on file. When `withDetails` is on (the default), each record also includes the contractor bond block (surety company, bond number, effective date) and the workers' compensation block (coverage type, insurer, policy number, effective and expiration dates).

Dates are normalized to `YYYY-MM-DD` and missing values are returned as `null`. Optional paid AI add-ons (lead score, profile summary) and a contact enrichment add-on are off by default and billed per record only when they return usable output.

### Quickstart

Open the actor, paste this into the input, and press Run. It returns up to 10 plumbing (C-36) contractors in Los Angeles County with bond and workers' comp detail.

```json
{
  "classifications": ["C-36"],
  "counties": ["19"],
  "maxLicenses": 10,
  "withDetails": true
}
```

`classifications` and `counties` are both required and use the CSLB codes (county `19` is Los Angeles). Up to 10 classifications and 10 counties per run.

### Input reference

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `classifications` | string\[] | yes | (none) | One or more CSLB license classifications, for example `C-10` (Electrical), `C-36` (Plumbing), `B` (General Building). Up to 10 per run. |
| `counties` | string\[] | yes | (none) | One or more California county codes, for example `19` (Los Angeles), `30` (Orange), `37` (San Diego). Up to 10 per run. |
| `maxLicenses` | integer | no | `10` | Maximum license records to collect across all classifications and counties (1 to 1000000). Free Apify plans are capped at 10. |
| `withDetails` | boolean | no | `true` | When on, each record includes the contractor bond and workers' compensation detail. When off, only the core license fields are emitted. |
| `withLeadScore` | boolean | no | `false` | Paid add-on. AI-qualifies each contractor as a sales lead (0-100 plus hot/warm/cold). Billed per record only when a score is produced. |
| `withProfileSummary` | boolean | no | `false` | Paid add-on. Adds a 1-2 sentence AI profile summary. Billed per record only when a summary is produced. |
| `enrichContacts` | boolean | no | `false` | Paid add-on. For records without an email, attempt to find a public business contact email and name. Billed per attempt, plus an extra charge only when an email is found. |
| `enrichContactsMax` | integer | no | `50` | Cap how many results the contact add-on tries to enrich. Free Apify accounts are capped at 3. |

If no classification or county is provided, the run stops without charging. AI and contact add-ons require a paid Apify plan and are disabled for free accounts.

### Output reference

One dataset item per contractor license. Types: `string`, `integer`, `number`, `string[]`, `object`, or `null` when the value is absent.

| Field | Type | Description |
|---|---|---|
| `businessName` | string | Licensed business name. |
| `licenseNumber` | string | CSLB license number. |
| `status` | string | License status, for example `CLEAR`, `EXPIRED`, `SUSPENDED`. |
| `url` | string | CSLB license detail page URL. |
| `businessType` | string | Business type (`Corporation`, `Sole Ownership`, ...), or `null`. |
| `classifications` | string\[] | Trade classifications held on the license. |
| `issueDate` | string | License issue date (`YYYY-MM-DD`), or `null`. |
| `expireDate` | string | License expiry date (`YYYY-MM-DD`), or `null`. |
| `address` | string | Business street address. |
| `city` | string | City. |
| `state` | string | State code (`CA`). |
| `zip` | string | Postal code. |
| `county` | string | County name. |
| `phone` | string | Phone on file, or `null`. |
| `bondInfo` | object | Contractor bond `{ suretyCompany, bondNumber, effectiveDate }` (only with `withDetails`), or `null`. |
| `workersComp` | object | Workers' comp `{ coverageType, insuranceCompany, policyNumber, effectiveDate, expirationDate }` (only with `withDetails`), or `null`. |
| `aiLeadScore` | number | AI lead score (0-100) when the add-on is enabled, else `null`. |
| `aiLeadTemperature` | string | AI lead temperature (`hot`/`warm`/`cold`) when enabled, else `null`. |
| `aiProfileSummary` | string | AI profile summary when the add-on is enabled, else `null`. |
| `observedAt` | string | ISO 8601 timestamp of when the record was collected. |
| `error` | string | `null` on success. On a failed run, a single item with a populated `error` field is written instead. |

When the contact add-on finds an email, extra fields are added: `enrichedEmail`, `enrichedContactName`, `enrichedJobTitle`, `enrichedEmailStatus`, `enrichedSource`, `enrichedConfidence`.

### Example output record

Real record from a live run (input `{"classifications": ["B","C-36"], "counties": ["19"], "withDetails": true, "withLeadScore": true, "withProfileSummary": true}`):

```json
{
  "businessName": "EL DESIGN INC",
  "licenseNumber": "1090237",
  "status": "CLEAR",
  "businessType": "Corporation",
  "classifications": ["B", "C36"],
  "issueDate": "2022-04-19",
  "expireDate": "2028-04-30",
  "address": "185 GLENDALE BLVD",
  "city": "LOS ANGELES",
  "state": "CA",
  "zip": "90026",
  "county": "Los Angeles",
  "phone": "(213) 247 5025",
  "bondInfo": {
    "suretyCompany": "AMERICAN CONTRACTORS INDEMNITY COMPANY",
    "bondNumber": "100883043",
    "effectiveDate": "2024-08-19"
  },
  "workersComp": { "coverageType": "Exempt", "insuranceCompany": null, "policyNumber": null, "effectiveDate": null, "expirationDate": null },
  "aiLeadScore": 75,
  "aiLeadTemperature": "warm",
  "aiProfileSummary": "EL DESIGN INC is a licensed contractor based in Los Angeles, CA, with CSLB license 1090237, classified under B and C36. The corporation has been licensed since April 19, 2022, and has a clear status with a contractor bond from American Contractors Indemnity Company.",
  "observedAt": "2026-08-14T07:12:10.709Z",
  "error": null
}
```

### Run via API and CLI

Start a run and wait for it to finish, then read the dataset. Replace `<TOKEN>` with your Apify API token.

Run synchronously and get dataset items in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~california-cslb-scraper/run-sync-get-dataset-items?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"classifications":["C-36"],"counties":["19"],"maxLicenses":25,"withDetails":true}'
```

Start a run asynchronously:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~california-cslb-scraper/runs?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"classifications":["C-10","C-46"],"counties":["30","37"],"maxLicenses":500}'
```

Apify CLI:

```bash
apify call scrapers_lat/california-cslb-scraper \
  --input '{"classifications":["B"],"counties":["19"]}'
```

### Fetch results

Every run writes to a dataset. Fetch items as JSON, CSV, or Excel by changing `format`:

```bash
## JSON
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"

## CSV
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"

## Paginate large datasets
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&offset=1000&limit=1000"
```

`<DATASET_ID>` is returned as `defaultDatasetId` in the run object. Use `offset` and `limit` to page through large result sets. `clean=true` drops empty and internal fields.

### Billing and limits

- **Pay per result.** You are charged per license record returned (`result` event). A `details` event is charged when real bond or workers' comp detail is merged. See the [pricing tab](https://apify.com/scrapers_lat/california-cslb-scraper/pricing) for current prices.
- **No charge on failure.** If the download fails or matches nothing, the actor writes a single item with a populated `error` field and does not charge. Empty runs cost nothing.
- **Spend cap respected.** Set `maxTotalChargeUsd` on the run; once reached, the actor stops emitting and charging further billable results, including add-on charges.
- **Free Apify plans** are capped at 10 records per run. Upgrade for higher `maxLicenses`.
- **AI and contact add-ons** require a paid Apify plan and are billed per record only when they return usable output.

### FAQ and troubleshooting

**How do I select classifications and counties?**
Pick from the dropdowns in the input, or pass the CSLB codes directly. Classifications use the CSLB labels (`C-36`, `B`, `C-10`); counties use their numeric codes (`19` = Los Angeles). Up to 10 of each per run.

**A run returned 0 records. Why?**
No contractor in the selected counties held the selected classifications, or the portal returned no spreadsheet. Broaden the classifications or add counties. Empty runs cost nothing.

**Do I get bond and workers' comp?**
Yes, when `withDetails` is on (the default). Each record includes the `bondInfo` and `workersComp` blocks parsed from the CSLB export, with `null` where the source omits a value.

**Why is `workersComp.insuranceCompany` null?**
The contractor is `Exempt`, self-insured, or has no current W/C policy. Only rows with an active W/C policy carry an insurer and policy number.

**Is this an official CSLB tool?**
No. This actor is independent and has no affiliation with the California Contractors State License Board. It reads only publicly available CSLB data.

### Related scrapers

- [California DRE Scraper](https://apify.com/scrapers_lat/california-dre-scraper): California real estate licensee records.
- [Florida DBPR Scraper](https://apify.com/scrapers_lat/florida-dbpr-scraper): Florida professional and contractor licenses.
- [USA Contractor Licenses Scraper](https://apify.com/scrapers_lat/usa-contractor-licenses-scraper): Contractor licenses across US states.
- [Texas TDLR Scraper](https://apify.com/scrapers_lat/texas-tdlr-scraper): Texas licensed professionals and businesses.
- [Oregon CCB Contractors Scraper](https://apify.com/scrapers_lat/oregon-ccb-contractors-scraper): Oregon licensed construction contractors.

### More scrapers at scrapers.lat

Built and maintained by [scrapers.lat](https://scrapers.lat), where we publish scrapers for US and Latin American public platforms: company registries, government data, finance, e-commerce and more. Browse the catalog or request a custom scraper at [scrapers.lat](https://scrapers.lat).

***

> Independent tool, not affiliated with the California Contractors State License Board (CSLB). Accesses only publicly available license data.

# Actor input Schema

## `maxLicenses` (type: `integer`):

Maximum number of contractor license records to collect across all selected classifications and counties. Optional.

## `withDetails` (type: `boolean`):

When enabled, each record also includes the contractor's bond information (surety company, bond number, effective date) and workers' compensation insurance (insurer, policy number, effective and expiration dates) parsed from the CSLB data export. When disabled, only the core license fields are emitted.

## `withLeadScore` (type: `boolean`):

AI-qualify each contractor license as a sales lead (0-100 score + hot/warm/cold). Paid add-on; paying users only. Charged only on usable output.

## `withProfileSummary` (type: `boolean`):

AI-generated 1-2 sentence English profile summary. Paid add-on; paying users only. Charged only on usable output.

## `classifications` (type: `array`):

One or more CSLB license classifications to include in the download (for example C-10 Electrical, C-36 Plumbing, B General Building). At least one classification is required. The CSLB data portal accepts up to 10 classifications per request.

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

One or more California counties to include in the download. At least one county is required. The CSLB data portal accepts up to 10 counties per request.

## `enrichContacts` (type: `boolean`):

Optional paid add-on, off by default. For each result without an email, attempt to find a public business contact email and a contact person's name. Billed per attempt, plus an extra charge only when an email is found.

## `enrichContactsMax` (type: `integer`):

Cap how many results the add-on tries to enrich, to control add-on cost. Leave empty to attempt all. Free Apify accounts are capped at 3.

## Actor input object example

```json
{
  "maxLicenses": 10,
  "withDetails": true,
  "withLeadScore": false,
  "withProfileSummary": false,
  "classifications": [
    "C-39"
  ],
  "counties": [
    "1"
  ],
  "enrichContacts": false,
  "enrichContactsMax": 50
}
```

# Actor output Schema

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

No description

# 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 = {
    "maxLicenses": 10,
    "classifications": [
        "C-39"
    ],
    "counties": [
        "1"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers_lat/california-cslb-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 = {
    "maxLicenses": 10,
    "classifications": ["C-39"],
    "counties": ["1"],
}

# Run the Actor and wait for it to finish
run = client.actor("scrapers_lat/california-cslb-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 '{
  "maxLicenses": 10,
  "classifications": [
    "C-39"
  ],
  "counties": [
    "1"
  ]
}' |
apify call scrapers_lat/california-cslb-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapers_lat/california-cslb-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/GQD7jv7Fl99zBgf7X/builds/49k0k8zlGwbs0cPSz/openapi.json
