# Wellfound Jobs Scraper: Startup Jobs, Salary, Equity (`arcadium/wellfound-jobs`) Actor

Wellfound (AngelList Talent) startup jobs by role, location or URL with salary, equity, description and company stage; $2.70 per 1,000 jobs. Role, location and remote searches, company website and ATS on request. No founder or recruiter names, free error rows.

- **URL**: https://apify.com/arcadium/wellfound-jobs.md
- **Developed by:** [Arcadium Data](https://apify.com/arcadium) (community)
- **Categories:** Jobs, Lead generation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.70 / 1,000 jobs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Wellfound Jobs Scraper: Startup Jobs, Salary, Equity

Give it roles and locations (or Wellfound URLs) and it returns one JSON row per startup job on Wellfound (formerly AngelList Talent): title, pay range, equity, full description, locations, remote policy, and the startup's stage, size, pitch and badges such as Top Investors or YC Funded. $2.70 per 1,000 jobs, job page details included; you pay only for rows you get.

**Why this actor**

- Salary and equity on the row, plus funding badges for startup targeting.
- Company domain and ATS on request (`jobsDbExport`) to merge with other job sources.
- Alias field names are accepted: `keyword`, `role`, `location`, `remote`, `searchUrls`, `urls`, `maxJobs`, `limit`.
- No founders, recruiters or team members are collected; unknown roles or places are free error rows.

Built by Arcadium Data: public data, dated and agent-ready, never personal data.

### Use with AI agents

The actor takes plain JSON and returns one flat row per job, so an AI agent or MCP client (for example through [mcp.apify.com](https://mcp.apify.com)) can call `arcadium/wellfound-jobs` directly. Input example for "software engineer jobs at startups in New York and San Francisco":

```json
{ "roles": ["software engineer"], "locations": ["New York", "San Francisco"], "maxJobsPerSearch": 100 }
```

"Remote data scientist jobs, with each startup's website":

```json
{ "roles": ["data scientist"], "remoteOnly": true, "includeJobDetails": true, "maxJobsPerSearch": 50 }
```

Read `title`, `companyName`, `compensation`, `salary`, `equityMinPercent`, `locations`, `remote`, `companyStage`, `companySize` and `url`. 100 jobs cost $0.27 plus the start fee. A role or location Wellfound does not know, or a URL that is not a Wellfound role or location page, comes back as a free row with `rowType: "error"`, a `code` (`not_found`, `unavailable`, `blocked`, `invalid_input`) and a `message`, never as a failed run. Retry on `blocked` and `unavailable` later.

### What you get

| Field | What it holds |
| --- | --- |
| `jobId`, `url`, `title`, `role`, `jobType` | The job: Wellfound's id (stable between runs), its page, the title, Wellfound's role category and full-time / contract / internship / cofounder. |
| `compensation`, `salary`, `equityMinPercent`, `equityMaxPercent` | Pay and equity as shown ("$75k – $150k CAD • 0.0% – 0.1%"), and parsed: `salary` is `{min, max, currency, period, source}`. |
| `locations`, `remote`, `remoteKind`, `wfhFlexible`, `acceptedRemoteLocations` | Where the job is, and the remote policy. |
| `yearsExperienceMin`, `yearsExperienceMax`, `postedAt` | Experience asked for; when the job went live. |
| `description` | The full job description in Markdown (emails, phone numbers and greeting names removed). |
| `atsSource`, `autoPosted` | The applicant tracking system the job came from (greenhouse, ashby, lever, workable, ...). |
| `companyName`, `companySlug`, `companyUrl`, `companyTagline`, `companyLogoUrl` | The startup. |
| `companySize`, `companyStage`, `companyBadges`, `valuation`, `ycFunded`, `topInvestors`, `recentlyFunded` | Startup signals Wellfound shows: size range, stage (Early / Growth / Scale / Public), funding and hiring badges. |
| `companyWebsite`, `industries`, `jobLocations`, `directApply`, `validThrough` | From the job page, with `includeJobDetails` (null otherwise). |
| `source`, `sourceType`, `searchRole`, `searchLocation`, `position` | Which search the job came from and its rank in it. |
| `jobsDb` | With `jobsDbExport`: `{ats, companyDomain, fingerprint}` to merge with other job sources. |

Output example:

```json
{
  "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", "Growth Stage", "Top Investors", "Valuation $500M+"],
  "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", "B2B", "Payments", "Hr Tech", "Fin Tech"],
  "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"
}
```

### Input

| Field | What it does |
| --- | --- |
| `roles` | Wellfound roles by name or slug (`"software engineer"`, `"product-manager"`); each is searched in every location. |
| `locations` | Cities or countries (`"San Francisco"`, `"London"`, `"united-states"`); `"remote"` searches remote jobs. Without roles, a location returns all startup jobs there. |
| `remoteOnly` | Search each role on its remote page; locations are ignored. |
| `startUrls` | Wellfound role or location pages (`/role/...`, `/role/l/<role>/<place>`, `/role/r/<role>`, `/location/<place>`). |
| `maxJobsPerSearch` | Jobs per search, 1 to 10,000 (default 100). |
| `maxItems` | Stop after this many jobs in total. A cost cap. |
| `jobTypes`, `postedWithinDays` | Keep only these job types; only jobs that went live in the last 1, 3, 7, 14 or 30 days. |
| `includeJobDetails` | Also read each job page: company website, industries, structured address and salary. Same price, slower. |
| `descriptionFormat`, `maxDescriptionChars` | `markdown` (default) or `none`; cut long descriptions. |
| `jobsDbExport` | Add the `jobsDb` merge fields. |
| `includeErrorRows` | A free row for every input without jobs (on by default). |

These input field names are also accepted as they are (`keyword`, `role`, `location`, `remote`, `searchUrls`, `urls`, `maxJobs`, `limit`).

### Use it from code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("arcadium/wellfound-jobs").call(run_input={
    "roles": ["machine learning engineer"],
    "locations": ["Berlin", "London"],
    "maxJobsPerSearch": 200,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item["rowType"] == "job":
        print(item["title"], item["companyName"], item["companyStage"], item["compensation"])
```

JavaScript:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('arcadium/wellfound-jobs').call({
  roles: ['product manager'],
  remoteOnly: true,
  maxJobsPerSearch: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((i) => i.rowType === 'job').length, 'jobs');
```

### Pricing

You pay per job delivered, the same on every Apify plan. Error rows and jobs that two of your searches both found are free.

| Apify plan | Per 1,000 jobs |
| --- | --- |
| Free | $2.70 |
| Starter (Bronze) | $2.70 |
| Scale (Silver) | $2.70 |
| Business (Gold) | $2.70 |
| Platinum | $2.70 |
| Diamond | $2.70 |

Plus a one-off $0.001 per GB of memory when a run starts (the run uses 512 MB).

Set a maximum cost per run in the Apify run options and the actor stops before it goes over.

### Related actors

- [Career Site Jobs Scraper: 9 ATS incl. Workday, Personio](https://apify.com/arcadium/career-site-jobs)

### Use cases

- Startup recruiting: who is hiring for a role in a city, with pay and equity, and how fast they answer.
- Job boards and aggregators: fresh startup jobs per role, with the ATS they come from.
- VC and market research: hiring by stage, size and funding badges; which YC or top-investor startups grow a team.
- Sales prospecting: growing startups with their website (`includeJobDetails`), ready to enrich.
- Salary and equity benchmarks for startup roles.

### Limitations

- Wellfound's role and location pages list up to three jobs per startup per page; a startup with more open roles shows the rest on its own page, which this actor does not read.
- The search covers the roles and places Wellfound has landing pages for. An unknown location is reported as `not_found`, not silently widened.
- Company websites, industries and structured salaries need `includeJobDetails` (one extra request per job).
- `postedWithinDays` and `jobTypes` are applied to the jobs a page lists, so a strict filter still reads the pages it skips.
- No people: founders, recruiters and team members are not collected.

### Privacy

Public job listings only, read the way an anonymous visitor's browser reads Wellfound's public role pages. No login, no account. No founder, recruiter or contact names are collected; emails and phone numbers in descriptions are replaced with `[email]` and `[phone]`, and greeting names are removed. Startup names are companies.

### FAQ

**Why are there fewer jobs than Wellfound's headline count?**
The role pages show each startup with up to three of its jobs. The headline counts every open job of every startup.

**What is `atsSource` good for?**
It names the applicant tracking system behind the job (Greenhouse, Ashby, ...). Pair it with our Career Site Jobs actor to read the startup's full job board.

**Something looks wrong in the output. Who do I tell?**
Open an issue on the actor page with the run link. We read them all.

# Actor input Schema

## `roles` (type: `array`):

Wellfound 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>.

## `locations` (type: `array`):

City 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.

## `remoteOnly` (type: `boolean`):

Search every role on its remote page (wellfound.com/role/r/<role>); locations are ignored.

## `startUrls` (type: `array`):

Wellfound 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.

## `maxJobsPerSearch` (type: `integer`):

Jobs per role and location or URL, 1 to 10,000 (default 100). A search ends when Wellfound has no more pages.

## `maxItems` (type: `integer`):

Stops the run after this many jobs across all searches. A cost cap; leave empty for no limit.

## `jobTypes` (type: `array`):

Only these job types. Values: full-time, contract, internship, cofounder. Empty = all.

## `postedWithinDays` (type: `string`):

Values: 1, 3, 7, 14, 30 (days). Only jobs that went live in that window. Empty = any date.

## `includeJobDetails` (type: `boolean`):

Reads each job's page too: company website, industries, structured address and salary, apply-on-Wellfound flag. Same price per job, slower runs.

## `descriptionFormat` (type: `string`):

Values: markdown (the full job description as Wellfound stores it, contact details removed) or none (smaller rows).

## `maxDescriptionChars` (type: `integer`):

Cut descriptions after this many characters, 0 = full text (default).

## `jobsDbExport` (type: `boolean`):

Adds a jobsDb object per job: the ATS the company posts through, the company domain (with job page details) and a cross-board fingerprint for merging with other job sources.

## `includeErrorRows` (type: `boolean`):

Adds a free row (rowType error, with a code and message) for every role, location or URL that gave no jobs. On by default.

## `maxRetries` (type: `integer`):

How often a request is retried after a temporary error, 0 to 10.

## `proxyConfiguration` (type: `object`):

Leave empty: the actor starts on datacenter proxies and moves to residential ones when a page asks for a check.

## Actor input object example

```json
{
  "roles": [
    "software engineer"
  ],
  "locations": [
    "New York"
  ],
  "startUrls": [],
  "maxJobsPerSearch": 50,
  "includeJobDetails": false,
  "descriptionFormat": "markdown",
  "maxDescriptionChars": 0,
  "jobsDbExport": false,
  "includeErrorRows": true,
  "maxRetries": 4
}
```

# Actor output Schema

## `results` (type: `string`):

All rows of this run in the default dataset.

## `view_overview` (type: `string`):

No description

## `view_details` (type: `string`):

No description

## `view_errors` (type: `string`):

No description

## `record_stats` (type: `string`):

Requests, data volume, retries, proxy tiers and cost per job for this run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "roles": [
        "software engineer"
    ],
    "locations": [
        "New York"
    ],
    "startUrls": [],
    "maxJobsPerSearch": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("arcadium/wellfound-jobs").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "roles": ["software engineer"],
    "locations": ["New York"],
    "startUrls": [],
    "maxJobsPerSearch": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("arcadium/wellfound-jobs").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "roles": [
    "software engineer"
  ],
  "locations": [
    "New York"
  ],
  "startUrls": [],
  "maxJobsPerSearch": 50
}' |
apify call arcadium/wellfound-jobs --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,arcadium/wellfound-jobs"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/GDo42lF6Fo9a9yi8r/builds/3KXOpm4NmLZgZCLCx/openapi.json
