Arcadium Data Scrapers
Home / Guides / Wellfound Jobs Scraper

How to use Wellfound Jobs Scraper

Step by step: in the Apify Store, over the API, from JavaScript or Python, in n8n, and from AI agents through MCP or LangChain.

$2.70 per 1,000 jobs (live Apify price on 2026-11-03).

1. In the Apify Store (no code)

  1. Open arcadium/wellfound-jobs and sign in to Apify (a free account works).
  2. Fill in the input form. The fields below are the ones the example uses.
  3. Set a maximum cost per run in the run options if you want a hard cap.
  4. Start the run. Rows appear in the Output tab as they arrive.
  5. Export the dataset as JSON, CSV or Excel, or connect an integration.
Input fieldTypeDescription
rolesarrayWellfound role names or slugs, e.g. ["software engineer", "product manager", "data-scientist"]. Each role is searched in every location below. Wellfound's own role list: wellfound.com/role/<slug>.
locationsarrayCity or country names or slugs, e.g. ["San Francisco", "New York", "London", "united-states"]. "remote" searches remote jobs. Without roles, each location returns all startup jobs there. Empty = no location filter.
startUrlsarrayWellfound role or location pages, e.g. https://wellfound.com/role/l/software-engineer/san-francisco, https://wellfound.com/role/r/data-scientist or https://wellfound.com/location/berlin.
maxJobsPerSearchintegerJobs per role and location or URL, 1 to 10,000 (default 100). A search ends when Wellfound has no more pages.

Example input:

{
  "roles": [
    "software engineer"
  ],
  "locations": [
    "New York"
  ],
  "startUrls": [],
  "maxJobsPerSearch": 50
}

2. Over the Apify API

The synchronous endpoint runs the actor and returns its rows in one call (for runs up to about five minutes; use the asynchronous run endpoint for longer ones).

curl -X POST "https://api.apify.com/v2/acts/arcadium~wellfound-jobs/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"roles":["software engineer"],"locations":["New York"],"startUrls":[],"maxJobsPerSearch":50}'

3. From JavaScript

// npm install apify-client
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('arcadium/wellfound-jobs').call({
  "roles": [
    "software engineer"
  ],
  "locations": [
    "New York"
  ],
  "startUrls": [],
  "maxJobsPerSearch": 50
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

4. From Python

# pip install apify-client
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("arcadium/wellfound-jobs").call(run_input={
    "roles": ["software engineer"],
    "locations": ["New York"],
    "startUrls": [],
    "maxJobsPerSearch": 50,
})
items = client.dataset(run.default_dataset_id).list_items().items  # apify-client 3.x returns a Run object
print(items)

5. In n8n

Paste this node into a workflow (it is a plain HTTP Request node). Create a Header Auth credential with name Authorization and value Bearer <APIFY_TOKEN>; each returned row becomes one item for the next node.

{
  "nodes": [
    {
      "name": "Run arcadium/wellfound-jobs",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        0,
        0
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.apify.com/v2/acts/arcadium~wellfound-jobs/run-sync-get-dataset-items",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "{\"roles\":[\"software engineer\"],\"locations\":[\"New York\"],\"startUrls\":[],\"maxJobsPerSearch\":50}",
        "options": {
          "timeout": 300000
        }
      }
    }
  ],
  "connections": {}
}

6. From an AI assistant (MCP)

Add Apify’s MCP server to Claude Desktop, Cursor, VS Code or any MCP client, limited to this actor:

{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=arcadium/wellfound-jobs",
      "headers": {
        "Authorization": "Bearer <APIFY_TOKEN>"
      }
    }
  }
}

More on the MCP page.

7. From LangChain

# pip install langchain-apify   (reads APIFY_API_TOKEN from the environment)
from langchain_apify import ApifyActorsTool

tool = ApifyActorsTool("arcadium/wellfound-jobs")
rows = tool.invoke({"run_input": {
    "roles": ["software engineer"],
    "locations": ["New York"],
    "startUrls": [],
    "maxJobsPerSearch": 50,
}})
# or give `tool` to an agent: create_react_agent(llm, [tool])

Sample output

One row, from the example in the actor’s README. Long text is shortened and lists are cut to two items.

{
  "rowType": "job",
  "platform": "wellfound",
  "jobId": "4844846",
  "url": "https://wellfound.com/jobs/4844846-software-engineer",
  "title": "Software Engineer",
  "role": "Software Engineer",
  "jobType": "full-time",
  "remote": false,
  "remoteKind": null,
  "wfhFlexible": null,
  "locations": [
    "New York"
  ],
  "acceptedRemoteLocations": [],
  "compensation": "$142k – $187k",
  "salary": {
    "min": 142000,
    "max": 187000,
    "currency": "USD",
    "period": "year",
    "source": "structured"
  },
  "equityMinPercent": null,
  "equityMaxPercent": null,
  "yearsExperienceMin": null,
  "yearsExperienceMax": null,
  "postedAt": "2026-10-15T00:02:06Z",
  "description": "## About Check\n\nPayroll is broken. It's still running on decades-old infrastructure. **We're rebuilding it.** ...",
  "atsSource": "ashby",
  "autoPosted": false,
  "companyId": "8170097",
  "companyName": "Check",
  "companySlug": "checkhq",
  "companyUrl": "https://wellfound.com/company/checkhq",
  "companyTagline": "Check’s mission is to make paying people simple",
  "companySize": "51-200",
  "companyStage": "Growth Stage",
  "companyBadges": [
    "Actively Hiring",
    "B2B"
  ],
  "ycFunded": false,
  "topInvestors": true,
  "recentlyFunded": false,
  "valuation": "Valuation $500M+",
  "companyLogoUrl": "https://photos.wellfound.com/startups/i/8170097-670b14dbd6d668e33d45382818a7008d-medium_jpg.jpg",
  "companyWebsite": "https://checkhq.com/",
  "industries": [
    "SaaS",
    "Enterprise Software"
  ],
  "jobLocations": [
    {
      "locality": null,
      "region": "New York",
      "country": "United States"
    }
  ],
  "directApply": true,
  "validThrough": null,
  "detailsIncluded": true,
  "source": "software engineer in new york",
  "sourceType": "roleLocation",
  "searchRole": "software-engineer",
  "searchLocation": "new-york",
  "position": 1,
  "scrapedAt": "2026-10-22T12:00:00.000Z"
}
FieldWhat it holds
rowTypeKind of row. Filter on this first. Values: 'job': one job with its startup (charged). 'error': a role, location or URL gave no jobs; see code and message (free).
platformAlways 'wellfound'.
jobIdWellfound job id (digits), stable across runs. Use it to deduplicate.
urlJob page on Wellfound, e.g. https://wellfound.com/jobs/2421931-software-engineer.
titleJob title as posted.
roleWellfound's role category of the job, e.g. 'Software Engineer'.
jobTypeValues: full-time, contract, internship, cofounder.
remoteTrue when the job can be done remotely.
remoteKindValues: ONSITE, REMOTE, ONSITE_OR_REMOTE. Null when the startup did not set it.
wfhFlexibleTrue when the startup marks work from home as flexible. Null when not set.
locationsOffice locations of the job, e.g. ['New York', 'San Francisco'].
acceptedRemoteLocationsWhere remote candidates may live, e.g. ['United States']. Empty when not restricted or not remote.
compensationPay and equity text as Wellfound shows it, e.g. '$75k – $150k CAD • 0.0% – 0.1%'.
salaryPay range {min, max, currency, period, source}; 'structured' when read from the job page, 'text' when parsed from compensation. Null when no pay is shown.
equityMinPercentLow end of the equity offer in percent. Null when none is shown.
equityMaxPercentHigh end of the equity offer in percent. Null when none is shown.
yearsExperienceMinMinimum years of experience asked for. Null when not set.
yearsExperienceMaxMaximum years of experience asked for. Null when not set.
postedAtWhen the job went live, ISO 8601.
descriptionFull job description in Markdown; emails, phone numbers and greeting names are removed. Null with descriptionFormat none.
atsSourceApplicant tracking system the job was imported from: greenhouse, ashby, lever, workable, ... 'other' for one we do not list, null when posted on Wellfound directly.
autoPostedTrue when Wellfound imported the job automatically.
companyIdWellfound startup id.
companyNameStartup name.
companySlugStartup slug on Wellfound, e.g. 'checkhq'.
companyUrlStartup profile on Wellfound, built from companySlug.
companyTaglineThe startup's one-line pitch as shown on Wellfound.
companySizeEmployee range, e.g. '1-10', '11-50', '51-200', '5000+'.
companyStageStage badge: 'Early Stage', 'Growth Stage', 'Scale Stage' or 'Public Stage'. Null when not shown.
companyBadgesAll badges Wellfound shows, e.g. 'Top Investors', 'YC Funded', 'Recently funded', 'Responds within a week'.
ycFundedTrue when Wellfound shows the YC Funded badge.
topInvestorsTrue when Wellfound shows the Top Investors badge.
recentlyFundedTrue when Wellfound shows the Recently funded badge.
valuationValuation badge, e.g. 'Valuation $1B+'. Null when not shown.
companyLogoUrlStartup logo image.
companyWebsiteStartup website from the job page (includeJobDetails). Null otherwise.
industriesIndustries from the job page, e.g. ['SaaS', 'Fin Tech'] (includeJobDetails). Null otherwise.
jobLocationsStructured job addresses [{locality, region, country}] from the job page (includeJobDetails). Null otherwise.
directApplyTrue when you apply on Wellfound itself (includeJobDetails). Null otherwise.
validThroughClosing date of the posting when the job page gives one. Null otherwise.
detailsIncludedTrue when the job page was read for this row.
sourceThe search this job came from, e.g. 'software engineer in New York' or a URL.
sourceTypeValues: role, roleLocation, roleRemote, location, url.
searchRoleRole slug of the search, e.g. 'software-engineer'. Null for location searches.
searchLocationLocation slug of the search, 'remote' for remote searches, null when none.
position1-based rank of the job in its search.
jobsDbOnly with jobsDbExport: {ats, companyDomain, fingerprint} for merging with other job sources.
scrapedAtWhen the row was read, ISO 8601.
inputError rows only: the role, location or URL that gave no jobs.
codeError rows only. Values: not_found, no_match, unavailable, blocked, invalid_input.
messageError rows only: what went wrong, in plain words.

Schedule it

In Apify Console, create a Task from your input and add a Schedule (for example daily). Each run writes a new dataset; integrations can push the rows to Google Sheets, Slack, a webhook or your database.