# $0.99💰Wellfound · Startup Jobs + Funding Stage Signals (`memo23/wellfound-jobs-scraper`) Actor

\[$0.99💰] Wellfound startup jobs scraper — paste any /jobs listing URL (with optional ?market/?industry/?location filter) and get flat rows with title, comp band, locations, remote flag, company size, market tags, and Wellfound's funding-stage signals. Listings-only, JSON/CSV out

- **URL**: https://apify.com/memo23/wellfound-jobs-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Jobs, Automation, Agents
- **Stats:** 21 total users, 18 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.99 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

Scrape startup job listings from **Wellfound.com** (formerly AngelList Talent) — title, compensation band, locations, remote flag, posted date, plus the **startup**'s name, logo, slug, company-size band, market tags, headcount, and Wellfound's **funding-stage / top-investor / recently-funded / growing-fast** signals — denormalized into every row. **Paste any `/jobs` listing URL** (with optional `?location`, `?industry`, or `?market` filter) and get back self-contained flat rows ready for CSV.

![How Wellfound Startup Jobs Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-wellfound.png)

### Why this actor

Wellfound is the largest English-language startup job board — ~50 jobs per listing page across many filters and ~500 pages of pagination. It also runs **DataDome** anti-bot protection on company-profile, role-search, and individual-job-detail pages, so most scrapers either break or charge premium prices for thin data.

This actor takes a different angle: **everything you need is already on the listing page**. Wellfound server-renders its `/jobs` Apollo state with the full JobListing + Startup graph embedded — one fetch unlocks ~50 jobs with denormalized company data, no detail-page enrichment required.

- **Three-stack race fetch** — impit (Rust + rustls Firefox), gotScraping (Node + headerGenerator), and **impers** (libcurl-impersonate Chrome 142). The fastest legit response wins per page, so a single fingerprint hiccup doesn't burn the retry budget
- **Apollo-state extraction** — one `JSON.parse` of `__NEXT_DATA__` resolves `JobListing` → `Startup` → `Badge` / `NewTag` / `JobListingRemoteConfig` refs in-memory. No DOM walking
- **Per-URL `maxItems`** — paste 3 listing filters with `maxItems: 200` → up to 600 rows (200 per filter). Free-tier users have a hidden global ceiling of 100 rows
- **Apify Residential US** by default — Wellfound is US-centric and serves canonical English pages with full Apollo state on US exits
- **One flat row per job** — company-level fields are denormalized on every row so CSV consumers don't need to join
- **No actor-start fee** — pricing is a flat `$0.0015` per row (`$1.50 / 1,000 jobs`). Your cost = rows × rate, with nothing extra on top. Most Wellfound scrapers add a per-run charge ($0.005-$0.20) on top of their per-row rate; we don't

### v1.1 — opt-in `/company/{slug}` enrichment 🆕

When you set `enrichCompanyProfile: true`, after the listings phase completes the actor runs a second pass: for each unique startup in the dataset, it fires 30 parallel undici fetches at `/company/{slug}`, parses the Apollo state, and merges these fields into **every job row for that company**:

| Field | What it carries | Example (Airbnb) |
|---|---|---|
| `companyTotalRaised` | Total funding amount in USD (integer) | `11333560000` ($11.3 B) |
| `companyFundingRoundsCount` | Number of recorded rounds | `20` |
| `companyLatestRoundType` | Most recent round name | `"IPO"` |
| `companyLatestRoundClosedAt` | ISO timestamp of latest round | `"2020-11-27T..."` |
| `companyFundingRounds[]` | Full round history (`roundType`, `closedAt`, `valuation`) | 20 rounds back to Series B 2011 |
| `companyProductDescription` | Long-form product/company bio | Full Airbnb marketing copy |
| `companyWebsiteUrl` | Official company URL (not Wellfound) | `"http://airbnb.com"` |
| `companyTwitterUrl` / `companyLinkedinUrl` / `companyFacebookUrl` / `companyBlogUrl` / `companyProductHuntUrl` | All social URLs | Populated when present |
| `companyIsOperating` | Whether Wellfound flags it as operational | `true` |
| `companyIsIncubator` | Whether the profile is an incubator | `false` |
| `companyIsShell` | Wellfound's shell-company flag | `false` |
| `companyIsYcFunded` | Y Combinator funding (new on /company/, not exposed on listings!) | `true` |
| `companyProfileCompletenessScore` | Wellfound's internal 0-100 completeness | `78` |
| `companyFounders[]` | Founder identities resolved from User refs | `[{name: "Joe Gebbia", slug: "joegebbia", ...}, {name: "Brian Chesky", ...}]` |
| `enrichmentStatus` | `'enriched'` / `'failed'` / `null` | — |
| `enrichmentAttempts` | How many fetch attempts the burst used | `7` |

#### Bonus — per-job "side-band" data (free side-effect of company enrichment)

The `/company/{slug}` Apollo state embeds the company's recent JobListings **with richer fields than the listing-page versions**. When company enrichment succeeds, the embedded data is harvested for free and populated on the matching job rows — no extra fetches, no extra charges, no DataDome wall to cross:

| Field | Description | Coverage example (Airbnb) |
|---|---|---|
| `jobDescriptionSnippet` | First ~500 chars of the job description as HTML (the "snippet" Wellfound shows in cards). **Partial answer to "full job description" without /jobs/{id}.** | 10/10 jobs populated |
| `jobType` | `"full_time"` / `"contract"` / `"part_time"` / `"internship"` | 10/10 |
| `equity` | Equity component separately from compensation (e.g. `"0.1% – 0.5%"`) | 0/10 (Airbnb's public, no equity offered) |
| `yearsExperienceMin` / `yearsExperienceMax` | Required experience range | 10/10 |
| `autoPosted` | `true` if the job is auto-syndicated from an ATS | 10/10 (Airbnb is auto-posted) |
| `atsSource` | Original ATS source (`"greenhouse"` / `"lever"` / etc.) when syndicated | 0/10 (Airbnb returns null) |
| `recruitingContact` | **Hiring-manager identity** when Wellfound exposes it — `{ name, slug, avatarUrl, pathName }`. Typically populated for manually-posted jobs at smaller startups, null for auto-posted ATS jobs. | 0/10 (Airbnb is ATS-auto-posted) |

#### Pricing

| Event | When charged | Rate |
|---|---|---|
| `additional-data` | Every job row written | `$0.0015` ($1.50 / 1k rows) |
| `company-enrichment` | **Per successful company** (de-duped — a company with 56 jobs = 1 charge) | `$0.0015` per company |

So a 1,000-row run with enrichment ON across ~150 unique companies costs roughly **$1.50 (rows) + $0.225 (companies) = $1.725**. Failed enrichments cost nothing extra.

#### Honest caveats

- **Best-effort fetching.** Wellfound's DataDome wall on `/company/` lets a fluctuating **5-15% of attempts** through per IP-session. With 30 parallel attempts per company we typically hit **70-90% URL success rate** — but in observed pool-degraded windows we've seen 0%. Every row carries `enrichmentStatus` so you always know which got through.
- **`enrichJobDetail` is the harder surface.** Wellfound's job-detail pages are protected more aggressively than company pages — expect ~30-60% per-job success on a good day, lower during anti-bot surges. Failed enrichments are NOT charged.

---

### Honest field-coverage note

Wellfound only attaches the full structured graph to **featured listings** (~4 of ~50 jobs per page). The remaining ~92% of rows carry the basic job + company-identity fields (title, comp band, locations, remote, posted, company name + slug + logo) but **leave the funding-stage / market-tags / badges / company-size fields as `null` / empty arrays**.

**What this means for you:**

| Always populated (every row) | Sparse — only on featured rows (~8%) |
|---|---|
| `jobId`, `jobTitle`, `jobUrl`, `jobSlug` | `companySize`, `companySizeBand` |
| `compensation` + parsed min/max/currency/equity | `companyHighConcept` |
| `locations[]`, `remote`, `remoteKind`, `wfhFlexible` | `liveJobListingsCount` |
| `primaryRoleSlug`, `postedAt`, `postedAtUnix` | `marketTags[]`, `locationTags[]` |
| `companyId`, `companyName`, `companySlug`, `companyUrl`, `companyLogoUrl` | `companyStage`, `companyStageLabel` |
| `recentlyFunded`, `hasTopInvestors`, `growingFast`, `activelyHiring`, `topResponder`, `quickResponder` (default `false` for non-featured) | `businessType` (B2B / B2C) |
|  | `allBadgeLabels[]` |

To get only the rich-featured rows, filter your output for `companyStage != null` post-run. Across multiple pages the featured set rotates, so paginating to `?page=N` reveals progressively more featured startups.

### Use cases

- **Startup hiring tracker** — paginate `/jobs?market=ai` daily to track which AI startups are hiring fastest, what salary bands they advertise, and which companies hit Wellfound's `GROWING_FAST` or `RECENTLY_FUNDED` flags
- **Sourcer / recruiter tooling** — feed `companySlug` + `companyName` into outbound CRMs to build a "currently hiring in {market}" lead list; the compensation band on every row lets you pre-filter by salary tier
- **Compensation benchmarking** — `compensationMin` / `compensationMax` / `compensationCurrency` / `hasEquity` are parsed from Wellfound's raw band strings, so you can run quantile analysis without re-parsing
- **VC / analyst feeds** — featured-row signals (`companyStage`, `recentlyFunded`, `hasTopInvestors`, `growingFast`) are useful for tracking which startups Wellfound itself flags as venture-backed and growing. Honest caveat: investor names + raise amounts aren't published on the listing surface, only the boolean flags
- **Remote-job aggregation** — `remote: true` + `acceptedRemoteLocations[]` lets you filter for region-eligible remote roles

### Input

| Field | Type | Required | Notes |
|---|---|---|---|
| `startUrls` | `string[]` | yes | Wellfound `/jobs` listing URLs (optionally with `?location`, `?industry`, `?market`, `?page` params). Detail URLs (`/jobs/{id}`, `/company/{slug}`, `/role/...`) are rejected — DataDome blocks them for HTTP-only clients. |
| `maxItems` | `integer` | no | Maximum job rows emitted **per startUrl**. 3 listings × `maxItems: 200` → up to 600 total rows (200 each). Each row = one paid `additional-data`. Default `1000`. Free-tier users have a hidden global ceiling of `100` rows. |
| `maxConcurrency` | `integer` | no | Parallel HTTP requests across listing URLs. Sweet spot 3–5 via Apify Residential US. Default `4`. |
| `maxRequestRetries` | `integer` | no | Per-URL retry budget. Each retry rotates the proxy session with mild exponential backoff and re-races the three HTTP stacks. Default `10`. |
| `proxy` | object | no | **Apify Residential US** is the default. Direct connections from non-US IPs sometimes get rerouted to localized variants; US residential always returns canonical English pages. |

#### Example input

```json
{
  "startUrls": [
    "https://wellfound.com/jobs",
    "https://wellfound.com/jobs?market=ai",
    "https://wellfound.com/jobs?location=san-francisco"
  ],
  "maxItems": 200,
  "maxConcurrency": 4,
  "proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "US" }
}
````

That yields **up to 600 job rows** — 200 per listing URL, ~4 pages each (Wellfound serves ~50 jobs per page).

### Output schema

One flat row per `JobListing`. All identity + compensation + remote + posted fields are populated on every row; the structured "featured" fields are sparse (see honest note above).

```jsonc
{
  // ── Job identity ──
  "jobId":           "4246042",
  "jobUrl":          "https://wellfound.com/jobs/4246042-sales-development-representative",
  "jobSlug":         "sales-development-representative",
  "jobTitle":        "Sales Development Representative",

  // ── Compensation (parsed best-effort from Wellfound's free-text band) ──
  "compensation":         "$40k – $80k • No equity",
  "compensationMin":      40000,
  "compensationMax":      80000,
  "compensationCurrency": "USD",
  "hasEquity":            false,

  // ── Location + remote ──
  "locations":               ["Dubai", "New York City", "San Francisco", "London", "Paris", "Bengaluru"],
  "acceptedRemoteLocations": [],
  "remote":                  true,
  "remoteKind":              "REMOTE",       // REMOTE / ONSITE / HYBRID
  "wfhFlexible":             false,

  // ── Role + time ──
  "primaryRoleSlug":  "sales-development-3",
  "postedAt":         "2026-05-22T06:49:02.000Z",
  "postedAtUnix":     1779432542,

  // ── Company identity (denormalized — always populated) ──
  "companyId":         "10559109",
  "companyName":       "CredShields Technologies",
  "companySlug":       "credshields-blockchain-security",
  "companyUrl":        "https://wellfound.com/company/credshields-blockchain-security",
  "companyLogoUrl":    "https://photos.wellfound.com/startups/i/10559109-….jpg",

  // ── Company structured data (FEATURED ROWS ONLY — ~8% of rows have these) ──
  "companySize":           "SIZE_201_500",       // null on non-featured rows
  "companySizeBand":       "201-500 employees",   // null on non-featured rows
  "companyHighConcept":    "Unlock the potential of every investment partnership",  // null on non-featured rows
  "liveJobListingsCount":  56,                    // null on non-featured rows — total open jobs at this company
  "marketTags":            ["Real Estate Tech", "B2B Software"],   // [] on non-featured rows
  "locationTags":          ["San Francisco"],     // [] on non-featured rows

  // ── Wellfound badge signals (FEATURED ROWS ONLY) ──
  "companyStage":      "scale_stage",        // "early_stage" / "scale_stage" / null
  "companyStageLabel": "Scale Stage",         // human label / null
  "recentlyFunded":    false,                  // raised in last 6 months (boolean)
  "hasTopInvestors":   true,                   // Wellfound flagged top investors (boolean)
  "growingFast":       true,                   // strong hiring growth in last month (boolean)
  "activelyHiring":    true,                   // actively processing applications (boolean)
  "topResponder":      false,                  // top 1% of responders (boolean)
  "quickResponder":    false,                  // responds within a day (boolean)
  "businessType":      "B2B",                  // "B2B" / "B2C" / null
  "allBadgeLabels":    ["Actively Hiring", "B2B", "Scale Stage", "Top Investors", "Growing fast"],

  // ── Meta ──
  "sourcePageUrl":    "https://wellfound.com/jobs",
  "sourcePageIndex":  1,
  "scrapedAt":        "2026-05-22T09:13:58.526Z"
}
```

### Key output fields

- **`jobId` + `jobUrl`** — stable Wellfound identifiers. `jobUrl` is the canonical permalink; useful as a join key even though Wellfound itself blocks HTTP fetches of the URL
- **`compensation` parsed band** — `compensationMin` / `compensationMax` come from Wellfound's free-text strings via a best-effort regex. `null` when Wellfound shows "Competitive" or omits a band entirely
- **`remote` + `remoteKind` + `wfhFlexible`** — three flags so you can distinguish "fully remote", "on-site with WFH flexibility", and "hybrid"
- **`postedAt` ISO + `postedAtUnix`** — the moment Wellfound first published the listing (`liveStartAt` in their schema)
- **Company "rich" fields** — only populated on featured rows. The honest note above explains why — Wellfound only attaches the structured graph to paid-promoted listings, and we report what Wellfound actually serves rather than padding non-featured rows with fake data

### How it works

1. **Resolve & dedupe** the `startUrls` — accept `/jobs[?…]` listing URLs; reject detail URLs up-front with a clear reason
2. **Race three HTTP stacks** (impit Firefox / gotScraping / impers Chrome 142) against the first page; first 200 OK with a real body (~250 KB) wins
3. **Parse `__NEXT_DATA__`** — one `JSON.parse` resolves the full Apollo normalized graph (`JobListing`, `Startup`, `Badge`, `NewTag`, `JobListingRemoteConfig`)
4. **Walk JobListing entries** in document order, resolve refs in-memory, emit one flat row per job with denormalized company data
5. **Paginate** to `?page=N+1` until either the parser returns 0 rows or per-URL `maxItems` is hit
6. **Push each row** through `Dataset.pushData` + `Actor.chargeOutputRecord('additional-data')`

### FAQ

**Why are the company-size / market-tag / badge fields empty on most rows?**
Wellfound only attaches the full Apollo Startup payload to featured (paid-promoted) listings — roughly 4 of every 50 jobs per page. Non-featured rows get the lean shape (`id`, `name`, `slug`, `logoUrl`). We surface the truth of what Wellfound serves; we don't fabricate data. To get only the rich rows, filter your dataset post-run for `companyStage != null`.

**Can you scrape the full job description / company profile / investor list?**
No — those live behind DataDome-protected detail pages (`/jobs/{id}`, `/company/{slug}`) that don't serve to non-browser clients. Adding a JS-runtime stack would bypass this but would also dramatically raise per-row cost and break the listings-only price point. We chose to ship narrow + honest.

**Is the actor US-only?**
The default proxy is US Residential because Wellfound is US-centric and US exits return canonical English pages. EU residential also works; the proxy is configurable.

**Does pagination really go to page 500?**
Yes — we verified `/jobs?page=500` returns 200 OK with full Apollo state. The realistic ceiling is wherever Wellfound stops serving fresh listings; the scraper's natural stop condition is "0 rows on a page → end".

**What happens if Wellfound changes the Apollo schema?**
The parser emits a structured warning (`apolloState.data missing or malformed`) and the page is treated as the end of pagination — noisy degradation rather than silent breakage. You'll see the warning in the log immediately on the first run.

**How do I get only fully-remote jobs?**
Filter the output for `remote === true`. We can't push the `?remote=true` query filter to Wellfound directly — DataDome blocks that specific param — so we filter client-side after the scrape.

### Support

Issues / feature requests / pricing questions — open a ticket on the [Apify console](https://console.apify.com/) issues tab for this actor.

### Additional services

Apify hosts a portfolio of complementary actors covering related surfaces. If you need scrapers for LinkedIn jobs, Indeed, Glassdoor reviews, or AmbitionBox employee feedback, check the same author's other listings.

### Explore more scrapers

If Wellfound covers your startup-job needs, you may also be interested in:

- **AmbitionBox Reviews Scraper** — employee reviews from India's leading review platform
- **TotalJobs Scraper** — UK-wide job listings from the Stepstone Group brands
- **Expedia Hotel Reviews Scraper** — Expedia + Hotels.com reviews with sort/filter URN support

### ⚠️ Disclaimer

This actor scrapes only publicly accessible Wellfound listing pages (`https://wellfound.com/jobs`). It does not bypass authentication, solve CAPTCHAs, or access private data. **Detail URLs (`/jobs/{id}`, `/company/{slug}`, `/role/...`) are explicitly rejected** — we don't try to fetch DataDome-protected surfaces. You are responsible for compliance with Wellfound's Terms of Service in your jurisdiction. The scraper is provided "as is" without warranty; use is at your own risk.

### SEO Keywords

wellfound scraper, wellfound jobs scraper, angellist talent scraper, angellist jobs scraper, startup job scraper, startup hiring scraper, wellfound api, wellfound listings scraper, vc-backed startup jobs, ai startup jobs scraper, fintech startup jobs scraper, san francisco startup jobs scraper, remote startup jobs scraper, wellfound salary scraper, wellfound compensation scraper, startup sourcing tool, recruiter sourcing scraper, hiring intelligence scraper, wellfound data export, apify wellfound, wellfound csv export, recently funded startup jobs, growing startups jobs scraper, top investor startups, scale stage startups, early stage startups jobs, wellfound market filter, wellfound industry filter, wellfound location filter, datadome bypass wellfound, headless wellfound scraper

# Actor input Schema

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

Paste one or more Wellfound `/jobs` listing URLs. Working shapes:
• Plain listing — `https://wellfound.com/jobs`
• Market filter — `https://wellfound.com/jobs?market=ai`
• Industry filter — `https://wellfound.com/jobs?industry=fintech`
• Location filter — `https://wellfound.com/jobs?location=san-francisco`
• Specific page — `https://wellfound.com/jobs?page=5` (combinable with filters)

⚠️ Detail URLs are NOT supported and will be rejected:
• `/jobs/{id}-{slug}` (individual job pages)
• `/company/{slug}` and `/company/{slug}/jobs`
• `/role/r/{role}` and `/role/l/...`

Wellfound blocks these via DataDome on non-browser clients. Use a `/jobs?…` filter to reach the same jobs from the listing surface.

**Leave empty to use the structured filter fields below instead.**

## `market` (type: `string`):

Wellfound market slug. Examples: `ai`, `fintech`, `web3`, `saas`, `cyber-security`, `developer-tools`, `mobile`, `e-commerce`, `consumer`, `b2b`. The slug is what appears in the URL after `?market=` when you filter on Wellfound's website. Used to build `https://wellfound.com/jobs?market={value}` when no `startUrls` is provided. Combinable with `location` below.

## `industry` (type: `string`):

Wellfound industry slug. Examples: `real-estate-tech`, `cyber-security`, `blockchain-cryptocurrency`, `health-care`, `education`, `gaming`. Used to build `https://wellfound.com/jobs?industry={value}` when no `startUrls` is provided. Note: `market` and `industry` overlap; pick one.

## `location` (type: `string`):

Wellfound location slug. Examples: `san-francisco`, `new-york`, `london`, `berlin`, `united-states`, `remote`, `europe`. Used to build `https://wellfound.com/jobs?location={value}` when no `startUrls` is provided. Can be combined with `market` or `industry` (e.g. `market: ai` + `location: san-francisco` → `https://wellfound.com/jobs?market=ai&location=san-francisco`).

## `keyword` (type: `string`):

Case-insensitive substring match across job title, role slug, company name, market tags, location tags, badge labels, and (when enrichment is on) job description. Rows that don't match get filtered out before being written to the dataset.

Examples:
• `rust` → keeps rows mentioning Rust
• `rust, golang, scala` → keeps rows mentioning ANY of the three (OR logic)
• `senior` → keeps senior-level roles
• `remote` → keeps rows where 'remote' appears anywhere (title, location tags, etc.)

**Cost behaviour**: filtering happens AFTER fetching, so Apify compute for the fetches is unchanged — but `additional-data` charges (and enrichment charges) only fire for rows that pass the filter. You don't pay for rows you filter out.

Leave empty to disable filtering.

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

Maximum job rows emitted **per startUrl**. Pass 3 listings with `maxItems: 200` → up to 600 total rows (200 each). Pass 1 listing with `maxItems: 5000` → up to 5000 rows from that listing. Each row is one paid `additional-data` event. Wellfound serves ~50 jobs per page; pagination has been verified clean to page 500. Default 1000. Free-tier users are additionally capped at 100 total rows across the whole run.

## `maxConcurrency` (type: `integer`):

Parallel HTTP requests across listing URLs. Wellfound's listing surface is friendly; concurrency 3-5 is the sweet spot. Higher values risk rate-limiting on the residential proxy pool, not on Wellfound's edge.

## `maxRequestRetries` (type: `integer`):

Per-URL retry budget. Each retry rotates the proxy session with mild exponential backoff and re-races three HTTP stacks (impit Firefox / gotScraping / impers Chrome142). Default 10 — Wellfound's listing surface is reliable enough that ≤3 retries usually suffice, but the budget is there for proxy hiccups.

## `enrichCompanyProfile` (type: `boolean`):

💰 **Pricing**: ADDITIONAL $1.50 per 1,000 unique companies enriched — on top of the base $1.50/1k row charge. De-duplicated: a company with 56 jobs = 1 enrichment charge, not 56. Failed enrichments are NOT charged. So a 1,000-row run across 150 unique companies costs ~$1.50 (rows) + ~$0.18 (120 of 150 successfully enriched) = ~$1.68 total.

Every job row also includes the company's:

• Total funding raised (e.g. Airbnb: $11.3B)
• Funding-round history — Series A/B/C, IPO, dates
• Founders — names, slugs, avatars (e.g. Brian Chesky, Joe Gebbia)
• Social URLs — Twitter, LinkedIn, Facebook, blog, ProductHunt
• Official company website
• Y Combinator badge (when applicable)
• Operating / incubator / shell flags + Wellfound's profile-completeness score

Bonus: for jobs whose company is successfully enriched, rows ALSO get job-type, equity, required years of experience, ATS source, and (when Wellfound exposes it) the recruiting contact's identity — all free with this toggle.

Reliability: typically 70-90% of unique companies enriched per run.

## `enrichJobDetail` (type: `boolean`):

💰 **Pricing**: ADDITIONAL $1.50 per 1,000 jobs enriched — on top of the base $1.50/1k row charge. Per-job (not per-company). Failed enrichments are NOT charged. So a 1,000-row run with ~40% job-detail success rate costs ~$1.50 (rows) + ~$0.60 (400 enriched) = ~$2.10 total.

Every job row also includes:

• Full job description (~4 KB of HTML, the same text Google shows in Jobs search)
• Structured salary — min, max, currency, time unit (year/month/hour)
• Employment type — full-time / part-time / contractor / intern
• Required years of experience
• Eligible-applicant countries (for remote roles)
• Direct-apply flag (whether Wellfound hosts the application form)
• Industry tag

Reliability today: ~30-60% on a good day, can drop to 0% during anti-bot surges. Wellfound's job-detail pages are the hardest to reach.

## `proxy` (type: `object`):

Apify Residential US is the default. Wellfound is US-centric — direct connections from non-US IPs occasionally get rerouted to a localized version of the site; US residential always returns the canonical English listing with full Apollo state. EU exits also work in practice.

## Actor input object example

```json
{
  "startUrls": [
    "https://wellfound.com/jobs",
    "https://wellfound.com/jobs?market=ai",
    "https://wellfound.com/jobs?location=san-francisco"
  ],
  "maxItems": 1000,
  "maxConcurrency": 4,
  "maxRequestRetries": 10,
  "enrichCompanyProfile": false,
  "enrichJobDetail": false,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# 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 = {
    "startUrls": [
        "https://wellfound.com/jobs",
        "https://wellfound.com/jobs?market=ai",
        "https://wellfound.com/jobs?location=san-francisco"
    ],
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/wellfound-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 = {
    "startUrls": [
        "https://wellfound.com/jobs",
        "https://wellfound.com/jobs?market=ai",
        "https://wellfound.com/jobs?location=san-francisco",
    ],
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

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

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

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

```

## CLI example

```bash
echo '{
  "startUrls": [
    "https://wellfound.com/jobs",
    "https://wellfound.com/jobs?market=ai",
    "https://wellfound.com/jobs?location=san-francisco"
  ],
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call memo23/wellfound-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=memo23/wellfound-jobs-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "$0.99💰Wellfound · Startup Jobs + Funding Stage Signals",
        "description": "[$0.99💰] Wellfound startup jobs scraper — paste any /jobs listing URL (with optional ?market/?industry/?location filter) and get flat rows with title, comp band, locations, remote flag, company size, market tags, and Wellfound's funding-stage signals. Listings-only, JSON/CSV out",
        "version": "0.0",
        "x-build-id": "3FJYnxyELmKyLUqdA"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/memo23~wellfound-jobs-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-memo23-wellfound-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/memo23~wellfound-jobs-scraper/runs": {
            "post": {
                "operationId": "runs-sync-memo23-wellfound-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/memo23~wellfound-jobs-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-memo23-wellfound-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "startUrls"
                ],
                "properties": {
                    "startUrls": {
                        "title": "Wellfound /jobs URLs",
                        "type": "array",
                        "description": "Paste one or more Wellfound `/jobs` listing URLs. Working shapes:\n• Plain listing — `https://wellfound.com/jobs`\n• Market filter — `https://wellfound.com/jobs?market=ai`\n• Industry filter — `https://wellfound.com/jobs?industry=fintech`\n• Location filter — `https://wellfound.com/jobs?location=san-francisco`\n• Specific page — `https://wellfound.com/jobs?page=5` (combinable with filters)\n\n⚠️ Detail URLs are NOT supported and will be rejected:\n• `/jobs/{id}-{slug}` (individual job pages)\n• `/company/{slug}` and `/company/{slug}/jobs`\n• `/role/r/{role}` and `/role/l/...`\n\nWellfound blocks these via DataDome on non-browser clients. Use a `/jobs?…` filter to reach the same jobs from the listing surface.\n\n**Leave empty to use the structured filter fields below instead.**",
                        "items": {
                            "type": "string"
                        }
                    },
                    "market": {
                        "title": "Market filter",
                        "type": "string",
                        "description": "Wellfound market slug. Examples: `ai`, `fintech`, `web3`, `saas`, `cyber-security`, `developer-tools`, `mobile`, `e-commerce`, `consumer`, `b2b`. The slug is what appears in the URL after `?market=` when you filter on Wellfound's website. Used to build `https://wellfound.com/jobs?market={value}` when no `startUrls` is provided. Combinable with `location` below."
                    },
                    "industry": {
                        "title": "Industry filter",
                        "type": "string",
                        "description": "Wellfound industry slug. Examples: `real-estate-tech`, `cyber-security`, `blockchain-cryptocurrency`, `health-care`, `education`, `gaming`. Used to build `https://wellfound.com/jobs?industry={value}` when no `startUrls` is provided. Note: `market` and `industry` overlap; pick one."
                    },
                    "location": {
                        "title": "Location filter",
                        "type": "string",
                        "description": "Wellfound location slug. Examples: `san-francisco`, `new-york`, `london`, `berlin`, `united-states`, `remote`, `europe`. Used to build `https://wellfound.com/jobs?location={value}` when no `startUrls` is provided. Can be combined with `market` or `industry` (e.g. `market: ai` + `location: san-francisco` → `https://wellfound.com/jobs?market=ai&location=san-francisco`)."
                    },
                    "keyword": {
                        "title": "Keyword(s) — comma-separated for OR logic",
                        "type": "string",
                        "description": "Case-insensitive substring match across job title, role slug, company name, market tags, location tags, badge labels, and (when enrichment is on) job description. Rows that don't match get filtered out before being written to the dataset.\n\nExamples:\n• `rust` → keeps rows mentioning Rust\n• `rust, golang, scala` → keeps rows mentioning ANY of the three (OR logic)\n• `senior` → keeps senior-level roles\n• `remote` → keeps rows where 'remote' appears anywhere (title, location tags, etc.)\n\n**Cost behaviour**: filtering happens AFTER fetching, so Apify compute for the fetches is unchanged — but `additional-data` charges (and enrichment charges) only fire for rows that pass the filter. You don't pay for rows you filter out.\n\nLeave empty to disable filtering."
                    },
                    "maxItems": {
                        "title": "Max jobs per listing URL",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum job rows emitted **per startUrl**. Pass 3 listings with `maxItems: 200` → up to 600 total rows (200 each). Pass 1 listing with `maxItems: 5000` → up to 5000 rows from that listing. Each row is one paid `additional-data` event. Wellfound serves ~50 jobs per page; pagination has been verified clean to page 500. Default 1000. Free-tier users are additionally capped at 100 total rows across the whole run.",
                        "default": 1000
                    },
                    "maxConcurrency": {
                        "title": "Max parallel requests",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Parallel HTTP requests across listing URLs. Wellfound's listing surface is friendly; concurrency 3-5 is the sweet spot. Higher values risk rate-limiting on the residential proxy pool, not on Wellfound's edge.",
                        "default": 4
                    },
                    "maxRequestRetries": {
                        "title": "Max request retries",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Per-URL retry budget. Each retry rotates the proxy session with mild exponential backoff and re-races three HTTP stacks (impit Firefox / gotScraping / impers Chrome142). Default 10 — Wellfound's listing surface is reliable enough that ≤3 retries usually suffice, but the budget is there for proxy hiccups.",
                        "default": 10
                    },
                    "enrichCompanyProfile": {
                        "title": "Add company funding + founders + social URLs  (extra +$1.50 per 1,000 unique companies enriched)",
                        "type": "boolean",
                        "description": "💰 **Pricing**: ADDITIONAL $1.50 per 1,000 unique companies enriched — on top of the base $1.50/1k row charge. De-duplicated: a company with 56 jobs = 1 enrichment charge, not 56. Failed enrichments are NOT charged. So a 1,000-row run across 150 unique companies costs ~$1.50 (rows) + ~$0.18 (120 of 150 successfully enriched) = ~$1.68 total.\n\nEvery job row also includes the company's:\n\n• Total funding raised (e.g. Airbnb: $11.3B)\n• Funding-round history — Series A/B/C, IPO, dates\n• Founders — names, slugs, avatars (e.g. Brian Chesky, Joe Gebbia)\n• Social URLs — Twitter, LinkedIn, Facebook, blog, ProductHunt\n• Official company website\n• Y Combinator badge (when applicable)\n• Operating / incubator / shell flags + Wellfound's profile-completeness score\n\nBonus: for jobs whose company is successfully enriched, rows ALSO get job-type, equity, required years of experience, ATS source, and (when Wellfound exposes it) the recruiting contact's identity — all free with this toggle.\n\nReliability: typically 70-90% of unique companies enriched per run.",
                        "default": false
                    },
                    "enrichJobDetail": {
                        "title": "Add full job description + structured salary + experience required  (extra +$1.50 per 1,000 jobs enriched)",
                        "type": "boolean",
                        "description": "💰 **Pricing**: ADDITIONAL $1.50 per 1,000 jobs enriched — on top of the base $1.50/1k row charge. Per-job (not per-company). Failed enrichments are NOT charged. So a 1,000-row run with ~40% job-detail success rate costs ~$1.50 (rows) + ~$0.60 (400 enriched) = ~$2.10 total.\n\nEvery job row also includes:\n\n• Full job description (~4 KB of HTML, the same text Google shows in Jobs search)\n• Structured salary — min, max, currency, time unit (year/month/hour)\n• Employment type — full-time / part-time / contractor / intern\n• Required years of experience\n• Eligible-applicant countries (for remote roles)\n• Direct-apply flag (whether Wellfound hosts the application form)\n• Industry tag\n\nReliability today: ~30-60% on a good day, can drop to 0% during anti-bot surges. Wellfound's job-detail pages are the hardest to reach.",
                        "default": false
                    },
                    "proxy": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify Residential US is the default. Wellfound is US-centric — direct connections from non-US IPs occasionally get rerouted to a localized version of the site; US residential always returns the canonical English listing with full Apollo state. EU exits also work in practice.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ],
                            "apifyProxyCountry": "US"
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
