# Changelog of California Construction Trades Directory & Leads (CSLB) (`scrapebench/california-construction-trades-directory`) Actor

- **URL**: https://apify.com/scrapebench/california-construction-trades-directory/changelog.md
- **Full Actor documentation**: https://apify.com/scrapebench/california-construction-trades-directory.md

## Changelog

### 0.1.2 — 2026-08-23

- **Large sweeps no longer time out.** Results were delivered and charged one row at a time, which
  measured ~0.25s per row on the platform — 21s of a 28s run for 85 rows, against 1.9s of actual
  scraping. The actor's own default input returns 12,894 contractors, so a default run spent ~54
  minutes on API round trips against a 3600s limit, and the same thirteen trades across Los Angeles
  (39,558 contractors) needed about 2.7 hours. Three of a buyer's four runs timed out. Rows are now
  delivered 1,000 at a time with one charge per batch, which takes the Los Angeles sweep to roughly
  40 round trips. Order is still push-then-charge, so nobody is billed for a row they did not get.
- **The pricing example was understated 5.4×.** The listing quoted the default sweep as ~2,400 rows
  / $4.80; it is 12,894 rows / $25.79 (measured 2026-08-23). Corrected, along with a note that
  `maxResults` is a cap **per trade** — 500 across thirteen trades allows up to 6,500 rows.

### 0.1.1 — 2026-08-20

- **A CSLB outage is now reported, not hidden.** When the state portal is down it redirects every
  request to a Department of Consumer Affairs maintenance page, which looks like an ordinary
  successful page load. The sweep used to treat that as "none of your counties exist" and finish
  with zero rows. It now returns a single free row explaining that CSLB is not answering, so an
  empty sweep can never be mistaken for a quiet market. That row is never charged.

### 0.1 — 2026-08-19

Initial release.

- Sweeps a list of CSLB trades across a list of California counties in one run.
- All requested counties are fetched in a **single request per trade**: `lbCounty` is genuinely
  multi-select (measured 2026-08-19 — Contra Costa 493 + Sonoma 365 + Solano 140 + Napa 98 =
  1,096 rows in one POST).
- Classifications are looped one per request on purpose. CSLB accepts several
  `lbClassification` values and silently honours exactly **one** — whichever appears earliest in
  the form's option order, not the first or last submitted — returning 200 with a valid
  spreadsheet for the wrong trade. Measured: `[C-27, C-36]` and `[C-36, C-27]` both return the
  same 463 C-27 rows, while `[C-36]` alone returns 400 rows neither contained. `_post_list` takes
  a single classification by construction and a regression test asserts it.
- Deduplicated by licence number across the whole sweep before charging, so a contractor holding
  several of the requested trades is one row and one charge. Each row carries `matched_trade`.
- Unusable input (no trades, no counties, or no county that resolves) returns the free county
  list; a genuinely empty sweep returns a free `Notice` row. Neither is ever a failed run.
- Proxy off by default — CSLB answers Apify's platform IPs directly (measured 2026-08-19).
