# Changelog of Crunchbase Company Intelligence — Firmographics & Contact (`foxlabs/crunchbase-company-intelligence`) Actor

- **URL**: https://apify.com/foxlabs/crunchbase-company-intelligence/changelog.md
- **Full Actor documentation**: https://apify.com/foxlabs/crunchbase-company-intelligence.md

## Changelog

### 0.1.12 — 2026-10-14 — companies are read in parallel; cheaper per company

- Companies are now read in small groups through the one cleared session instead of strictly one after another. The reads are short JSON calls over a residential exit, so waiting for them serially was most of a run's wall-clock — and compute is billed by time.
- A withdrawn session fails a whole group at once; the session is repaired and only that group's companies are retried.
- Groups of 3 (`readConcurrency`, 1–8). Companies Crunchbase refused during the batch get a second pass at the end, one at a time on a repaired session — refusals during a wobble are recovered instead of being sold as a miss.

### 0.1.11 — 2026-10-14 — pricing

- Pay-per-event: **$0.012** per company delivered, plus a **$0.02 Crunchbase session** charged once per run, on the first company actually delivered. A run that comes back empty costs nothing, and companies that cannot be resolved or that Crunchbase refuses stay free.
- The session fee is the real fixed cost of a run, measured on the platform: launching the browser and clearing the anti-bot challenge costs about $0.025 before a single company is read. Charging it once keeps the per-company price inside the market band instead of loading that cost onto every record.

### 0.1.10 — 2026-10-14 — batches no longer stall after ~10 companies; a refused read is never called "not found"

- **Crunchbase withdraws a cleared session part-way through a batch.** Measured: a 25-company run delivered 9 and reported the other 16 as "not found" (run LvS0iNDH9aMl9VKXy) — yet all 16 resolved normally on a fresh session (run vZ5kpjFmjl1H3vLz1, 3/3). The actor now notices the withdrawal, sits through the challenge again on the same exit IP, and retries the company; if that fails it relaunches on a new exit IP (up to 3 times per run).
- **Only HTTP 404 counts as "not found".** Any other failed read (403, 429, 5xx, network) is reported as "Crunchbase refused the request" and is never charged. Before this, a refused read was reported — and would have been sold — as a company that does not exist.
- Companies are paced ~0.6 s apart; bursts are what cost the session.

### 0.1.9 — 2026-10-14 — pay-per-event charging

- Charges two events: `crunchbase-session` once per run and `company-record` for each company delivered. The session is charged only after the anti-bot challenge clears, so a run that Crunchbase refuses costs nothing; a company that cannot be resolved, or that Crunchbase refuses, is never charged.

### 0.1.0 — 2026-10-11

- Initial release. Name / domain / Crunchbase URL / permalink → public Crunchbase profile: description, website, employee range, HQ, categories, Crunchbase rank, IPO/operating status, contact email & phone, social profiles and funding signals.
- Clears Crunchbase's Cloudflare managed (Turnstile) challenge with a self-hosted hardened Firefox (Camoufox), **headless** — no paid unblocking service. The challenge is cleared once per run; every company is then fetched same-origin as clean `/v4/data` JSON.
- Domain inputs are resolved via Crunchbase autocomplete using the brand label and **verified against the company's own website**, so `stripe.com` → Stripe (not Stripe Capital) and `nvidia.com` → NVIDIA.
- Funding amount (`fundingTotalUsd`) and founded date (`foundedOn`) are paywalled by Crunchbase for logged-out sessions: they are returned as `null` with a `paywalledFieldsNeedLogin` flag and can be unlocked by supplying a Crunchbase session cookie (BYOC). No paywall is bypassed.
- Runs on Apify's `actor-node-playwright-camoufox` base image (Node 24, Playwright pinned 1.59.1). The image installs production deps without omitting optional ones, so `camoufox-js`'s `impit` native bindings load correctly.
- Routes the browser through a proxy (default: Apify Residential) because Crunchbase scores datacenter exit IPs — the Cloudflare challenge does not clear from a plain datacenter container IP. `geoip` aligns the fingerprint to the proxy location. Bring your own clean proxy via `proxyConfiguration`.
- Rotates the exit IP on failure: up to 4 attempts, each through a fresh proxy session, and reloads once mid-challenge — residential pools vary IP-by-IP against Turnstile.
- Runs the browser **headful** (under the base image's xvfb) and **clicks the interactive Turnstile checkbox** when Cloudflare escalates to it on a marginal IP, instead of only waiting passively. `disable_coop` enables reaching the cross-origin Turnstile iframe. This is what makes the challenge clear reliably without a clean dedicated proxy.
- A dead proxy IP (geoip lookup fails at launch) now rotates to the next IP instead of failing the whole run; each IP gets a short (~38s) window so a clean one is found quickly.
- **Caches the exit that cleared** (in a named, cross-run key-value store) and tries it first next run — the sticky session re-requests the same IP, so repeat runs usually skip the dirty-IP rotation (faster and more reliable). Falls back to rotation if the cached exit no longer clears.
