Wellfound Jobs Scraper - Startup Roles, Salaries & Remote Jobs avatar

Wellfound Jobs Scraper - Startup Roles, Salaries & Remote Jobs

Pricing

from $1.00 / 1,000 dataset items

Go to Apify Store
Wellfound Jobs Scraper - Startup Roles, Salaries & Remote Jobs

Wellfound Jobs Scraper - Startup Roles, Salaries & Remote Jobs

Scrape startup jobs from Wellfound.com by keyword, location, role, or remote status. Extract job details, compensation, company badges, and other listing data, with MCP connector export support.

Pricing

from $1.00 / 1,000 dataset items

Rating

5.0

(1)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

1

Bookmarked

4

Total users

2

Monthly active users

3 days ago

Last modified

Share

Wellfound Scraper: Startup Jobs, Compensation & Company Data

Wellfound Scraper turns Wellfound startup job listings into a clean dataset. Search one or more Wellfound locations, or paste Wellfound job-search links, and get job title, role, compensation, remote status, posting date, and company details (size, logo, high concept, hiring badges) for every matching listing, plus the full job description text whenever Wellfound's own page data carries it. Narrow results by keyword, role, remote status, compensation, and hiring badges in either mode, then export to JSON, CSV or Excel, or read results straight through the API.

Why This Scraper?

  • Two clear modes. Search mode builds Wellfound location pages for you from a list of location slugs; URL mode reads Wellfound /jobs or /location/... links you paste in. No manual URL building for search mode.
  • Full job and company context in every row. Title, role, compensation range, remote status, locations, posting date, plus the company's size, logo, one-line pitch and hiring badges.
  • Full job description text included whenever Wellfound's own listing data carries it.
  • Five filters, both modes. Keyword, role keyword, remote-only, require-compensation and actively-hiring-only all apply whether you searched by location or pasted URLs, so a bulk pull still comes back narrowed.
  • Resume and recurring monitoring. Continue one interrupted run from its run ID, or turn on Incremental mode for a schedule that returns only the jobs that are new, changed, or newly back.
  • MCP connector export. Send a condensed, human-readable job summary into Notion, Linear, Airtable or Apify connectors while the complete record always stays in the dataset.
  • Fails loudly when genuinely blocked. A run where every request is refused stops with a clear message instead of quietly billing an empty result.

Use Cases

  • Startup recruiters and sourcers: build a running feed of new engineering, product and sales roles at companies in specific cities or remote-friendly searches.
  • Job boards and aggregators: mirror Wellfound listings with company and compensation context to power your own search or alerting product.
  • Compensation research: collect posted salary ranges and equity mentions across roles and locations for benchmarking.
  • Sales and BD prospecting: use the "actively hiring" and investor/responder badges as signals for which startups are growing right now.
  • Job seekers and career sites: track new remote-eligible roles matching specific keywords on a recurring schedule.

Data You Get

Sample shape: values are illustrative placeholders, not from a live listing.

FieldExample
jobId"00000001"
jobUrl"https://wellfound.com/jobs/00000001-sample-role"
jobTitle"Sample Platform Engineer"
jobType"full-time"
primaryRoleTitle"Software Engineer" (or a role slug like "software-engineer" when only the role code is available)
descriptionText"Full role description text appears here." (markdown stripped, capped at 5000 characters)
compensation"$100k - $150k"
compensationMin / compensationMax100000 / 150000
hasCompensation / hasEquitytrue / false
locations["San Francisco"]
acceptedRemoteLocations["United States"]
remote / remoteKindtrue / "remote"
yearsExperienceMin / yearsExperienceMax3 / 7
postedAt"2026-01-01T00:00:00Z"
companyName"Sample Company"
companyUrl / companyLogoUrl"https://wellfound.com/company/sample-company" / logo image URL
companySize"SIZE_51_200"
companyHighConcept"Sample company summary"
allBadgeLabels["Actively Hiring", "Top Investors"]
activelyHiring / hasTopInvestorstrue / true
quickResponder / topResponderfalse / false
sourceUrl / sourceLabel"https://wellfound.com/location/san-francisco" / "san-francisco"
scrapedAt"2026-01-01T00:00:00Z"

A few secondary fields ride along too: jobSlug and companySlug (the URL slugs behind jobUrl/companyUrl), descriptionLength (character count of descriptionText), companyId, and autoPosted/atsSource (whether and through which applicant-tracking system a listing was auto-posted, when Wellfound tags one). Note that compensationCurrency currently recognizes only the U.S. dollar sign; postings priced in another currency leave it blank even though compensation still holds the original text. remote is true for any listing with a remote arrangement, including hybrid or flexible ones that merely carry remote configuration data; check remoteKind for the exact arrangement.

How to Use

  1. Pick a mode: search (build pages from Wellfound location slugs) or url (paste Wellfound /jobs or /location/... links).
  2. Fill in locations or URLs for that mode, and switch on any keyword, role, remote, compensation or hiring-badge filters you need.
  3. Set Max items (and optionally Max pages) to control run size and cost, then click Start.
  4. Download the dataset as JSON, CSV or Excel, or read it through the API.

Search one location:

{
"mode": "search",
"locations": ["san-francisco"],
"maxItems": 20
}

Search multiple locations with filters:

{
"mode": "search",
"locations": ["san-francisco", "new-york"],
"keywords": ["python", "platform"],
"roleKeywords": ["engineer"],
"requireCompensation": true,
"maxItems": 25
}

Paste Wellfound URLs, remote jobs only:

{
"mode": "url",
"startUrls": [
{ "url": "https://wellfound.com/location/san-francisco" },
{ "url": "https://wellfound.com/jobs" }
],
"remoteOnly": true,
"maxItems": 10
}

Daily monitoring with full expiry tracking:

{
"mode": "search",
"locations": ["san-francisco"],
"incrementalMode": true,
"emitExpired": true,
"maxItems": 100000,
"maxPages": 0
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/wellfound-jobs-scraper").call(run_input={"mode": "search", "locations": ["san-francisco"]})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
print(job["jobTitle"], job["companyName"], job["compensation"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/wellfound-jobs-scraper').call({ mode: 'search', locations: ['san-francisco'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

How Max items is split across locations and URLs

Max items is a cap, not a guaranteed count: a run can return fewer rows when the selected locations, URLs, keywords and filters match fewer current jobs. When a run has more than one location or URL source, the remaining budget is divided roughly evenly across the sources still to be read, in order, so an early source cannot use up the whole cap before later ones are tried. Max pages limits how many result pages are read per source; leave it empty or 0 to walk every page a source has, since Max items is the primary control on run size.

Resume and recurring updates

  • Resume (resumeFromRunId) continues one interrupted run: paste its run or dataset ID and the actor skips every job it already collected there (matched by jobId), so you don't pay twice. A bad or unreadable ID fails the run immediately, before any new scraping starts.
  • Incremental mode (incrementalMode) is for a schedule over the same search. The first run returns everything as NEW. Later runs classify each job as NEW, UPDATED (with changedFields), UNCHANGED (suppressed and not billed unless emitUnchanged is on), REAPPEARED, or leave the previous state untouched. REAPPEARED is not something that "happens by default": a job can only be classified REAPPEARED once a prior run marked it absent, which only happens when that prior run had emitExpired on and completed a full, uncapped, non-resumed scan of the tracked search (that run normally also emits an EXPIRED row for the job, though a Resume-seeded placeholder can be marked absent without one). Until that has happened once, no job in that campaign can ever come back as REAPPEARED. stateKey names or shares the stored state; leaving it empty derives one automatically from mode, locations, URLs, keywords and filters, so different searches never mix state. With Incremental mode off, output is exactly as before, with no extra fields.
  • resumeFromRunId and incrementalMode are different tools: use Resume after one run was cut off, and Incremental mode for a schedule that runs the same search again and again. Combining them only works to bootstrap a brand-new monitoring campaign from a prior plain run; if that campaign already has saved state, the run fails rather than silently mixing the two.

Send results into your apps (MCP connectors)

Optionally pipe the scraped jobs into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each job, not the full JSON. Each job becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset, and a connector write error never fails the run.

  1. Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where job entries should be created.
  4. Use Max jobs to export per connector to cap how many of this run's jobs are sent, separately from the dataset itself.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch for Wellfound location pages, or url for pasted Wellfound links.
locationsarrayno default (prefill: ["san-francisco"])Wellfound location slugs or names for search mode.
startUrlsarrayno default (prefill: sample /location/... and /jobs URLs)Wellfound /jobs or /location/... URLs for URL mode.
keywordsarrayno default (prefill: ["python"])Keeps rows where at least one term appears in the job, company, role, location, badge, compensation or description text.
roleKeywordsarrayno defaultKeeps rows where at least one term appears in the job title or primary role.
remoteOnlybooleanfalseKeeps only jobs marked remote or carrying remote configuration data.
requireCompensationbooleanfalseKeeps only jobs with a compensation value.
activelyHiringOnlybooleanfalseKeeps only jobs whose company carries an actively-hiring badge.
maxItemsinteger20Maximum matching rows to save (1 to 100000). Runs can return fewer rows when filters match fewer current jobs.
maxPagesinteger0Maximum pages to read per location or URL source. 0 walks every result page; maxItems is the primary output cap.
resumeFromRunIdstringno default (empty)A previous run ID (or dataset ID) from this actor. Jobs already collected there (matched by jobId) are skipped.
incrementalModebooleanfalseDaily/recurring monitoring of the same search. See "Resume and recurring updates" above.
stateKeystringno default (empty)Optional name for a monitoring campaign; auto-derived from mode/locations/URLs/keywords/filters when left empty.
emitUnchangedbooleanfalseIncremental mode only. Also return (and bill) jobs unchanged since the last run, marked UNCHANGED.
emitExpiredbooleanfalseIncremental mode only. Also return (and bill) jobs no longer found, marked EXPIRED, once a run has fully scanned the search.
proxyobjectApify Proxy ResidentialConnection settings. The default is recommended for Wellfound.
mcpConnectorsarrayno default (empty)Optional connector IDs for sending a job summary into your apps.
notionParentPageUrlstringno default (empty)Required only to enable the Notion export.
maxNotifyListingsinteger50Maximum jobs sent to each selected connector per run. Does not affect the dataset.

Output Example

Sample shape: values are illustrative placeholders, not from a live listing.

{
"jobId": "00000001",
"jobUrl": "https://wellfound.com/jobs/00000001-sample-platform-engineer",
"jobSlug": "sample-platform-engineer",
"jobTitle": "Sample Platform Engineer",
"descriptionText": "Full role description text appears here.",
"descriptionLength": 40,
"jobType": "full-time",
"primaryRoleTitle": "Software Engineer",
"compensation": "$100k - $150k",
"compensationMin": 100000,
"compensationMax": 150000,
"compensationCurrency": "$",
"hasCompensation": true,
"hasEquity": false,
"locations": ["San Francisco"],
"acceptedRemoteLocations": ["United States"],
"remote": true,
"remoteKind": "remote",
"yearsExperienceMin": 3,
"yearsExperienceMax": 7,
"postedAtUnix": 1767225600,
"postedAt": "2026-01-01T00:00:00Z",
"companyId": "00000001",
"companyName": "Sample Company",
"companySlug": "sample-company",
"companyUrl": "https://wellfound.com/company/sample-company",
"companyLogoUrl": "https://photos.wellfound.com/startups/i/00000001-medium_jpg.jpg",
"companySize": "SIZE_51_200",
"companyHighConcept": "Sample company summary",
"allBadgeLabels": ["Actively Hiring", "Top Investors"],
"activelyHiring": true,
"hasTopInvestors": true,
"quickResponder": false,
"topResponder": false,
"sourceUrl": "https://wellfound.com/location/san-francisco",
"sourceLabel": "san-francisco",
"scrapedAt": "2026-01-01T00:00:00Z"
}

Plan Requirement

Keep the default Apify Residential proxy setting for the most reliable results on Wellfound. Max items is a maximum cap, not a guaranteed count: a run can save fewer rows when the selected location, URL, keyword and filter combination matches fewer active jobs.

FAQ

How much does it cost?

You pay a small one-time run start fee plus a per-row price for every job saved to the dataset. The Pricing tab shows the current rates. Use Max items to cap the cost of any run, and leave emitUnchanged/emitExpired off unless you specifically want those extra rows returned and billed.

This actor collects only publicly available job listing data. You are responsible for how you use it: follow Wellfound's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution.

Can I get only new or changed jobs on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and (once eligible) reappeared jobs, and unchanged ones are not billed unless you turn emitUnchanged on.

What's the difference between Resume and Incremental mode?

Resume (resumeFromRunId) continues one specific interrupted run from a pasted ID; it is a one-time delta against that one dataset. Incremental mode remembers state itself and is for running the exact same search again and again on a schedule. Use Resume after a run was cut off; use Incremental mode for recurring monitoring. Mixing the two only works to bootstrap a brand-new monitoring campaign; if that state key already has saved history, the run fails rather than guessing which one you meant.

Why did my run fail instead of returning an empty dataset?

If every request to Wellfound was refused, the run stops with a clear message so "no jobs matched" is never confused with "nothing could be read." Retry in a few minutes, ideally with the default Residential proxy. A genuinely empty search, where Wellfound answered normally but nothing matched your location, URL or filters, still succeeds and reports the reason through the run status, without billing a placeholder row.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push job summaries into Notion, Linear or Airtable.

🔗 Want more jobs data?

Pair this actor with these related scrapers from the same team:

💼 CareerBuilder Scraper
Scrape CareerBuilder.com job listings by search or URL. Returns title, company profile...
💼 RemoteOK Jobs Scraper
Scrape RemoteOK jobs by keyword or job URL. Extract title, company, location, remote...
💼 Jora Jobs Scraper
Scrape Jora.com job listings across supported countries by keyword, filters, or URL...
💼 Monster Jobs Scraper
Scrape Monster.com job listings from search and direct job URLs. Extract full...
🏨 Caterer.com Scraper
Scrape UK hospitality jobs from Caterer.com, including chef, hotel, restaurant, bar, and...
💼 We Work Remotely Scraper
Extract current remote job listings from weworkremotely.com. Use keyword search or WWR...

👉 Browse all abotapi scrapers

💬 Support

  • 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.