# Wellfound Startup Jobs Scraper (`automation-lab/wellfound-startup-jobs-scraper`) Actor

Extract public Wellfound startup jobs by role, location, remote status, or URL with company, compensation, equity, descriptions, timestamps, and change monitoring.

- **URL**: https://apify.com/automation-lab/wellfound-startup-jobs-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Wellfound Startup Jobs Scraper

Extract public **Wellfound startup jobs** into structured records for recruiting,
job aggregation, market research, and scheduled change monitoring.

The Actor accepts Wellfound role and location filters or public search URLs. It
returns the company, role, description, locations, remote policy, compensation,
equity, experience range, canonical URL, and posting timestamp available in
Wellfound's public result pages.

### What does this Wellfound scraper do?

Wellfound organizes startup openings into public role and location pages. This
Actor converts those pages into integration-ready JSON without requiring a
Wellfound login.

It can:

- scrape a Wellfound role such as `software-engineer`;
- combine roles with locations such as `new-york` or `berlin`;
- select Wellfound's remote role pages;
- process public `/jobs` and `/role` search URLs;
- paginate with explicit item and page limits;
- normalize salary and equity ranges while retaining the source text;
- deduplicate jobs by stable Wellfound listing ID;
- label jobs `NEW`, `UPDATED`, or `UNCHANGED` between scheduled runs;
- emit only new or changed jobs to reduce downstream work.

### Who is it for?

#### Recruiters and talent teams

Build focused startup-job lists by role, location, compensation, and remote
availability. Schedule the Actor to watch searches your team repeats.

#### Job boards and data teams

Send consistent Wellfound job records into a spreadsheet, warehouse, database,
or internal search index.

#### Startup and labor-market analysts

Compare hiring activity, compensation ranges, remote policies, and role demand
across startup segments and locations.

#### AI agents and workflow builders

Use the Actor through the Apify API or MCP to retrieve current source records
before summarization, matching, or enrichment.

### Why use this Actor?

- **Structured SSR extraction:** parses Wellfound's embedded application state,
  rather than relying only on fragile visible text selectors.
- **Role and location targeting:** supports Wellfound's public SEO result routes.
- **Rich job rows:** result pages can include the full description as well as
  compensation, experience, startup, and remote fields.
- **Change monitoring:** persistent hashes identify listing changes between runs.
- **Bounded anti-block handling:** rotates challenged browser sessions and can
  fall back from datacenter to sticky US residential proxies.
- **Cost control:** blocks images, media, fonts, and unrelated third-party
  requests; duplicate or filtered records are not charged.

### What data can you extract?

| Field | Meaning |
| --- | --- |
| `jobId` | Stable Wellfound listing ID |
| `title` | Job title |
| `companyName` | Hiring startup name |
| `companySlug` | Wellfound startup slug |
| `companySize` | Company-size band, when available |
| `companyDescription` | Short startup description |
| `jobType` | Employment type |
| `primaryRole` | Wellfound role title or slug |
| `description` | Public job description, when embedded |
| `locations` | Listed job locations |
| `acceptedRemoteLocations` | Regions accepted for remote work |
| `remote` | Whether the job is remote-capable |
| `remoteType` | Remote configuration such as `REMOTE` |
| `compensation` | Original salary and equity text |
| `salaryMin`, `salaryMax` | Parsed salary range |
| `equityMinPercent`, `equityMaxPercent` | Parsed equity range |
| `experienceMinYears`, `experienceMaxYears` | Experience range |
| `postedAt` | Wellfound listing start timestamp |
| `url` | Canonical Wellfound job URL |
| `sourceUrl` | Result page used for extraction |
| `badges` | Startup badges from the result |
| `changeType` | `FOUND`, `NEW`, `UPDATED`, or `UNCHANGED` |
| `scrapedAt` | Extraction timestamp |

Source fields can be absent. Missing values are returned as `null` or an empty
array rather than invented.

### How to scrape Wellfound startup jobs

1. Open the Actor input in Apify Console.
2. Add one or more role slugs, such as `software-engineer`.
3. Optionally add location slugs, such as `new-york`.
4. Set `remoteOnly` if you need Wellfound's remote route.
5. Keep `proxyTier` set to `AUTO` unless you are testing a specific proxy path.
6. Choose `maxItems` and `maxPages`.
7. Start the run and open the **Wellfound jobs** dataset view.
8. Export the dataset or connect it to your workflow.

A useful first input is:

```json
{
  "roles": ["software-engineer"],
  "locations": ["new-york"],
  "maxItems": 20,
  "maxPages": 1,
  "proxyTier": "AUTO"
}
```

### Input parameters

| Input | Type | Default | Description |
| --- | --- | --- | --- |
| `roles` | string array | `software-engineer` in prefill | Wellfound role slugs |
| `locations` | string array | empty | Wellfound location slugs combined with roles |
| `query` | string | empty | Post-filter for title, company, role, or description |
| `startUrls` | URL array | empty | Public Wellfound `/jobs` or `/role` search URLs |
| `remoteOnly` | boolean | `false` | Use remote role routes and keep remote jobs |
| `maxItems` | integer | `50` | Maximum unique jobs saved |
| `maxPages` | integer | `3` | Maximum pages per route |
| `proxyTier` | enum | `AUTO` | Automatic, datacenter-only, or US residential-only |
| `monitorChanges` | boolean | `false` | Compare jobs with a prior snapshot |
| `stateKey` | string | empty | Stable label for one monitored search |
| `onlyNewOrChanged` | boolean | `false` | Skip unchanged records in monitoring mode |

Role and location values are lowercase URL slugs. The Actor rejects malformed
values and non-Wellfound URLs before scraping.

#### Free-text filtering

Wellfound's public `/jobs?q=` surface currently exposes a bounded featured set,
not a guaranteed exhaustive keyword index. The Actor therefore applies `query`
to the returned title, company, role, and description.

Use a public role route for broad source coverage. Use `query` to narrow those
records or to inspect the current public `/jobs` set.

### Wellfound role and URL examples

Software engineering:

```json
{
  "roles": ["software-engineer"],
  "maxItems": 50
}
```

Product management in Berlin:

```json
{
  "startUrls": [
    { "url": "https://wellfound.com/role/l/product-manager/berlin" }
  ],
  "maxItems": 20,
  "maxPages": 1
}
```

Remote data analyst jobs:

```json
{
  "roles": ["data-analyst"],
  "remoteOnly": true,
  "maxItems": 50
}
```

### Output example

A current result has this shape:

```json
{
  "jobId": "3317746",
  "title": "Software Engineer",
  "companyName": "Keeper",
  "companySlug": "keeper-tax",
  "companySize": "11-50",
  "companyDescription": "File your complex taxes confidently",
  "jobType": "full-time",
  "primaryRole": "Software Engineer",
  "description": "Mission and role details...",
  "locations": ["San Francisco"],
  "acceptedRemoteLocations": ["United States"],
  "remote": true,
  "remoteType": "ONSITE_OR_REMOTE",
  "compensation": "$135k – $175k • 0.05% – 0.25%",
  "salaryMin": 135000,
  "salaryMax": 175000,
  "equityMinPercent": 0.05,
  "equityMaxPercent": 0.25,
  "experienceMinYears": 0,
  "experienceMaxYears": null,
  "postedAt": "2026-07-28T20:58:57.000Z",
  "url": "https://wellfound.com/jobs/3317746-software-engineer",
  "sourceUrl": "https://wellfound.com/role/software-engineer?page=1",
  "badges": ["ACTIVELY_HIRING"],
  "changeType": "FOUND",
  "scrapedAt": "2026-08-09T14:20:00.000Z"
}
```

The source changes continuously, so IDs, listings, and values in future runs
will differ.

### Monitor new and changed Wellfound jobs

Enable `monitorChanges` and provide a stable `stateKey`. The first run labels
current jobs `NEW`. Later runs compare stable content fields:

- `NEW`: listing ID was not in the prior snapshot;
- `UPDATED`: tracked listing content changed;
- `UNCHANGED`: content hash is the same;
- `FOUND`: ordinary non-monitoring run.

Example:

```json
{
  "roles": ["data-analyst"],
  "remoteOnly": true,
  "maxItems": 100,
  "maxPages": 2,
  "monitorChanges": true,
  "stateKey": "remote-data-analyst-watch",
  "onlyNewOrChanged": true
}
```

Use the same `stateKey` only for the same search universe. Changing roles,
locations, or limits while reusing a key changes what the snapshot represents.

### How much does it cost to scrape Wellfound startup jobs?

The Actor uses pay-per-event pricing:

- one `start` event per run;
- one `item` event for each emitted dataset record;
- filtered, duplicate, unchanged-skipped, and failed records are not item events.

The measured configuration charges a **$0.005 start fee**. At the BRONZE item
tier, each emitted job is **$0.0013131**.

| Emitted jobs | Example BRONZE total |
| ---: | ---: |
| 20 | $0.031262 |
| 100 | $0.13631 |
| 500 | $0.66155 |

Actual item rates depend on the applicable Apify pricing tier. Proxy and compute
usage can vary with anti-bot retries, but users are billed through the declared
Actor events rather than a separate proxy event.

### Scheduling and export workflows

#### Recruiting monitor

Schedule the monitoring input daily. Send only `NEW` and `UPDATED` rows to Slack,
a CRM, or an applicant-tracking workflow.

#### Labor-market dataset

Run a list of role/location URLs on a regular schedule. Export JSON, CSV, Excel,
XML, or RSS through Apify dataset endpoints.

#### Compensation analysis

Store `salaryMin`, `salaryMax`, and equity fields in a warehouse. Retain
`compensation` to audit parsing against the source text.

#### Startup enrichment

Join `companyName` or `companySlug` with a separate company-domain or enrichment
workflow. This Actor intentionally keeps its primary output job-focused.

### Run with the Apify API

Replace `APIFY_TOKEN` with your token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~wellfound-startup-jobs-scraper/runs?token=APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"roles":["software-engineer"],"locations":["new-york"],"maxItems":20}'
```

To wait and retrieve dataset items:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~wellfound-startup-jobs-scraper/run-sync-get-dataset-items?token=APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"roles":["product-manager"],"maxItems":10}'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/wellfound-startup-jobs-scraper').call({
  roles: ['software-engineer'],
  locations: ['new-york'],
  maxItems: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient('APIFY_TOKEN')
run = client.actor('automation-lab/wellfound-startup-jobs-scraper').call(
    run_input={
        'roles': ['data-analyst'],
        'remoteOnly': True,
        'maxItems': 20,
    }
)
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use through MCP

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/wellfound-startup-jobs-scraper"
```

#### Claude Desktop, Cursor, and VS Code setup

Use the same remote MCP server JSON in Claude Desktop, Cursor, or VS Code:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/wellfound-startup-jobs-scraper"
    }
  }
}
```

Example prompts:

- "Find current Wellfound software engineer jobs in New York and compare salary ranges."
- "Run my remote data analyst monitor and summarize only new or updated roles."
- "Export the current Berlin product manager listings as a concise table."

### Performance and proxy behavior

The target uses Cloudflare and DataDome. A direct request may return a challenge
instead of job data.

`AUTO` uses this bounded strategy:

1. open a sticky datacenter browser session;
2. reuse a healthy identity for pages in the run;
3. retire an identity after a challenge or missing structured state;
4. retry with another datacenter identity;
5. fall back to sticky US residential identities when necessary.

Images, fonts, media, analytics, and unrelated third-party requests are blocked.
A run fails clearly after bounded retries instead of silently returning a false
empty dataset.

### Limits and expected behavior

- Wellfound can change its routes, embedded state, fields, and anti-bot rules.
- Public role pages expose a subset of all jobs per startup and page.
- Free-text filtering is bounded by the records Wellfound exposes publicly.
- Some listings omit compensation, equity, experience, or remote details.
- Salary parsing preserves source text but does not convert currencies.
- A source page with no matching jobs produces an empty dataset successfully.
- A challenge after all configured retries fails the run with a non-zero status.
- Monitoring tracks listings observed within your chosen page and item limits.

### Troubleshooting

#### The run failed with a Wellfound challenge

Use `AUTO` first. If your workflow deliberately forced `DATACENTER`, retry with
`RESIDENTIAL`. Do not repeatedly rerun an unchanged failed task without checking
the run log and source availability.

#### My location returned no jobs

Use the lowercase Wellfound URL slug, such as `new-york`, and verify that the
corresponding public role/location page exists. Naturally sparse searches can
return zero records.

#### Why are compensation fields null?

Wellfound does not publish compensation for every job. The Actor does not infer
or estimate missing salary or equity.

#### Why did a second monitoring run emit nothing?

With `onlyNewOrChanged: true`, that is the expected result when all observed jobs
match the previous snapshot.

### Responsible use and legality

This Actor accesses public, anonymous Wellfound pages. Web-scraping rules vary by
jurisdiction and use case. Review Wellfound's terms, robots guidance, applicable
privacy law, employment-data rules, and your contractual obligations.

Do not use job data for unlawful discrimination, harassment, spam, or attempts
to identify private individuals. Minimize retained data, respect deletion and
access rights where applicable, and use conservative schedules.

### FAQ

#### Does this require a Wellfound account?

No. The supported routes are public and anonymous.

#### Can it scrape any job title as a role?

Role inputs follow Wellfound's URL taxonomy. Common values include
`software-engineer`, `product-manager`, `data-analyst`, `growth-marketer`,
`sales-manager`, and `operations-manager`.

#### Does it include full job descriptions?

Role and location result state commonly includes descriptions. The field is
nullable because Wellfound can omit or change it.

#### Can I export to Excel or Google Sheets?

Yes. Use Apify's dataset export or integrations after the run.

#### Can I run it on a schedule?

Yes. Apify schedules are especially useful with `monitorChanges` and
`onlyNewOrChanged`.

#### Are unchanged jobs charged in monitoring mode?

They are not item events when `onlyNewOrChanged` is enabled.

### Related automation-lab Actors

- [Cutshort Jobs Scraper](https://apify.com/automation-lab/cutshort-jobs-scraper)
  for another technology hiring source.
- [Company Domain Finder](https://apify.com/automation-lab/company-domain-finder)
  to enrich hiring-company names with domains in a separate workflow.

These Actors are optional. Wellfound extraction works independently.

# Actor input Schema

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

Wellfound role slugs such as software-engineer, product-manager, data-analyst, or growth-marketer.

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

Wellfound location slugs such as new-york, san-francisco, berlin, or london. Each location is combined with every selected role.

## `query` (type: `string`):

Keep listings whose title, company, role, or description contains this phrase. Wellfound's public free-text page exposes a bounded featured set; use role filters for broader coverage.

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

Optional public wellfound.com /jobs, /role, or role/location search URLs. The same filters and limits apply to these URLs.

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

Use Wellfound's remote role route and keep only listings marked remote. Location routes remain location-specific and are filtered after extraction.

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

Maximum unique job records saved across every route and page.

## `maxPages` (type: `integer`):

Maximum Wellfound result pages to inspect for each role, location, or search URL.

## `proxyTier` (type: `string`):

AUTO starts with lower-cost datacenter browser sessions and falls back to sticky US residential sessions after challenges. Force one tier for controlled workflows.

## `monitorChanges` (type: `boolean`):

Compare stable listing fields with the prior run that used the same state key and label records NEW, UPDATED, or UNCHANGED.

## `stateKey` (type: `string`):

Stable private label for one monitored search, for example engineering-us-remote. Required when change tracking is enabled.

## `onlyNewOrChanged` (type: `boolean`):

When monitoring, skip unchanged listings from the dataset and charges.

## Actor input object example

```json
{
  "roles": [
    "software-engineer"
  ],
  "startUrls": [],
  "remoteOnly": false,
  "maxItems": 20,
  "maxPages": 3,
  "proxyTier": "AUTO",
  "monitorChanges": false,
  "onlyNewOrChanged": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing normalized Wellfound startup job records.

## `monitoringState` (type: `string`):

Private key-value store records used when change tracking is enabled.

# 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"
    ],
    "startUrls": [],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/wellfound-startup-jobs-scraper").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"],
    "startUrls": [],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/wellfound-startup-jobs-scraper").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"
  ],
  "startUrls": [],
  "maxItems": 20
}' |
apify call automation-lab/wellfound-startup-jobs-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/Vo00saXTXBZx5P3D6/builds/t7bgFGGxkGOqq9s3b/openapi.json
