CA DRE Real Estate License Status Delta avatar

CA DRE Real Estate License Status Delta

Pricing

$10.00 / 1,000 license status changeds

Go to Apify Store
CA DRE Real Estate License Status Delta

CA DRE Real Estate License Status Delta

Watches named California DRE real estate license holders and alerts on a genuine status change, a restricted-license flag, or the license disappearing from the Licensed/Licensed NBA registry entirely (expiration, surrender, or revocation). For HR screening, brokerages, insurers, due-diligence.

Pricing

$10.00 / 1,000 license status changeds

Rating

0.0

(0)

Developer

Radu Furtuna

Radu Furtuna

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Watches specific California real estate license holders in the official California Department of Real Estate (DRE) daily bulk registry (secure.dre.ca.gov/datafile/CurrList.zip) and delivers/bills only on a genuine change since your last check — never a re-delivery of an unchanged status.

Not a lookup tool and not legal advice. This is an informational monitor of a public government registry's publication state. It is not a legal determination of anyone's current right to practice real estate in California, not a full disciplinary history, and not a substitute for the official lookup at secure.dre.ca.gov/publicasp/pplinfo.asp before any decision that matters (hiring, a brokerage relationship, a commission deal, E&O insurance, due diligence).

What it watches

One watch = one DRE license number (lic_number, 1-8 digits — leading zeros optional, e.g. 7012 or 00007012). Per run it checks each watch against the same day's snapshot of the official bulk file and reports:

  • new — first time this license number was found (after baseline; the very first sighting of a watch is a free baseline, not billed).
  • status_changed — lic_status (Licensed / Licensed NBA) or the restricted_flag changed while the license stayed in the registry.
  • removed_from_registry — the license number, previously found, is now absent from the bulk file entirely (no row at all, under any role) on two consecutive daily runs. See "Honest limits" below — this is the disciplinary/lifecycle signal for this source, and it is a two-strike confirmation (see next section), not a single-run signal.
  • restored — a license previously confirmed removed_from_registry is found again (reissued/ reinstated).
  • candidate_removed — a license, previously found, is absent on this run for the first time. This is informational only: it is delivered with billed: false and never charges the license-status-changed event. If the license is found again on a later run before a second consecutive absence, the candidate is silently cancelled — nothing is billed either way.

Every genuine transition (new, status_changed, restored, and a confirmed removed_from_registry) is billed once under the same event; the same unchanged status is never billed twice, and candidate_removed is never billed.

Two-strike removal confirmation

A single run's snapshot integrity gate (see below) only proves the file isn't catastrophically truncated — it accepts a snapshot that is genuinely valid but 1-9% smaller than the last one (a normal, honest day of registry churn). At 429,000+ rows, that "acceptable" shrinkage window is on the order of tens of thousands of license numbers, so a single run's disappearance is not, by itself, strong enough evidence that DRE actually removed the license — the row could simply have landed in that legitimate day-to-day slack.

To avoid billing removed_from_registry on a false signal, this actor requires the disappearance to repeat on the next run before charging anyone:

  1. First consecutive absence of a previously-found, not-yet-removed license → recorded internally as a pending candidate and delivered as candidate_removed, billed: false. The license's last known status is left untouched in the actor's history — only a candidate flag is set.
  2. If the license is found again before a second consecutive absence, the candidate flag is simply cleared. Nothing is billed, nothing is reported as removed_from_registry or restored — as far as billing is concerned, this never happened.
  3. Second consecutive absence (the license is still missing on the very next run that itself passes the integrity gate) → now confirmed and billed as removed_from_registry, and the license is marked removed in history. A restored event (billable) can only happen after this confirmed state.

In short: the first disappearance is a free, unbilled warning; billing only happens once the same disappearance has been independently observed twice in a row.

Delivery/billing guarantee: at-most-once, not exactly-once

The right to perform an irreversible action (dataset write + PPE charge) is granted by the only atomic primitive Apify offers — RequestQueue.addRequest(uniqueKey) → wasAlreadyPresent — in a separate named queue that acts as a permanent journal (<prefix>-<monitorId>-claims). The Apify Key-Value Store has no CAS, no conditional write and no ETag, so it can only ever be a diagnostic state machine, never the source of at-most-once.

Concretely: for one computed event, delivery and charging each happen no more than once. If the run dies after taking the claim, the event may be lost (it stays dataset_unknown/charge_unknown and is never re-delivered) — but you will never be billed twice. That is a deliberate trade: "never overcharge" beats "never lose a row".

Boundaries of the guarantee, stated honestly:

  • Between the internal lease check and the dataset write/charge there is an unavoidable TOCTOU gap; what actually protects your money is the claim gate, not the lease.
  • The guarantee holds for as long as the named claims queue exists. Anyone with account access can delete or recreate it via Console/API, which starts the journal from zero. This is a boundary of any durable storage, not a defect of the protocol.
  • The guarantee applies from the build in which the claim gate was introduced onward. Older builds must not keep running against the same monitorId.

The free candidate_removed row is covered by the same rule: it costs nothing, but a dataset write is irreversible, so it passes through its own claim gate (a separate key namespace whose key contains no runId — it is keyed by the license number, its change sequence and the missing epoch, so a licence that disappears, comes back unchanged and disappears again gets a second, distinct right). Consequently that informational row is at-most-once as well: it may be lost, never duplicated. The two-strike confirmation itself is unaffected — it is driven by the durable index, not by whether the row was delivered.

Honest limits — read this before relying on removed_from_registry

  • The durable dataset is a delivery-attempt log, not a guaranteed mirror of the default dataset. Each row is written to the durable dataset first, then mirrored to the run's default dataset before billing proceeds for that row. If the durable write succeeds but the default-dataset mirror write fails (e.g. transient Apify storage error), the item is marked dataset_unknown, billing for it is permanently blocked (fail-closed — we never charge for a row we can't confirm was delivered), and the run is not retried into re-creating that exact row. The durable dataset can therefore end up with a small number of orphan rows that were never mirrored and never billed. The default dataset is the canonical log of rows successfully written to this run's output (see its run_summary row) — but a default-dataset row does not by itself prove the row was billed: the row is written before Actor.charge() runs, so if charging then fails or comes back charge_unknown, the row is present but not confirmably paid. run_summary.eventsBilled and Apify's own billing ledger are the source of truth for confirmed payment, not the presence of a row in either dataset.

California DRE's bulk file is not a historical record — it is a working list. Confirmed directly from DRE's own published record layout (Form RE 776, "Record Format — Licensee & Examinee data files"):

"This list includes only DRE Licensee's who have a DRE license status of 'Licensed' or 'Licensed NBA'."

That means a license that leaves Licensed/Licensed NBA status (revoked, suspended, surrendered, or simply expired without renewal) is not marked with a different status value the way Texas TREC does (status='Deleted' stays as an explicit value on the row) — it disappears from the file as a row, entirely. This actor treats that disappearance as the honest billable signal removed_from_registry, distinct from a real fetch failure (a corrupted/empty ZIP, a changed CSV header, or a violated uniqueness contract — those remain a fail-closed source_access_limited, with no baseline/history/billing change).

removed_from_registry is only ever emitted after the run's snapshot has passed a fail-closed integrity gate — never from any disappearance in a potentially truncated file. Before a single watch is classified as new/changed/removed, every run must validate the entire downloaded snapshot: the ZIP passes testzip() (no CRC corruption), it contains exactly one file named CurrList.csv (not zero, not more, not a different name), its decompressed size is under a sane cap, its bytes decode as strict UTF-8 (no silent replacement of invalid bytes), and the number of valid parsed rows is at least 300,000 and not a material drop (more than ~10%) from the row count of the last snapshot that itself passed this gate (persisted durably per monitor). If any of that fails, the run ends source_access_limited for every watch in the run — no baseline is read or written, no removed_from_registry/restored/status_changed event fires, and no charge happens for anyone. This exists specifically to close a gap where a syntactically valid but truncated ZIP (a cut-off download, a proxy returning a partial 200 response) would otherwise have looked like a legitimate, fully-updated snapshot and turned every previously-tracked license absent from the truncated file into a billable removed_from_registry. It catches catastrophic truncation, but a snapshot that legitimately shrinks by up to ~9% still passes — see "Two-strike removal confirmation" above for how billing still avoids acting on that gap from a single run.

What we verified live vs. what we did not, and why this matters: on 2026-09-13 we downloaded the live file (429,248 data rows), parsed its full structure, cross-checked several restricted_flag=Y records, and independently confirmed the quoted sentence above by downloading and parsing DRE's own RE 776 format document. What we did not do — because the source updates once a day and the build window was a few hours, not a day-plus — is watch one specific, real license actually leave the file between two runs and confirm no other explanation fits. The "disappearance = left Licensed/Licensed NBA (commonly expiration, surrender, or revocation)" conclusion rests on DRE's own documented file contract, not on an observed live transition of a real record. If a future run of this actor (or an audit) ever finds a disappearance that is better explained by something else, that is a real bug report, not an expected edge case.

A removed_from_registry event never tells you why. It does not distinguish "license expired and was not renewed" from "license was revoked for cause" — DRE's bulk file does not carry that distinction at all. For anything consequential, follow up at secure.dre.ca.gov/publicasp/pplinfo.asp (which does show a license's current standing and, separately, DRE's public disciplinary actions page) before acting.

License numbers are not always unique rows. A person can appear more than once in the same file — once under their own license (Broker/Salesperson/Corporation) and again for each corporation where they are a registered Officer. Confirmed live against the full file (2026-09-13): of 406,503 distinct license numbers, 405,051 (99.6%) have exactly one "own" row; 1,452 (0.4%) have none of their own (their personal license is not currently in the list, but they remain an Officer of an active corporation — the officer row with the lowest affiliated corporation number is used); zero have more than one "own" row. If that last count is ever non-zero in a future snapshot, the actor treats it as a broken source contract (source_access_limited) rather than guessing which row is "the" license.

Restricted ≠ revoked. restricted_flag=Y (2,282 of 429,248 rows on 2026-09-13) means DRE's own documented meaning, "License is restricted" — commonly a condition/probation-style restriction. It is tracked and billed as a status-relevant change, but it is not itself a revocation, and Licensed NBA is not a disciplinary status either — DRE documents it as "the license is in a non-working status" (no broker affiliation for a salesperson, or no business address on file for a broker/corporation), an administrative state, not misconduct.

Fast health check / probeOnly mode

  • probeOnly (boolean, default: false, prefill: true): When set to true, the actor only checks network connectivity and HTTP availability of the official CA DRE source (https://secure.dre.ca.gov/datafile/CurrList.zip) via a lightweight HTTP HEAD / Range request. It verifies the source is online, writes a health check receipt to the dataset, and exits in seconds (under 5 seconds) with exit code 0 without downloading the full 70MB dataset or billing any events. Recommended for health checks, uptime monitors, and platform QA tests.

Coverage and billing record

Every run writes a coverage record with per-watch status/reason/matched, removedFromRegistryCount (confirmed, billed second-strike removals only), pendingRemovalCandidateCount (unbilled first-strike candidates from this run), and recordsDelivered/recordsBilled — enough to reconcile every charge against every row. A watch that never matched (typo, or a license number DRE has never issued) is reported as matched: false, status: "ok" — not an error.

What it does not do

  • Does not search by name — you provide the license number.
  • Does not scrape any DRE web page; it uses DRE's own official daily bulk export.
  • Does not retain or re-deliver a status that has not changed.
  • Does not cover license types outside the DRE registry (brokers, salespersons, corporations, and their officer affiliations) — no mortgage loan originator (NMLS) or broker-associate data.