# California Real Estate License Lookup — DRE Register (`automation-lab/california-dre-license-register`) Actor

Filter California DRE current license rows by number, name, county or type. Export status, dates, addresses, restrictions and official corporation/officer cross-links for due diligence.

- **URL**: https://apify.com/automation-lab/california-dre-license-register.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Business
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 license rows

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 Real Estate License Lookup — DRE Current Register

Use this California real estate license lookup to screen current DRE salesperson, broker, corporation and responsible-officer license rows for onboarding and recurring due diligence. Filter the official bulk register by license number, name, county or type, then export structured records with status, dates, addresses, restrictions and DRE's related-license fields.

This is an independent tool, not affiliated with or endorsed by the California Department of Real Estate. It reads the official current-register export, not the individual verification site's discipline history.

### Who is it for?

- Brokerage operations teams screening agent lists before onboarding.
- Mortgage and title teams checking current license rows alongside their own compliance process.
- Analysts comparing salesperson, broker and corporate-officer records across repeated snapshots.

### Why use it?

The source is a statewide ZIP containing a large CSV, not a query API. This Actor downloads the current official file, validates its shape and scans it with your filters. You receive normalized dates, preserved leading-zero numbers, explicit source provenance and consistent fields without managing the ZIP yourself.

There is no private mirror or credential requirement. Every run reads the official source. The delivered-row limit does not skip source validation.

### Coverage and important limitations

The export includes four row types: Salesperson, Broker, Corporation and Officer. A license number can appear on multiple rows. An Officer registration is not a separate inferred corporate ownership claim.

- Only the **current register** is covered. Missing rows are **not proof of revocation**, surrender, expiration or misconduct.
- Status strings are DRE's `Licensed` or `Licensed NBA`; the latter means no business address.
- The restricted flag is preserved, not interpreted as a disciplinary history.
- No historical records, disciplinary comments, email enrichment or real-time monitoring are included.
- Related-license fields are the source's cross-links. A number lookup returns only rows whose **own** license number matches; it does not recursively fetch related persons or corporations.
- DRE describes this file as updated daily. The HTTP Last-Modified timestamp is source-file provenance, not a guaranteed per-row change date.

### Getting started

1. Open the Actor and keep the example `county: Orange`, `licenseType: Broker`, `maxItems: 10`.
2. Run it. Download and full-register validation happen before record delivery.
3. Inspect the default dataset and the `SUMMARY` key-value record.
4. Export JSON, CSV or Excel using Apify's dataset tools.
5. For repeated checks, schedule runs in Apify and compare snapshots in your own downstream system.

### Inputs

All nonblank filters combine with **AND**, including license-number lookups. Input string edges are trimmed. Blank filters mean no restriction.

| Field | Behavior |
|---|---|
| `licenseNumber` | Exact eight digits, including leading zeros. Matches the row's own number only. |
| `name` | Case-insensitive substring of last/company name, first name and suffix joined with comma-space. Internal whitespace is literal. |
| `county` | Case-insensitive exact county name; `Orange` does not match `Orange County`. |
| `licenseType` | Exact `Salesperson`, `Broker`, `Corporation` or `Officer`. |
| `maxItems` | Global distinct delivered-row cap after filters, default 100, range 1–10000. Zero is invalid. |

An empty object returns the first 100 rows in CSV order. It is not a random sample or an aggregate. Unsupported input fields and invalid combinations/types fail rather than being silently ignored.

### Example inputs

**Orange County brokers**

```json
{"county":"Orange","licenseType":"Broker","maxItems":10}
```

**Own-license-number rows**

```json
{"licenseNumber":"01794680","maxItems":20}
```

**Corporate name screening**

```json
{"name":"Bryan Industrial","licenseType":"Corporation","maxItems":20}
```

### Output fields

Each dataset item represents one current license row, not one unique person. Optional blank source fields are `null`. The same own license number can legitimately appear with different types or related-license numbers.

| Fields | Meaning |
|---|---|
| `licenseNumber`, `licenseType`, `licenseStatus` | Official row identity, type and current status. |
| `name`, `lastName`, `firstName`, `nameSuffix` | Combined display name and original name components; corporation names use lastName. |
| `originalDateOfLicense`, `effectiveDate`, `expirationDate` | ISO dates, or null when blank/zero in the source. |
| `multipleLicense` | DRE multiple-license indicator. |
| `relatedLicenseNumber`, `relatedLicenseType` | DRE's explicit cross-link; no inferred graph expansion. |
| `relatedLastName`, `relatedFirstName`, `relatedNameSuffix` | Name components supplied for the related license. |
| `address1`, `address2`, `city`, `state`, `zipCode`, `county` | Public mailing/business-address fields supplied by DRE. |
| `foreignNation`, `foreignPostalInfo` | Foreign-address fields when present. |
| `restricted`, `ethicsAndAgency` | Original DRE indicators, not conclusions about discipline. |
| `sourceUrl`, `sourceLastModified`, `retrievedAt` | Official ZIP URL, HTTP file timestamp and scan-start timestamp. |

### Example output

The following public corporate record illustrates the source-backed relationship shape observed in the current CSV; dates and provenance depend on the run.

```json
{
  "licenseNumber": "00002442",
  "licenseType": "Corporation",
  "licenseStatus": "Licensed",
  "name": "Bryan Industrial Properties Inc",
  "effectiveDate": "2024-02-04",
  "expirationDate": "2028-02-03",
  "county": "ORANGE",
  "relatedLicenseNumber": "01794680",
  "relatedLicenseType": "Officer",
  "restricted": "N",
  "sourceUrl": "https://secure.dre.ca.gov/datafile/CurrList.zip"
}
```

Other documented fields also appear on real dataset rows. This abbreviated example is not an exhaustive schema.

### Summary and completeness

`SUMMARY` contains scanned source rows, per-type counts, raw filter-match count, delivered rows, limitReached and provenance. Duplicate identical matching source rows are delivered only once. Match count is before deduplication; it can exceed delivery count even without a cap.

The Actor checks the exact header, eight-digit identities, row types, status vocabulary, all four type presence and a conservative statewide row-count floor. A changed or incomplete export fails instead of masquerading as a valid empty search. No individual verification pages are fetched.

### How much does it cost to screen California DRE license rows?

Pricing uses a one-time **$0.005 start fee** plus the license-row event. Empty searches have the start fee but no license-row charge. Invalid input is rejected before charging. Each successfully delivered row uses the same item event, regardless of license type; related fields have no separate event charge.

| Plan tier | Per license row |
|---|---:|
| FREE | $0.0046 |
| BRONZE | $0.004 |
| SILVER | $0.00312 |
| GOLD, PLATINUM, DIAMOND | $0.0024 |

BRONZE examples including the start fee: an estimated total of $0.009 for a 1-record run, $0.045 for a 10-record run, or $0.405 for a 100-record run. Check the current Apify pricing panel before running. Platform spending limits may stop delivery before maxItems; treat the dataset as partial when the summary reports fewer delivered rows than matched rows.

### Limits and troubleshooting

Every run downloads the large official export even for one-number lookups. This can take longer than an interactive search. The default run timeout is one hour to allow larger filtered exports; smaller limits are recommended for initial evaluation.

Transient network failures, rate limits and server errors receive up to three total download attempts with bounded backoff. Permanent errors, schema changes and invalid rows fail explicitly. No paid proxy fallback is enabled. A terminal failure can leave partial results if delivery itself fails; do not treat a failed run as a complete export.

**No results?** Check the exact county and eight-digit number, try a wider name substring, or remove one AND filter. Absence is not a legal finding.

**Source changed?** Preserve the failed run ID and contact the maintainer through Apify. Do not interpret a failed download as no matching licenses.

### Integrations

Use CSV exports for spreadsheet checks, JSON for a compliance pipeline, or Apify datasets with Make, Zapier and webhooks. Keep each successful run as a separate snapshot and join on license number, type and related number rather than license number alone. Downstream change comparison and notifications are your integration's responsibility; the Actor does not emit alerts.

### API usage

Keep tokens in environment variables. Start one run and retain its ID; the response contains run/storage metadata, not the license rows.

```bash
curl -X POST "https://api.apify.com/v2/acts/automation-lab~california-dre-license-register/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
  -d '{"county":"Orange","licenseType":"Broker","maxItems":10}'
```

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/california-dre-license-register').call({county:'Orange',licenseType:'Broker',maxItems:10});
const { items } = await client.dataset(run.defaultDatasetId).listItems({limit:10});
console.log(items);
```

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/california-dre-license-register').call(run_input={'county':'Orange','licenseType':'Broker','maxItems':10})
print(client.dataset(run['defaultDatasetId']).list_items(limit=10).items)
```

### MCP use

Select the stable Actor-specific tool subset:

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/california-dre-license-register"
```

Equivalent client configuration for Claude Desktop, Cursor, or VS Code (use that client's HTTP MCP configuration format):

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=automation-lab/california-dre-license-register"}}}
```

Use the client's supported Apify authentication setup. Discover actual names and schemas with scoped `tools/list`: Actor selection also includes run/dataset/KV/abort helper tools, not exactly one tool. Read-only discovery does not authorize execution.

Example prompts: “Look up own-license-number rows for 01794680.” For a filtered screening workflow: “Run the DRE register Actor once for ten Orange County brokers. Follow that same run to completion and return license number, name, status and expiration.”

For an authorized invocation, retain the returned run ID and storage IDs. `call-actor` waits at most 45 seconds (default 30). If pending, check the **same** run with bounded 2/4/8/10-second backoff and a 120-second deadline. Configure client request timeout above the selected wait plus transport margin. On timeout recover the known run; never restart to poll. At deadline report pending and its ID. Report failures honestly and identify partial rows.

After success, request bounded dataset pages, for example 20 source rows from offset 0, at most 100 rows and 64 KiB of serialized UTF-8 content admitted to model context. Enforce this host-side, track source offsets and stop at exhaustion or either budget. Disclose truncation and the next offset; keep full exports outside model context. A client unable to intercept oversized responses cannot guarantee a byte ceiling. No universal token-saving claim is made.

### Legality, responsible use and privacy

Source: [DRE Examinee/Licensee List Data Files](https://www.dre.ca.gov/Licensees/ExamineeLicenseeListDataFiles.html). Public availability does not waive applicable privacy, data-use or due-diligence obligations. Handle public addresses responsibly and verify significant decisions with DRE's official services. This tool is not legal advice.

Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL queries are removed; reports are retained for 30 days. Successful datasets are stored in your Apify run storage.

### FAQ

**Does an absent license mean revoked?** No. This is only the current bulk register; use official DRE verification for significant decisions.

**Does the Actor use AI?** No runtime AI or model enrichment is used. Source fields are normalized deterministically.

**How do I delete results?** Delete your Apify run dataset/KV storage using platform controls. Temporary source files are cleaned after processing; sanitized failure reports expire after 30 days.

**How do I get support?** Preserve the run ID and open an Actor issue in Apify. Do not post sensitive inputs publicly.

### Related Actors

- [Virginia Real Estate License Lookup](https://apify.com/automation-lab/virginia-real-estate-license-lookup) for a separate state corpus.
- [Texas TREC License Holder Search](https://apify.com/automation-lab/texas-trec-license-holder-search-scraper) for Texas records.

These products do not add coverage to this California export.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/california-dre-license-register/changelog.md

# Actor input Schema

## `licenseNumber` (type: `string`):

Exact eight-digit DRE number including leading zeros. Returns only rows with this own license number, not related-license matches. Blank means all numbers.

## `name` (type: `string`):

Case-insensitive substring of last/company name, first name and suffix joined with comma-space. Outer input whitespace is trimmed; internal whitespace is literal. Blank means all names.

## `county` (type: `string`):

Case-insensitive exact county name after trimming input. For example Orange. Blank means all counties.

## `licenseType` (type: `string`):

Exact DRE row type. Blank means all four types. All nonblank filters are combined with AND, including license-number lookups.

## `maxItems` (type: `integer`):

Global cap on distinct delivered license rows after all filters, in CSV order. Default 100; range 1–10000. Zero is invalid. The complete source is still scanned and validated. Platform charge limits may stop delivery earlier.

## Actor input object example

```json
{
  "county": "Orange",
  "licenseType": "Broker",
  "maxItems": 10
}
```

# Actor output Schema

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

Delivered current-register rows

## `summary` (type: `string`):

Source counts, filter match counts, delivery limit and file provenance

# 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 = {
    "county": "Orange",
    "licenseType": "Broker",
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/california-dre-license-register").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 = {
    "county": "Orange",
    "licenseType": "Broker",
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/california-dre-license-register").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 '{
  "county": "Orange",
  "licenseType": "Broker",
  "maxItems": 10
}' |
apify call automation-lab/california-dre-license-register --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/california-dre-license-register"
        }
    }
}
```

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/uErzmc1tMfQwcgVwT/builds/aH2m0joxSoB5qTGBR/openapi.json
