Wellfound Jobs Scraper — Startup Roles, Salary & Equity avatar

Wellfound Jobs Scraper — Startup Roles, Salary & Equity

Pricing

from $0.60 / 1,000 job postings

Go to Apify Store
Wellfound Jobs Scraper — Startup Roles, Salary & Equity

Wellfound Jobs Scraper — Startup Roles, Salary & Equity

Startup jobs from Wellfound's public role listings, by role and city or remote: title, salary and equity as shown, location, remote policy, experience, posting date, ATS, and each startup's size, stage, badges and pitch. No browser, no key, no recruiter contacts.

Pricing

from $0.60 / 1,000 job postings

Rating

0.0

(0)

Developer

Insight Solutions

Insight Solutions

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Security

Limited permissions

Share

Role and city in, startup jobs out. Give this Actor a few roles — software-engineer, product-manager, data-scientist — and where: remote, new-york, san-francisco, Austin, TX. It reads Wellfound's public role listings and returns one row per job: title, salary and equity as Wellfound shows them (and as numbers), locations, remote policy and the countries a remote hire may live in, job type, years of experience, seniority, posting date, the ATS the job is synced from, and the full description as plain text.

Every job carries its startup's facts from the same page: size band, stage (Early, Growth, Scale, Public), Wellfound's badges (YC, TOP_INVESTORS, GROWING_FAST, ACTIVELY_HIRING, B2B…), the one-line pitch and the logo — and each startup also comes back once as a free company row. HTTP only: no browser, no login, no cookies, no API key.

No recruiter contacts, by design: e-mail addresses, phone numbers, profile links and every sentence that names a recruiter, founder or other person are removed from descriptions. $1.00 per 1,000 jobs on the FREE tier; company rows and diagnostics are free.

Hiring on company career sites rather than on Wellfound? Career Site Jobs API reads Greenhouse, Lever, Ashby and 10+ more ATS boards, Careers Page Jobs API starts from a company domain, and Remote Jobs API merges the remote-only job boards. This one is for startup jobs, with the salary, equity and company stage startups publish on Wellfound.

Try it in 30 seconds

This is the Store prefill; paste it and run:

{ "roles": ["software-engineer", "product-manager"], "locations": ["remote", "new-york"], "maxJobsPerSearch": 80 }

Four searches — each role remote and in New York — of up to 80 jobs each: about ten listing pages, each request at least half a second after the last, so the run finishes in well under a minute and returns up to 320 jobs (a job listed under two searches is returned once). Our offline test suite runs it against the captured pages and gets 101 distinct jobs from 59 startups; a live run reads live pages.

Remote engineering roles that went live this week, with a salary of at least $150k shown:

{ "roles": ["software-engineer", "frontend-engineer", "backend-developer", "data-engineer"], "locations": ["remote"], "postedWithinDays": 7, "minSalary": 150000 }

Titles work too, and cities as you would write them:

{ "roles": ["Product Designer", "ML engineer"], "locations": ["San Francisco", "Austin, TX", "NYC"], "includeDetails": true, "maxJobsPerSearch": 40 }

From code — client.actor("insight.solutions/wellfound-jobs-api").call(run_input={"roles": ["software-engineer"], "locations": ["remote"]}) with apify-client, or POST https://api.apify.com/v2/acts/insight.solutions~wellfound-jobs-api/run-sync-get-dataset-items.

What comes back

A job row (from the captured Austin listing of 2026-11-04; the description shortened):

{
"rowType": "job",
"role": "software-engineer",
"location": "austin",
"searchUrl": "https://wellfound.com/role/l/software-engineer/austin",
"jobId": "4716782",
"title": "Software Engineer",
"url": "https://wellfound.com/jobs/4716782-software-engineer",
"company": "Boom",
"companySlug": "boom-app",
"companyUrl": "https://wellfound.com/company/boom-app",
"companySize": "11-50",
"companyStage": "Early Stage",
"companyHighConcept": "Modern rental financial services for property managers and renters",
"companyBadges": ["ACTIVELY_HIRING", "B2C", "GROWING_FAST"],
"locations": ["Austin"],
"remote": false,
"jobType": "full-time",
"compensation": "$120k – $200k • 0.01% – 0.15%",
"salaryMin": 120000,
"salaryMax": 200000,
"salaryCurrency": "USD",
"salaryPeriod": "year",
"equityMin": 0.01,
"equityMax": 0.15,
"postedAt": "2026-09-15T00:00:52.000Z",
"atsSource": "ashby",
"description": "Software Engineer\n\nWe hire software engineers across levels under a single posting. Title, compensation, and scope are set during the process based on demonstrated competency, so apply once and we will place you at the right level. …",
"scrapedAt": "2026-11-04T12:00:00.000Z"
}

That posting's company paragraph names its founder and its angel investors; those two sentences are gone from description ("Now serving thousands of renters, Boom is led by …"), and the rest of the paragraph is kept.

A company row, one per startup seen, free:

{
"rowType": "company",
"companySlug": "methodfi",
"name": "Method Financial",
"size": "51-200",
"stage": "Growth Stage",
"badges": ["ACTIVELY_HIRING", "B2B", "TOP_INVESTORS", "YC", "GROWING_FAST"],
"highConcept": "The future of financial account connectivity",
"jobCount": 2,
"jobsListed": 2,
"companyUrl": "https://wellfound.com/company/methodfi"
}

A search that returned nothing comes back as a free diagnostic row saying why — unresolved, blocked, no-jobs, parse-failed, timeout or invalid-input — and the last row of every run is a free summary with what each search read and why it stopped.

Use cases

  • Startup job boards and newsletters — schedule it daily over the roles your readers want and publish what is new, with salary and equity ranges already split into numbers.
  • Compensation research — salary and equity bands per role, city, company stage and size, from what startups publish themselves.
  • Recruiting and talent sourcing — which startups are hiring for a role right now, how big they are, what stage, whether they are YC or backed by top investors.
  • Sales and partnerships — hiring is a buying signal: startups opening engineering or sales roles, with their stage, size and pitch, as one free company row each.
  • Market maps — which kinds of startups hire where: the company rows give stage, size and badges per startup across your searches.

How it compares

  • Wellfound's own listing data, not scraped text. The jobs, their startups and the badges are read from the structured data Wellfound embeds in its own listing pages, so every field is the value Wellfound shows — nothing is guessed from layout.
  • Salary and equity as numbers, next to the text. $120k – $200k • 0.01% – 0.15% becomes salaryMin, salaryMax, salaryCurrency, equityMin and equityMax, and the original string is kept in compensation.
  • Company facts on every job. Size, stage, badges and pitch ride along on each job row, and each startup is also one free company row — no second lookup.
  • No browser, no session, no workaround. Plain HTTP through Apify's datacenter proxy. If Wellfound answers with its security check, the run stops after that one request and says so in a free row; it is never worked around.
  • No recruiters. Contact details and people's names are removed from descriptions before a row is written.

Where the data comes from

Three kinds of public wellfound.com pages, and nothing else:

  • Role listings by city — https://wellfound.com/role/l/<role>/<city>, then ?page=2, ?page=3… Each page lists 20 startups with their highlighted jobs (30–40 jobs a page in our captures) and states how many pages and jobs the listing has.
  • Remote role listings — https://wellfound.com/role/r/<role>, paged the same way.
  • Job pages — https://wellfound.com/jobs/<id>-<slug>, only with includeDetails: their schema.org JobPosting adds the company website, industry, employment type, structured locations and benefits.

Role slugs are Wellfound's own: this Actor knows 67 seen on Wellfound's listing pages (plus a few common ones), maps titles and abbreviations to them, and passes any other slug through as written. City slugs likewise (new-york, san-francisco, los-angeles, austin, seattle, boston, chicago, denver, district-of-columbia…). A slug Wellfound does not have answers 404 and comes back as a free unresolved row.

Company profile pages are behind Wellfound's security check and are never requested; company facts come from the listing pages. Search forms and query URLs that Wellfound's robots.txt disallows (?jobId=, ?role=, /_jobs/, /search) are never built: the only query string ever sent is ?page=N.

Input reference

FieldTypeDefaultWhat it does
rolesstring[]prefill: software-engineer, product-managerWellfound role slugs, or titles matched to the nearest slug. A title that matches nothing is a free unresolved row and costs no request.
locationsstring[][] = remoteremote, a city slug, or a city as you would write it (Austin, TX, NYC, Washington, DC). Every role is searched in every location; at most 100 searches per run.
keywordsstring""Keep a job only when every word appears in its title or description.
remoteOnlybooleanfalseOnly jobs Wellfound marks remote.
minSalaryinteger0Keep a job when the top of its displayed salary reaches this (listing currency, a year); jobs that show no salary are dropped while it is set.
postedWithinDaysinteger00–3,650. Only jobs that went live on Wellfound within this many days.
maxJobsPerSearchinteger200 (prefill 80)1–2,000 jobs per role × location. A search also stops at Wellfound's last page, and reads at most one page per 20 jobs asked for — three per 20 while a filter is on.
includeDetailsbooleanfalseAlso read each returned job's page for its JSON-LD posting. One extra request per job.
maxConcurrencyinteger41–8 searches at once. Requests to wellfound.com always start at least half a second apart.
maxRunSecsinteger24030–3,600. Rows already returned are kept — and billed — when it runs out; each search never started gets a free timeout row.
proxyConfigurationobject{ "useApifyProxy": true }Apify datacenter proxy by default.

A run with nothing usable — no role, no role or no location that resolves, or more than 100 searches — finishes FAILED before a single request, with a free invalid-input row saying why. Anything else finishes SUCCEEDED, including a run that returned no job (it says why, in free rows, and bills nothing).

Output reference

Every row has the same columns, null where a column does not apply, so the dataset exports as one table. rowType is job, company, diagnostic or summary; ok is false only on diagnostic rows; scrapedAt is on every row.

Job rows (paid, the primary event): role and location (the search, as slugs), searchUrl, jobId, title, url, company, companySlug, companyUrl (a link; never read), companySize, companyStage, companyHighConcept, companyBadges[], companyLogo, locations[], remote, remoteConfig ({ kind: REMOTE | ONSITE_OR_REMOTE | ONSITE, wfhFlexible }), acceptedRemoteLocations[], jobType (full-time, contract, internship, cofounder…), compensation (as displayed), salaryMin, salaryMax, salaryCurrency, salaryPeriod, equityMin, equityMax (percent; 0 – 0 when Wellfound shows "No equity"), yearsExperienceMin, yearsExperienceMax, seniority (from the title: intern, entry, senior, lead, staff, principal, manager, director, vp, executive), postedAt (when the job went live), atsSource (greenhouse, ashby, workable…; null when posted on Wellfound directly), description (plain text, at most 20,000 characters, redacted).

With includeDetails, from the job's own page: detailsRead (false when the page could not be read — the row is still returned), companyWebsite, industry, employmentType (FULL_TIME…), validThrough, benefits (plain, at most 5,000 characters, redacted), jobLocations[] ({ city, region, country }). Where the listing showed no salary, the posting's fills it.

Company rows (free, one per startup seen, after the jobs): name, size, stage, badges[], highConcept, jobCount (its jobs returned by this run), jobsListed (its highlighted jobs on the pages read), plus company, companySlug, companyUrl, companyLogo.

Diagnostic rows (free): errorType, error, role, location, searchUrl, requests.

Summary row (free, last): note (the status message), jobsReturned, requests, stats (per search: pages read, Wellfound's page and job totals, jobs read and returned, requests, why it stopped; jobs filtered and de-duplicated, companies, job pages read, diagnostics by type, what was charged).

errorTypeMeaning
unresolvedA role or location that matches nothing (no request made), or a listing Wellfound does not have (HTTP 404 or a redirect away; one request).
blockedWellfound answered with its security check (HTTP 403 or 429, or the check page itself). The run stops there: one request, never retried. Pages read before it are kept.
no-jobsThe listing was read and returned no job: none listed, none matching your filters, or every one already returned by an earlier search in the run.
parse-failedThe page answered but was not a listing this Actor can read.
timeoutmaxRunSecs ran out before the search was started.
invalid-inputNothing usable in the input; the run is FAILED.

Pricing

EventWhat it isFREEBRONZESILVERGOLD
actor-startOnce per run, only after the run has returned a job$0.001$0.001$0.001$0.001
jobOne job returned$0.001$0.001$0.0008$0.0006

$1.00 per 1,000 jobs on FREE and BRONZE, $0.80 on SILVER, $0.60 on GOLD. Company rows, diagnostics and the summary are free.

RunCost
The prefill as the offline test suite runs it — 101 jobs$0.102
The prefill live, at most 320 jobsat most $0.321
10 roles × 5 locations at 200 jobs each, if every search fills≈ $10.00
1,000 jobs at GOLD$0.601
Every search blocked, unresolved or empty$0.00, SUCCEEDED

Charging is charge-after-push: rows are in your dataset before the event is recorded. Each listing page's jobs are checked against ACTOR_MAX_TOTAL_CHARGE_USD before they are pushed; when the budget cannot cover them all, the jobs it can cover are returned and the run stops cleanly — never a row past the ceiling, and no job page is read for a job the budget cannot pay for. Never charged: company rows, diagnostics, the summary, jobs your filters dropped, a job listed under two searches the second time, and a run that returns no job (start fee included).

Limits

  • Company profile pages are not read. They sit behind Wellfound's security check. Company facts (size, stage, badges, pitch, logo) come from the listing pages; companyUrl is a link for you to open.
  • Highlighted jobs only. A listing page shows 20 startups and each startup's 1–3 highlighted jobs for that role. A startup's other openings are not on the page and are not returned, so a listing's own job total (totalJobCount in the summary — 133 for software engineers in Austin) is more than its pages carry (70 on the first two of its three pages).
  • Salary and equity only when Wellfound shows them. About one in five captured jobs shows no salary, and equity appears only where the startup lists it. Nothing is inferred from the description.
  • Listings are not ordered by date. A page mixes jobs that went live this week with jobs that have been live for years; postedWithinDays filters them, at the cost of reading more pages.
  • The security check ends the run. If Wellfound answers with it (as it does for company pages from datacenter IPs), the run stops after that one request with a free blocked row. No proxy rotation, no browser, no retry.
  • Paced: every request to wellfound.com starts at least half a second after the one before, whatever maxConcurrency is. A listing page is about 0.5–0.6 MB.
  • includeDetails is slow on purpose: one more paced request per job — 200 jobs is at least 100 seconds of job pages. The listing already carries the full description, salary and equity.
  • At most 100 searches (roles × locations) per run, and at most 100 pages per search.
  • Role and city slugs are Wellfound's. The bundled table is a sample of the slugs seen on Wellfound; any other slug is tried as written and a 404 comes back as a free unresolved row.
  • Descriptions are cut at 20,000 characters, at a word boundary.
  • Not affiliated with, endorsed by or sponsored by Wellfound or any startup whose jobs you retrieve. Names are used descriptively, to say which public pages are read.

Use it from an AI agent, or from code

One JSON object in, one flat array out — the shape agent runtimes want. The Actor runs with limited permissions and pay-per-event pricing, so it works over the Apify MCP server (mcp.apify.com) and with agentic (x402) payments. The Integrations tab pushes results to Slack, a webhook, Zapier, Make, Google Sheets, Snowflake or BigQuery, and Apify Schedules run it unattended — daily with postedWithinDays: 1 is a "new startup jobs" feed.

curl -X POST "https://api.apify.com/v2/acts/insight.solutions~wellfound-jobs-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"roles":["software-engineer"],"locations":["remote"],"minSalary":150000,"maxJobsPerSearch":100}'
# pip install apify-client
from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("insight.solutions/wellfound-jobs-api").call(run_input={
"roles": ["software-engineer", "product-manager"],
"locations": ["remote", "san-francisco"],
"maxJobsPerSearch": 100,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
if row["rowType"] == "job":
print(row["company"], row["companyStage"], row["title"], row["compensation"], row["url"], sep=" | ")
elif row["rowType"] == "company":
print(f'{row["name"]}: {row["size"]} people, {row["stage"]}, badges {row["badges"]}')

Building an app with Lovable? Apify's Lovable connector runs any Actor from inside a Lovable project with your Apify token. Connect Apify in Lovable once, then ask it: "Use Apify to run insight.solutions/wellfound-jobs-api every morning and build a startup-jobs board around the results." At the default settings a run of a few searches finishes well inside Lovable's 300-second synchronous limit, and every result is one JSON object per row, so the generated app needs no extra parsing. Usage bills to the Apify account whose token is connected.

FAQ

Which role slugs can I use? Any role page Wellfound has: the slug is the last part of wellfound.com/role/r/<slug>. Titles work too — "Software Engineer", "Product Designer", "ML engineer", "PM" — and are matched to the nearest slug this Actor knows. The summary row's stats.searches[] shows the slug each search used.

Why does a listing say 133 jobs when fewer came back? Wellfound's listing pages show each startup's highlighted jobs for the role, not every opening; the listing's own total counts them all. See Limits.

What are equityMin and equityMax? The equity range Wellfound displays, in percent: 0.01% – 0.15% is 0.01 and 0.15. "No equity" is 0 and 0; a job that says nothing about equity has null.

Is salaryMin always a yearly USD salary? Wellfound shows salaries as $…k ranges, which are yearly, and salaryPeriod says year. A salary in another currency keeps that currency in salaryCurrency (€ → EUR, £ → GBP); minSalary compares numbers in the listing's own currency.

Why are some job rows' company stage or size empty? Not every startup shows a stage badge or a size band on Wellfound; the columns are null when it does not.

Do I need includeDetails? Usually not: the listing carries the full description, salary, equity, locations and remote policy. Turn it on for the company website, industry, schema.org employment type, structured locations and benefits text.

What happens when Wellfound shows its security check? The run stops after that request, returns what it already read (billed) and one free blocked row, and finishes SUCCEEDED. Try again later; nothing is retried automatically.

  • Public pages only. Every page read is a Wellfound role listing or job page that any anonymous visitor's browser loads. The Actor never logs in, never sends or keeps cookies, never accepts credentials and needs no API key.
  • No recruiter contacts by design. E-mail addresses (plain, obfuscated and mailto: links), phone numbers, LinkedIn profile and post links (with their link text, which is a name), Recruiter: … lines, and every sentence that points the reader at a named person or names a founder or executive ("send your resume to …", "founded by …", "our CEO, …") are removed from descriptions and benefits before a row is written. Company facts are company-level: Wellfound's startup records carry no people fields. Salary and equity ranges are kept: they are attributes of the job.
  • robots.txt is respected. Every URL this Actor builds — the role listings with ?page=N and the job pages — is allowed by wellfound.com's robots.txt (the test suite checks each shape against it); the query forms it disallows and its /_jobs/ and /search paths are never requested, and company pages are not read at all. Requests are at least half a second apart.
  • No bot walls are bypassed. The security check is one request and a free blocked row.
  • You are the controller of what you do next. If you combine this data with personal data or contact people based on it, GDPR, CCPA and similar obligations are yours.
  • Not affiliated with, endorsed by or sponsored by Wellfound or any startup named. Names and trademarks are used descriptively.

Our other Actors

Every Insight Solutions Actor is pay-per-result with no browser, no login and no API key, and every one of them returns free diagnostic rows instead of billing for failures. Prices are per 1,000 results.

Video, audio & social

News, documents & the web

Business, finance & jobs

Apps & games