Wellfound Startup Jobs Scraper avatar

Wellfound Startup Jobs Scraper

Pricing

from $2.50 / 1,000 dataset items

Go to Apify Store
Wellfound Startup Jobs Scraper

Wellfound Startup Jobs Scraper

Find and monitor startup roles for recruiters, analysts, and job seekers. Returns structured compensation, remote-work, company, location, and listing details. Includes compact output for agent workflows.

Pricing

from $2.50 / 1,000 dataset items

Rating

0.0

(0)

Developer

NaNomicon

NaNomicon

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

12 hours ago

Last modified

Share

Scrape Wellfound (formerly AngelList) startup job listings — structured salaries, equity, remote policy, and company data. Built for recruiters, analysts, job-seekers, and AI agents.

Why this one over the alternatives:

  • Fails loudly. Zero results or a site change = explicit error naming what broke — never a silent empty run burning your quota (the #1 complaint about other Wellfound scrapers).
  • Fresh and maintained. Daily builds; when the site changes we ship fixes within a day.
  • Cheap. Low platform usage we pass on to you.
  • Incremental by default. Repeat runs emit only NEW jobs — build job alerts without deduplicating anything yourself.
  • Webhook notifications. Optional secret webhookUrl receives one JSON notification after each run writes newly emitted jobs.
  • Stale-tolerant cache mode. $0.0005/result snapshots for agents that want bulk data fast and accept some staleness.

What you get

FieldExample
titleSenior Backend Engineer
companyVirta Health
comp$114k – $148k
salaryMin / salaryMax / salaryCurrency114000 / 148000 / USD
equityMinPct / equityMaxPct0.1 / 0.5
jobTypefull-time
remote / remoteKindtrue / "worldwide"
locations["United States"]
yearsExperienceMin / yearsExperienceMax2 / 5
postedAt1791847814 (unix)
descriptionbyte-identical text excerpt by default
companyUrldirect startup profile URL
companySize, companyHighConcept, companyLogoUrlwith enrich: true; no extra fetches or charges
companyBadgescomplete set of distinct, non-empty badge labels in first-seen order; whitespace-only labels ignored; labels kept verbatim; no badge-name allowlist
companyStage / companyFundingStagemachine-readable funding-stage token / display label from the same stage badge; token kept verbatim with no token allowlist
companyYcFundedtrue when the company carries a YC badge
descriptionMarkdownoptional; when descriptionFormat: "markdown"
descriptionHtmloptional; when descriptionFormat: "html"
urldirect job listing URL

With enrich: true, matching job rows include available company fields from data collected during the crawl. These fields add no fetches or charges. A missing company badge or funding-stage field means the source did not report a usable value for it — not that the company has no stage and is not YC-backed; the actor omits the key and never emits null. company-rollups always includes per-company open-role counts, salary medians, recent hiring, top titles, and remote share; rollups are free. The five single-valued company string fields (companySize, companyHighConcept, companyLogoUrl, companyStage, companyFundingStage) use the most frequent value across the company's jobs, with ties broken alphabetically. companyBadges in a rollup row is the ordered distinct union across the company's jobs; companyYcFunded is true if any of the company's jobs carries it.

companyStage is the machine-readable funding-stage token, taken verbatim from the stage badge; companyFundingStage is the display label of that same badge. companyYcFunded is true when the company carries a YC badge.

description remains the byte-identical default text excerpt; descriptionMarkdown or descriptionHtml is returned only when the matching format is requested.

Quick start

  1. Run with defaults — crawls software-engineer + backend-developer roles.
  2. Second run with the same input emits only newly posted jobs.
  3. Set compact: true for core fields only; set enrich: true to include available company fields at no extra charge.
{
"roleSlugs": ["software-engineer", "backend-developer"],
"keywords": [],
"locations": [],
"maxJobs": 500,
"maxFetches": 30,
"postedWithinDays": 7,
"minComp": 100000,
"compact": false,
"enrich": false,
"descriptionFormat": "text"
}

roleSlugs, keywords, and locations suggestions are non-exhaustive; custom slugs are allowed. To find a slug, open the matching Wellfound page and copy the URL path segment: after /role/r/ for roleSlugs, after /role/ for job-title keywords, or after /location/ for locations. Enter the slug, not the full URL or display name. For example, /location/new-york-city-ny uses slug new-york-city-ny. Wellfound pages and available listings can change.

Webhooks and description formats

  • Webhook notifications. Optional secret webhookUrl receives one application/json POST per run after dataset output is written, only when fresh jobs were emitted. Payload includes runId, actorId, runUrl, counts (new, totalEmitted), up to 50 newest compact jobs, datasetUrl, and crawledAt. Webhook failures warn but do not fail the run or lose data; requests time out after 10 seconds and retry once.
  • Description format. descriptionFormat accepts text (default), markdown, or html. Default description excerpt stays byte-identical; requested formats add optional descriptionMarkdown or descriptionHtml.

Pricing

  • $0.01 per run (apify-actor-start).
  • $0.0025 per fresh job (apify-default-dataset-item).
  • $0.0005 per cached job (cached-result).
  • A 1,000-job fresh run ≈ $2.51. Company fields with enrich: true add no fetches or charges.

Filters

  • roleSlugs — remote role pages; suggested values are non-exhaustive; custom Wellfound slugs are allowed.
  • keywords — additional job-title slugs, not arbitrary free-text keywords; fetched as general Wellfound role pages.
  • locations — location slugs; suggestions are non-exhaustive; custom values are slugified before fetching.
  • postedWithinDays — only jobs posted in the last N days.
  • minComp / minYears — lower bounds on salary / required experience.
  • maxJobs defaults to 500; maxFetches defaults to 30 and caps role and seed-page fetches only.
  • enrich — include available company fields; output toggle, no extra fetch or charge; default false.
  • descriptionFormat — text (default), markdown, or html; default text description is unchanged.
  • webhookUrl — optional secret endpoint; one post after emitted jobs are written, fail-soft with one retry.
  • cached / maxCacheAgeHours — snapshot serving and its freshness limit.

Recipes

  • Job alert: schedule identical input with postedWithinDays and maxJobs. Incremental state emits only new jobs; read the default dataset after each successful run and use a webhook to trigger downstream processing.

Reliability contract

  • Crawl fails loudly on: zero usable results, unparseable site state, missing company anchors, >5% fetch errors. Every failure names the cause.
  • Incremental state is keyed to your exact input — change the input, get a clean partition. Clear the actor's key-value store to reset.
  • Memory-capped 256–1024 MB: predictable platform cost.

For AI agents

Machine-readable docs: ./AGENTS.md — exact input/output schemas, pricing events, error semantics, and a copy-paste run command. Output fields are stable; compact: true returns the core subset agents need. If you are driving this actor from an LLM tool-call, read AGENTS.md, not this README.

Store sync

scripts/sync_store_state.py compares live Store metadata with .actor/store-state.desired.json; read-only by default, --apply writes. --publish authorizes public flips; --unpublish authorizes private flips; neither authorizes the other. Both checks are change-based: an apply leaving isPublic unchanged needs no flag. Refused apply sends no request; refusal happens before the write. Visibility flips are human decisions; the tool refuses to guess. Store categories are pinned to JOBS, LEAD_GENERATION, AGENTS in .actor/store-state.desired.json; --apply writes them (no flag needed — categories are not a visibility flip). The Store's example run input is kept in .actor/example-run-input.json; set it on the actor's exampleRunInput field so a Console test run uses a real input instead of the template placeholder. scripts/set_example_run_input.py applies it (--check to compare, --dry-run to preview; a bare run applies); the Apify CLI cannot set this field, so the script updates the actor's exampleRunInput field through the documented actor update endpoint (only that field is sent).

FAQ

Is this affiliated with Wellfound? No. Independent public-data extraction. Why does a run return 0 results but succeed? It doesn't — empty crawls fail with a reason. A successful run with no NEW jobs means everything was already emitted (incremental mode working). Blocked or empty? Open an issue with the run ID — failures are explicit by design, so support starts from the real error.