# Changelog of New Contractor License Leads 🛠️ (CA, FL, TX) (`tagadanar/contractor-license-leads`) Actor

- **URL**: https://apify.com/tagadanar/contractor-license-leads/changelog.md
- **Full Actor documentation**: https://apify.com/tagadanar/contractor-license-leads.md

## Changelog

### 2026-09-19

- **California works again.** The CSLB data portal changed how it handles sessions, and since about 1 September every California scan ended with "the license registry refused this run's requests" and no leads. Fixed: California scans, including the default example input, return leads again. Texas and Florida were not affected.
- That message also blamed a network block it had not verified. It now reports only what happened.

### 2026-09-02

- A registry fetch that fails on the proxy fallback now logs the real reason (undici hid it behind "fetch failed").
- A registry that answers 403/429/503 on both paths is reported as a block of our network, not as a "temporary source issue".

### 2026-08-29

- A run that asks for Texas without delta mode no longer claims Texas was read.
  TDLR publishes no license issue dates, so a date-window run skips it before
  any request is made — but the state landed in neither the "partial" nor the
  "skipped" list, and the summary said "Every requested registry (TX) was read
  in full, so there are genuinely no matching licenses". It now says "TX was not
  read: TDLR publishes no license issue dates, so Texas needs deltaMode", names
  only the registries that really were read end to end, and reports the run as
  partial rather than empty.
- The README now states the actual per-lead price ($0.08 per lead, $0.01 per run
  start) instead of "a few dollars".
- Runs no longer time out inside a registry **download**. The 2026-08-05 fix
  stopped a scan between rows, but a download that had not yet produced a row
  could not be stopped at all: the California portal's multi-step download, the
  two Florida extracts and the Texas pages each ran without any wall-clock
  limit, and a second state would start a fresh multi-megabyte download on time
  the first one had already spent. Every registry request is now bounded by the
  time the run actually has left, mid-download included, and a state that
  cannot be started is skipped instead of taking the run down with it.
- A run that stops on its own clock now says so plainly, with the number of
  leads it delivered and what to change: "Stopped at the run time limit… Raise
  the run timeout or ask for fewer states per run." Leads already collected are
  charged and pushed either way.
- A short run timeout no longer produces a run that gives up before it starts.
  The runway reserved for delivering leads is now capped at half the run, so a
  60-second run still spends 30 seconds scanning instead of reporting that it
  ran out of time immediately.
- "No leads found" is still only ever said when every registry you asked for
  was read in full — a scan cut short by the clock says that instead.

### 2026-08-05

- Runs stop as soon as they have the leads you asked for again. The 2026-08-02
  release made every California and Florida run read the whole registry before
  returning anything, so a run capped at 25 leads paid for the full 75 MB
  download. Short runs are back to finishing in seconds.
- A run can no longer time out inside a registry download. If the scan cannot
  finish within the run's timeout it stops, returns what it found, and says so
  in the run summary instead of ending with no results at all.
- An empty result from a scan that was cut short now says the registry was only
  read in part, rather than reporting it as "no new licenses".
- The shared daily registry snapshot is still written, but only by runs that
  read a registry all the way through — a partial read is never cached.

### 2026-08-02

- California runs are now much faster after the first one each day. The CSLB
  master file is downloaded once per day and shared by every later run, the
  way Florida already worked.
- A California download that gets cut short by the CSLB portal no longer ends
  the run: the licenses that did arrive are still returned, and that partial
  scan is not reused by later runs.

### 2026-07-17 v0.1.0

- Initial release. Newly issued contractor licenses from the three official
  registries: CA CSLB master file (ASP.NET portal, ~75 MB CSV streamed), FL
  DBPR construction + electrical board extracts (~52 MB, streamed, both legacy
  headerless and headered layouts supported), TX TDLR via the Socrata API on
  data.texas.gov (server-side license-type filter).
- Two modes: date window (CA/FL, `issuedWithinDays` / `issuedSince`) and delta
  (`deltaMode`, required for TX which publishes no issue dates; first TX run
  seeds an uncharged baseline). Seen-set in a named KV store, 180-day pruning,
  leads marked seen only after charge + push.
- Cross-state normalized lead schema (license number, business, owner, phone,
  address, classifications, issue date, status, source attribution).
  Classification filter matches codes and names, dash/case-insensitive.
- Fleet conventions: list-input coercion with alias unwrapping, bad input exits
  SUCCEEDED with a status message, fail-closed billing (charge before push),
  actor-start floor charged before validation. Streaming CSV parser keeps
  memory flat regardless of file size.
- Live-tested 2026-07-17: FL 194,697 rows streamed, 25 real leads with July
  issue dates; CA portal double-postback + 112,824 rows streamed, 15 leads
  with phones; TX delta baseline 37,834 licenses seeded then a clean 0-new
  second run. Peak RSS 151 MB (TX baseline) so memory 512 MB.
- Intended pricing (Console, at publish): `lead-found` $0.08 list with
  Bronze/Silver/Gold tiers (market anchor: retail contractor leads sell for
  $20+ each; $0.08 = $80/1k), `actor-start` $0.001 floor. No proxy input
  exists; run cost is compute + registry transfer only.
- Payer decision 2026-07-17 (platform measurements): USER-PAYS at first
  publish. FL DBPR 403s Apify runtime IPs and tarpits datacenter proxy, so FL
  scans fall back to residential internally (direct-first in `src/net.js`, no
  proxy input). The FL scan was a fixed ~33 MB residential transfer ($0.26
  measured, ~$0.42 worst case) independent of yield. CA measured $0.0016/run
  direct (no proxy), TX is a keyless Socrata API. Platform peaks 84-91 MB,
  memory 512.

### 2026-07-17 v0.1.6 (same day)

- Flipped to all-in pricing (we pay platform usage) to match the field: the
  contractor-license market on the Store is overwhelmingly all-in. Made safe
  by a daily shared FL registry snapshot: the first FL scan of the day
  downloads the DBPR extracts once and caches every dated row of the last 370
  days in a named KV store; every later FL run that day reads the snapshot
  for pennies. Runs asking for issue dates older than the cached window
  bypass the cache. Worst-case residential exposure is bounded at one
  download per day, not per run.
- Prefill (daily auto-test) moved from FL to CA, which runs direct with no
  proxy at all.
- Run start fee raised to $0.01 (market-normal: rivals charge $0.004-0.0055)
  so zero-yield CA/TX runs stay net-positive on compute.
