Scrape Wellfound (AngelList) startup jobs with the data most boards never publish: equity ranges parsed into numbers, alongside salary, company size and stage. Pick the role pages you want by slug. No browser, no proxy, no login, no cookies. Filter by equity, remote, tech stack or salary.
Fixed 🔴 — the default configuration returned ZERO rows
The first thing a new buyer does returned nothing, and reported success.
roles defaulted via input.roles ?? ['devops-engineer']. Apify applies
INPUT_SCHEMA defaults to getInput(), so an unset roles arrives as [] — not
undefined — and [] ?? x is []. The code default was unreachable, so a run
with the prefilled defaults fetched no role pages at all: 0 rows, exit
SUCCEEDED.
Fixed in both places, deliberately: INPUT_SCHEMA now carries the real default
(["devops-engineer"]), and the code falls back on emptiness rather than on
undefined, so the actor cannot be talked into fetching nothing.
Measured: 0 rows → 25 rows on the default configuration.
Added — a zero-row run now says why, and fails
Adopts the shared src/kit/, generated from apify-actor-kit.
Too-narrow filters, every role page refused, and a change in Wellfound's page data
are now three distinct, named, failing outcomes with a per-filter breakdown.
failOnZeroResults (default true) opts back into quiet green runs. A refused role
page is counted rather than only logged, so blocked reaches the diagnosis.
Fixed — useResidentialProxies advertised something it does not do
The input has been a no-op since 2.0.0 (the HTTP path needs no proxy), while its
schema still read "recommended, costs more but avoids blocks" and defaulted to
true. Now titled deprecated — no-op, described truthfully, and defaulted to
false. Residential proxy is billed at $10/GB; advertising it as recommended for a
path that never uses it is the worst kind of harmless.
Fixed — maxJobs advertised a ceiling it cannot reach
The schema offered up to 1,000. Each Wellfound role page is a single
un-paginated request carrying roughly 25 listings (measured 2026-08-27), so the
real ceiling is ~25 × the number of roles. Maximum corrected to 200.
Changed
One batched Actor.pushData() per run instead of one call per row.
Note: the 2.0.0 rewrite (browser → __NEXT_DATA__ over HTTP, 2026-08-14)
predates this changelog's coverage and is recorded in the TQM vault's
Scraper Commercialisation Plan §2.
Unreleased — 2026-08-13
Documentation only. No behavior changes; build 0.0.4 is unmodified.
Added
Full documentation suite: docs/ARCHITECTURE.md, docs/DEVELOPMENT.md, docs/WELLFOUND-DOM.md,
docs/IMPROVEMENT-PLAN.md, and CLAUDE.md.
.actor/dataset_schema.json — the output surface was previously undeclared, and now carries
per-field status warnings.
README rewritten as a buyer-facing listing with a "partially working, not ready to sell" banner
and a per-field status table.
Verified against live Wellfound
Two platform runs on 2026-08-13, both with useResidentialProxies: false:
Input
Rows
Cost
Duration
maxJobs: 10
50
$0.0548
221 s
maxJobs: 100
50
$0.0883
370 s
~$1.77 per 1,000 rows — the most expensive actor in the portfolio, roughly 30× the HTTP-based
siblings, because it renders ~51 browser pages per run.
Assessment corrected
An earlier reading of the run — "SUCCEEDED, 50 rows, highest yield after HackerNews" — was wrong.
Row count is not a working scraper. Field-level inspection shows most of the output is unusable:
Field
Status
title, jobUrl, jobId, salary*
✅ genuinely work
company
🔴 never extracts — 2 distinct values across 50 rows ("About the job", "Unknown")
location
🔴 never extracts — always "Not specified"
role
🔴 never extracts — always ""
remote
🔴 true on 49/50 — keyword-matched against the whole page
Detail-page selectors are [class*="…"] guesses written without a captured page; Wellfound ships
hashed CSS class names, so none match. The company selector falls through to the first <h2>,
which reads "About the job".
maxJobs is inert. The listing loop checks processedCount >= maxJobs before queueing, but
processedCount is only incremented in the detail handler, which hasn't run — so it is 0
throughout and the break never fires. Verified: 10 and 100 both return 50.
remote, hasEquity and techStack are matched against document.body.textContent, so
Wellfound's own navigation and marketing copy answer for the job.
Row 0 is the login wall — <h1> is "Find what's next", which passes the only validity gate.
useResidentialProxies defaults to true; on an account with no residential capacity the default
configuration cannot run.
currency is hard-coded "USD"; the salary regex reads max by computed array index.
The jobId fallback embeds Date.now().
The roles filter is doubly broken — role never extracts, so the filter is always skipped.
Fixed delay() calls total ~100 s of sleeping per run.
All are itemized and prioritized in docs/IMPROVEMENT-PLAN.md, which flags one investigation to run
before any selector work: capture a real detail page and check for JSON-LD or __NEXT_DATA__,
which would likely resolve most items at once.
This actor should not be listed for sale until improvement-plan items 1–3 are fixed.
0.0.4 and earlier
No changelog was kept. Build 0.0.4 is the deployed build as of 2026-08-13; the last source commit
was 2025-11-16. The actor carried the platform title "Wellfound Scraper - not working yet" until
2026-08-13.