πŸš€ Wellfound Jobs Scraper avatar

πŸš€ Wellfound Jobs Scraper

Pricing

from $4.99 / 1,000 results

Go to Apify Store
πŸš€ Wellfound Jobs Scraper

πŸš€ Wellfound Jobs Scraper

Pricing

from $4.99 / 1,000 results

Rating

0.0

(0)

Developer

Scraper Engine

Scraper Engine

Maintained by Community

Actor stats

0

Bookmarked

7

Total users

4

Monthly active users

22 days ago

Last modified

Share

Wellfound Jobs Scraper β€” Startup Roles, Salary and Descriptions

Wellfound Jobs Scraper extracts public startup job listings from Wellfound (formerly AngelList Talent) and returns job_title, company_name, salary, locations, isRemote and the full description as typed JSON. Search by location, role keyword or company, or paste Wellfound URLs in bulk. The description ships inside the same search payload as the listing, so a normal run needs no second request per job. No Wellfound account, login or cookie β€” start it from the Apify Console or the API.

What is Wellfound Jobs Scraper?

Wellfound Jobs Scraper is an Apify Actor that reads Wellfound's public job search and job pages with a stealth browser and returns 12 keys per listing. You describe the search with form fields β€” location, keyword, company, employment type, recency β€” and the Actor builds the Wellfound URL for you, or you hand it Wellfound URLs directly.

No Wellfound account, login or cookie is required, and there is no input field for one. Everything returned is what a signed-out visitor sees.

It is built for recruiters and talent teams tracking startup hiring, job-board and aggregator operators, compensation researchers, and developers piping listings into their own database or agent.

What Wellfound job data is publicly available to scrape?

Wellfound publishes the whole listing β€” title, employer, locations, remote status, compensation string and the complete description β€” to signed-out visitors, embedded as JSON in the search page itself. Everything that involves acting on a listing sits behind an account.

Data CategoryPublic β€” no loginNeeds a Wellfound account
Job title, employer name, employment typeβœ… Publicβ€”
Location list and remote/on-site statusβœ… Publicβ€”
Compensation string, including the equity clause when the employer published oneβœ… Publicβ€”
Full job descriptionβœ… Publicβ€”
Posting recencyβœ… Publicβ€”
Applying to a role, messaging the founder❌Candidate account
Saved jobs and curated role matches❌Candidate account
Candidate profiles and applicant pipelines❌Candidate / employer account

Wellfound Jobs Scraper only returns publicly visible data β€” what any visitor sees. Nothing behind a login wall.

A few fields that are public but deliberately not in this Actor's output: numeric salary minimum and maximum, the exact posting timestamp, company size and badges, and minimum years of experience. This Actor ships the compensation string as published and the posting age as relative wording.

What data can I extract with Wellfound Jobs Scraper?

Every row carries a rowType tag plus job identity, employer, location, compensation, timing and the full description. Job rows always contain the same 12 keys.

Field NameDescription
rowType"job" on a real listing, "error" on an uncharged accounting row
jobIdWellfound's own numeric listing id, as a string. The stable dedupe and join key
job_titleRole title as published
company_nameHiring startup's name
locationThe locations array comma-joined into one string. Falls back to "Remote" only when no named location was published
locationsArray of location names, one entry per office or region on the listing
isRemoteBoolean. The authoritative remote flag β€” read this rather than looking for "Remote" inside location
salaryNormalized compensation string, with any trailing equity or per-period clause preserved verbatim. Empty string when the employer published no pay
job_typeEmployment type normalized to Full-time, Part-time, Contract or Internship
dateRelative posting age as wording: today, yesterday, 4 days ago, 2 weeks ago, 3 months ago
URLCanonical wellfound.com/jobs/<id>-<slug> link, with Wellfound's own utm_campaign=google_jobs_apply tracking suffix appended
descriptionFull job description as plain text, with UTF-8 mojibake repaired
errorReasonError rows only. Typed reason a target was skipped
errorDetailError rows only. One-sentence explanation. Present in the JSON and API export; not in either Console table view

Job identity, employer and location

jobId is Wellfound's listing id and is populated on every job row, which makes it the key to diff runs on or to join against your own records. URL is built from jobId plus the listing slug, so it always points at a live Wellfound page β€” a card that arrives without a slug is skipped rather than turned into a URL that Wellfound 404s.

Location comes back twice on purpose. locations is the real array β€” a listing open in two cities gives you two entries. location is that array comma-joined, for spreadsheets and CSV exports. Remote status is a separate boolean, isRemote, so you can filter on it instead of pattern-matching a string.

Field naming is mixed and stays that way for backward compatibility: job_title, company_name and job_type are snake_case, jobId, isRemote, rowType, errorReason and errorDetail are camelCase, and URL is uppercase. The names are identical on every run.

Compensation, employment type and posting age

salary is a string, not parsed numerics. Wellfound publishes one compensation line per listing and this Actor normalizes it rather than decomposing it: "$140k – $185k β€’ 0.25% – 0.75%" becomes "140K–185K a year β€’ 0.25% – 0.75%". Everything after the bullet β€” the equity range, a per-hour note β€” is kept verbatim on the end instead of being discarded, and that is the only place equity data appears in the output. Two consequences worth knowing: a figure published without a k/m suffix is assumed to be thousands, and the phrase a year is appended to the range regardless of the underlying period, so read the preserved clause when the period matters. When the employer published no pay at all, salary is an empty string β€” that means undisclosed, not unpaid.

date is relative wording, derived from Wellfound's posting timestamp rather than published as an exact date. It is empty on the occasional card that carried no timestamp.

description is the field that usually costs nothing extra: Wellfound embeds it in the search payload for virtually every card, so the Actor reads it straight out of the listing page. Text values that are missing come back as an empty string, locations as [] and jobId as null β€” keys are never dropped, so downstream code needs no presence check.

πŸ€– Add-on: Need additional startup hiring data?

Hiring signals are more useful joined to something else. LinkedIn Jobs Scraper With Salary Range Filters covers the same roles on the larger board with exact posting dates, and LinkedIn Company URL - Mass Profile Finder With Firmographics turns the company_name values from a Wellfound run into firmographics for account scoring. If you are tracking why a startup is hiring, Google News Scraper By Publisher & Site Filter picks up the funding and launch coverage around the same companies.

Why not build this yourself?

Wellfound publishes no open public jobs API for third parties, so the public search surface is the only route to market-wide startup job data β€” and building against it yourself means owning four separate problems.

Anti-bot. Wellfound is fronted by DataDome. It answers a flagged request with a roughly 2.5 KB interstitial stub carrying <title>wellfound.com</title> instead of an error, so a naive scraper stores empty rows and believes it succeeded. Job-detail pages are throttled separately, and that throttling is cumulative rather than per-session, so it cannot be outrun with concurrency.

Two different payloads. Search and listing pages are a Next.js app whose real data sits in the __NEXT_DATA__ Apollo cache; individual /jobs/<id>-<slug> pages are Rails-rendered, carry no __NEXT_DATA__ at all, and expose their data as a schema.org ld+json JobPosting block instead. Gate both on the same marker and every job page looks blocked when it in fact loaded perfectly.

Pagination with no total. Wellfound publishes no page count anywhere β€” not in the DOM, not on any Apollo entity. There is no number to loop to; the only honest stop condition is "the next page added nothing new".

URL construction. A location-only search is not /jobs?location=<slug> β€” Wellfound ignores that parameter and serves a generic landing page of featured cards with no pagination. The genuine paginated page is /location/<slug>. Role searches are /role/r/<slug> and /role/l/<role>/<location>. Getting this wrong silently costs you most of the result set.

On top of that: a stealth browser build, a fingerprint coherent with the container it runs in, residential proxy rotation, and mojibake repair for pages served with a mismatched charset.

⚠️ Filters, caps and what happens on empty input

Four behaviours that are easy to get wrong, stated plainly.

An empty input does not fail β€” it silently widens. Nothing is required. If startUrls, locationName, companyName and includeKeyword all resolve to empty, the Actor logs a warning and crawls https://wellfound.com/jobs, Wellfound's generic jobs landing page. The Console hides this, because the input editor pre-fills locationName with New York; a Console run you never edited searches New York and looks correct. An API caller who posts {} β€” or who clears the location field β€” lands on the landing page instead, and that page is not a search. Wellfound serves it as a fixed block of featured cards (the source measured roughly 49) with no working pagination, so pagesToFetch above 1 buys nothing there. Always send at least one of those four parameters.

jobType and datePosted are post-fetch filters, not search parameters. They never reach Wellfound. The Actor fetches the listing page and then drops cards that do not match, which has two effects: pagesToFetch counts pages fetched, not rows kept, so a narrow filter can return very few rows from a full page; and because pagination stops when a page adds no new rows, a filter that rejects everything on page 2 ends the crawl there even if page 3 had matches. For a filtered sweep, raise pagesToFetch and expect the row count to be a fraction of the cards seen. datePosted also rejects a card whose posting age could not be parsed rather than letting it through, so an unknown date never satisfies a bounded window.

locationName and includeKeyword are applied by Wellfound, through the URL path. companyName is applied twice: it goes into a Wellfound keyword search, and the results are then filtered by a loose normalized substring match on the company name. Loose means loose β€” a short company name can match a longer one that contains it. Combining companyName with locationName produces a /jobs?keywords=…&location=… URL, and that location parameter is the one Wellfound ignores.

Leaving the proxy toggle off does not mean no proxy. Because DataDome blocks direct and datacenter connections from cloud IP ranges, the Actor starts on Apify residential proxy with sticky sessions when you leave proxyConfiguration at its default, rotating to a fresh residential exit IP on each retry. The input hint describing a no-proxy start is stale. Residential traffic counts toward your Apify proxy consumption. If you do enable Apify Proxy explicitly, a residential group starts at residential, and any other group starts at datacenter and escalates to residential on the first block.

Two caps, two owners. pagesToFetch is capped at 100 per starting URL by the Actor's schema, and the number of starting URLs is not capped, so the Actor-side ceiling is your seed list times 100. The practical ceiling is Wellfound's: a listing page carries roughly 45–60 cards, and pagination ends once a further page adds nothing new. requestDelay accepts 0 per the schema, but 0 is read as the 1-second default.

How to use Wellfound Jobs Scraper

Wellfound Jobs Scraper runs on Apify. Start it from the Apify Console or call it through the Apify API with your Apify token β€” there is no separate signup and no Wellfound credential.

  1. Open Wellfound Jobs Scraper on Apify and click Try for free
  2. Set Location β€” or a Keyword, or a Company Name, or paste Start URLs. No field is marked required, but supply at least one of those four or the run falls back to Wellfound's generic jobs landing page
  3. Narrow with Job Type and Date Posted if you need them, remembering that both are applied after the page is fetched
  4. Raise Pages to Fetch for more rows β€” each page is roughly 45–60 cards
  5. Click Start, then export as JSON, CSV or Excel, or read the dataset through the API

Leave Proxy Configuration alone unless you have your own proxy. The Actor already routes through Apify residential sessions, which is what Wellfound's anti-bot requires.

How to scale to bulk job extraction

startUrls is a list and takes priority over every search field, so one run can cover many searches. Mix forms freely: https://wellfound.com/location/san-francisco, https://wellfound.com/role/r/full-stack-engineer, https://wellfound.com/role/l/data-scientist/new-york, and individual https://wellfound.com/jobs/3312874-senior-backend-engineer pages in the same array. Listing URLs are paginated up to pagesToFetch; a job URL is fetched once, through the ld+json path.

Deduplication is per run and keyed on the canonical job URL, so overlapping seeds cannot produce the same listing twice in one dataset. Across runs, dedupe on jobId β€” it is Wellfound's own identifier and is stable, so the merge is exact rather than fuzzy.

What can you do with Wellfound startup job data?

  • πŸ” A startup recruiter benchmarking an offer runs a role-plus-location sweep and reads salary with job_type across company_name values to see what comparable early-stage teams are publishing, including the equity clause the compensation string preserves.
  • πŸ’Ό A job-board operator filters on isRemote and locations to populate a remote-only startup board, using URL for the outbound link and jobId to avoid re-posting a listing already in the database.
  • πŸ“ˆ A VC or platform analyst tracking portfolio hiring runs one seed per portfolio company with companyName, then counts rows per company_name and reads date to see which teams are actively scaling this month.
  • πŸ€– An AI engineer indexes description alongside job_title and company_name into a vector store so an agent can answer "which startups are hiring Rust engineers above $150k" against live listings instead of a stale export.
  • πŸ“Š A compensation researcher schedules the same location-and-role seeds weekly and builds a time series by diffing on jobId, using salary where it is populated and treating the empty string as undisclosed rather than zero.

Every one of these is callable from an agent framework over the Apify API, since the Actor is a standard HTTP-triggered run.

How does Wellfound Jobs Scraper handle rate limits and blocking?

Wellfound is protected by DataDome, and this Actor treats it as two separate problems.

Listing pages. Requests go through a stealth Firefox build (Camoufox) whose fingerprint is coherent with the container it runs in, with the browser's geo-IP matched to the proxy exit when a proxy is in use. Traffic defaults to Apify residential sticky sessions. Every page load is verified rather than assumed: a page counts as ready only when the Next.js app data is present and no DataDome markers appear in the document. If page 1 of a target does not become ready, the Actor rotates to a fresh residential session and retries, up to three attempts, escalating a datacenter tier to residential first if you configured one. It does not solve CAPTCHAs β€” there is no solver, and none is needed, because the strategy is a clean session rather than a defeated challenge.

Job-detail pages are throttled harder and cumulatively, so they are fetched strictly sequentially, never concurrently, with a 2-second floor delay that doubles after each genuine block up to 30 seconds. After three consecutive blocks the Actor stops opening job pages for the rest of the run and says so in the log β€” listing fields, including the description, keep coming from the search payload, which is unaffected.

A retry is only ever attempted before the first row of a target has been pushed, so a retry can never duplicate or re-charge a row. When a target genuinely cannot be retrieved, the Actor writes an uncharged accounting row naming the reason rather than leaving a silent gap.

⬇️ Input

Twelve parameters, none of them required. Read the empty-input behaviour above before calling this over the API.

ParameterRequiredTypeDescriptionExample Value
startUrlsNoarrayWellfound URLs to scrape β€” search/listing pages or individual job-detail pages. Takes priority over every search field below. Default [].["https://wellfound.com/location/new-york"]
locationNameNostringCity or region to search in. Builds the Wellfound search URL when no startUrls are given. Applied by Wellfound. Default "New York"."San Francisco"
includeKeywordNostringRole title, skill or technology. Combined with location into the search URL. Applied by Wellfound. Default ""."python engineer"
companyNameNostringEmployer to target. Runs a Wellfound keyword search, then keeps only cards whose company name loosely matches. Default ""."Ramp"
jobTypeNostringEmployment type: "" (any), "FULLTIME", "PARTTIME", "CONTRACTOR", "INTERN". Applied after fetch, not by Wellfound. Default ""."FULLTIME"
datePostedNostringRecency window: "all" (any time), "today", "3days", "week", "month". Applied after fetch; an unparseable posting age is rejected, not passed. Default "all"."week"
pagesToFetchNointegerListing pages to open per starting URL. Minimum 1, maximum 100. Roughly 45–60 cards per page. Pagination stops early once a page adds no new jobs. Default 1.5
fetchDescriptionsNobooleanOpen the individual job page only for the rare card whose description is missing from the search payload. Those fetches are sequential and back off. Default true.true
countryNameNostringCountry whose exit nodes the residential proxy should use. 249 values in the dropdown. Geo-targets the connection only β€” it does not filter which jobs are returned. Not applied when you supply your own proxy configuration. Default "United States"."United Kingdom"
proxyConfigurationNoobjectApify or custom proxy settings. Leaving this at its default still routes through Apify residential sticky sessions, which is what Wellfound's anti-bot requires. Default {"useApifyProxy": false}.{"useApifyProxy": false}
requestDelayNointegerSeconds to pause before each listing page load, plus jitter. Minimum 0, maximum 60 β€” but 0 is read as the 1-second default. Job-detail fetches use their own 2-second floor instead. Default 1.2
headlessNobooleanRun the stealth browser without a visible window. Turn off only when debugging locally. Default true.true

⚠️ Common pitfall: posting {} over the API. Nothing is required, so the run succeeds β€” on Wellfound's generic jobs landing page, which is not a search and does not paginate. Send locationName, includeKeyword, companyName or startUrls.

Example input

{
"startUrls": [],
"locationName": "San Francisco",
"includeKeyword": "backend engineer",
"companyName": "",
"jobType": "FULLTIME",
"datePosted": "week",
"pagesToFetch": 5,
"fetchDescriptions": true,
"countryName": "United States",
"proxyConfiguration": { "useApifyProxy": false },
"requestDelay": 2,
"headless": true
}

⬆️ Output

One row per job listing, the same 12 keys every run, pushed to the dataset as each listing is parsed so results fill while the run is still going. Missing text values arrive as an empty string, locations as [] and jobId as null β€” keys are never omitted. Export as JSON, CSV or Excel, or read the dataset through the Apify API.

Targets that could not be retrieved or parsed are written as accounting rows: rowType is "error", every job field is null, and errorReason carries a typed value β€” blocked, proxy_exhausted, missing_slug, unsupported_page_template, partial_seed, seed_error, no_ldjson, no_jobposting or detail_load_failed. These rows are never charged. Only a row whose rowType is "job" and which carries both a real title and a real URL is pushed with the row_result charged event, so an empty row cannot be billed. Filter clean results with rowType == "job".

Example output

A job row:

{
"rowType": "job",
"jobId": "3312874",
"job_title": "Senior Backend Engineer",
"company_name": "Obviant",
"location": "San Francisco, New York",
"locations": ["San Francisco", "New York"],
"isRemote": false,
"salary": "140K–185K a year β€’ 0.25% – 0.75%",
"job_type": "Full-time",
"date": "4 days ago",
"URL": "https://wellfound.com/jobs/3312874-senior-backend-engineer?utm_campaign=google_jobs_apply&utm_source=google_jobs_apply&utm_medium=organic",
"description": "We are looking for a senior backend engineer to own our ingestion platform. You will design the services that fuse thousands of structured and unstructured sources into one queryable dataset, work directly with the founders on architecture, and help shape the team as we grow past twenty people.\n\nWhat we are looking for\n- 5+ years building production services in Go, Rust or Python\n- Experience with event-driven pipelines at scale\n- Comfort with ambiguity and a bias toward shipping"
}

An uncharged accounting row from the same run:

{
"rowType": "error",
"jobId": null,
"job_title": null,
"company_name": null,
"location": null,
"locations": [],
"isRemote": null,
"salary": null,
"job_type": null,
"date": null,
"URL": "https://wellfound.com/role/l/backend-engineer/san-francisco",
"description": null,
"errorReason": "proxy_exhausted",
"errorDetail": "Blocked on every tier up to residential after 3 residential retries."
}

How does it work?

Wellfound's search and listing pages are a Next.js app, and the authoritative job data ships as JSON inside the page's __NEXT_DATA__ Apollo cache β€” JobListingSearchResult and StartupResult entities. Wellfound Jobs Scraper opens those pages in a stealth Firefox build through an Apify residential session, scrolls the lazy-loaded result list until the job count stops growing, then reads the Apollo cache directly rather than scraping rendered markup. Those JSON keys are far more stable than Wellfound's hashed CSS class names, and a DOM parser stands behind them as a fallback if the shape ever changes.

Individual job pages are a different animal: Rails-rendered, with no Apollo cache, and their machine-readable payload is a schema.org ld+json JobPosting block. Each page type is therefore checked against its own readiness signal, so a job page that loaded fine is never mistaken for an anti-bot block. Only publicly visible data is collected β€” no account, cookie or session is used. Field names and types stay identical from run to run regardless of Wellfound UI changes.

Integrations

Wellfound Jobs Scraper is an Apify Actor, so it works with anything that can call the Apify API or consume a dataset.

Calling Wellfound Jobs Scraper from Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("<YOUR_USERNAME>/wellfound-scraper").call(run_input={
"locationName": "San Francisco",
"includeKeyword": "backend engineer",
"datePosted": "week",
"pagesToFetch": 5,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
if row.get("rowType") != "job":
continue
print(row["jobId"], row["company_name"], row["job_title"], row["salary"] or "no pay published")

Works in Go, Ruby, Node.js, cURL β€” any language that can make an HTTP request. Testing rowType separates listings from the uncharged accounting rows.

Scheduled monitoring and delivery

Apify schedules run the Actor on a cron expression and fire a webhook when the run finishes. For a weekly startup-hiring digest, schedule the same seeds with datePosted set to "week", point the webhook at your endpoint to receive the dataset id, then diff the new rows against your stored set on jobId β€” a jobId you have not seen before is a genuinely new listing.

No-code tools (n8n, Make, LangChain)

In n8n, use the Apify node β€” or an HTTP Request node pointed at the Apify run endpoint with your token β€” and pass the same JSON input shown above; a Filter node on rowType drops accounting rows before the data reaches your sheet or database. In Make, the Apify module supports run-and-wait, so a scheduled sweep can feed an Airtable or Google Sheets step directly. In LangChain or any agent framework, wrap the run-and-fetch call as a tool: the rows are already typed JSON, so nothing needs parsing before they enter a prompt.

Scraping publicly accessible job postings is broadly treated as permissible where no authentication is bypassed, and Wellfound Jobs Scraper collects only what a signed-out visitor sees β€” no account, cookie or session.

What this Actor returns is business data, not personal data. Job titles, employer names, locations, employment types, compensation and equity ranges, and job descriptions are records about a company's hiring, and no field in the output identifies a recruiter, founder or hiring manager. GDPR and equivalent personal-data regimes therefore do not attach to this output the way they would to a profile scraper. The regimes that do apply are contractual and database-related: Wellfound's terms of service, and database or unfair-competition rules covering systematic reuse of a compiled dataset.

One narrow exception. description is free text written by the employer, and startup postings often name a founder or the hiring manager inside it. If you store or index description for EU or UK data subjects you may be processing incidental personal data even though no field was designed to carry it, and you need a lawful basis for it β€” typically documented legitimate interest. No other field in the output carries that exposure.

Consult legal counsel if your use case involves bulk storage of personal data, or republishing listings as a competing dataset.

❓ Frequently asked questions

What Wellfound job fields does Wellfound Jobs Scraper return?

The five most used are job_title, company_name, salary, locations and description, plus jobId as the stable key and isRemote as the remote flag. Twelve keys per job row in total β€” see the data fields table above for all of them.

Does Wellfound Jobs Scraper require a Wellfound account or login?

No. No login, no cookie, no session token, and no input field for any of them. The Actor reads Wellfound's public job surfaces anonymously, and the only credential involved is your Apify token. What it does need in practice is a residential exit IP, which it arranges itself β€” see the blocking section.

How many Wellfound jobs can I get in one run?

pagesToFetch allows up to 100 listing pages per starting URL and the number of starting URLs is not capped, so the Actor-side ceiling is your seed list times 100. The real ceiling is Wellfound's: a listing page carries roughly 45–60 cards, and pagination ends as soon as a further page adds no new jobs, because Wellfound publishes no total-page count anywhere in the payload. For wide collection, add more seeds rather than raising pagesToFetch on one.

What happens if my search returns zero jobs, or a listing is filled between runs?

An empty page 1 is indistinguishable to the Actor from a block, so it treats it as one: it rotates to a fresh residential session and retries up to three times, then writes an uncharged row with rowType of "error" and errorReason of proxy_exhausted. If you get that row for a search you believe exists, check the location or role spelling first: the Actor cannot tell an unrecognised search slug from a blocked page, because both arrive with no job cards on them.

A listing that is filled or removed between runs simply stops appearing in new results; nothing is deleted from your earlier datasets. If you hand a removed listing's URL to startUrls, the page will not yield a JobPosting block and you get an uncharged row with errorReason of no_jobposting or no_ldjson. Diff on jobId to detect disappearances between two runs.

Can I scrape multiple Wellfound searches at once?

Yes. startUrls is an array and takes priority over the search fields, so one run can mix location pages, role pages, role-plus-location pages and individual job URLs. Deduplication within a run is automatic and keyed on the canonical job URL, so overlapping seeds will not duplicate a listing.

Are salary and equity returned as numbers?

No β€” salary is a single normalized string, and any equity range lives inside it after a bullet separator rather than in a field of its own. "140K–185K a year β€’ 0.25% – 0.75%" is a typical value. It is an empty string whenever the employer published no compensation, which is common on Wellfound and means undisclosed. If you need numeric minimum and maximum values, parse the string on your side.

Does Wellfound Jobs Scraper work with Claude, ChatGPT and other AI agent tools?

Yes. It is callable as a standard HTTP endpoint through the Apify API, so LangChain, CrewAI, n8n or a hand-written tool definition can invoke it and receive typed JSON. No parsing step is needed before a row enters an LLM context window.

How does Wellfound Jobs Scraper compare to other Wellfound scrapers?

Checked on the Apify Store on 25 July 2026: orgupdate/wellfound-jobs-scraper is the most used and takes the same style of form-field input β€” keyword, location, company, job type, date posted β€” with a documented output of job_title, company_name, location, salary, date, job_type, URL and a posted_via column; a job id, a locations array and a remote boolean are not documented there. clearpath/wellfound-api-ppe is URL-first, with urls as its required input, and documents by far the deepest output: parsed base_salary numerics, equity_parsed, company size and badges, ATS source, and a monitor mode that returns only jobs new since the last run. crawlerbros/wellfound-scraper is a compact HTTP-only Actor with a short README, a maxItems cap of 500 and a remoteOnly toggle, and states in its own limitations section that the /jobs feed serves a single page of roughly 47 jobs. What this Actor documents that theirs do not: which filters Wellfound applies versus which are applied after the fetch, uncharged accounting rows with a typed reason for every skipped target, the equity clause preserved inside salary, and separate readiness handling for listing pages and job pages.

Does Wellfound Jobs Scraper return data in a format LLMs can use directly?

Yes. Every row is typed, normalized JSON with the same field names on every run, and UTF-8 mojibake is repaired before the row is written so descriptions do not arrive with Ò€ℒ where an apostrophe belongs. No HTML parsing, no selectors. Pass a row straight into an LLM, index it into a vector store, or hand it to an agent tool.

What happens when Wellfound changes its layout or anti-bot system?

The scraper is maintained, and because it reads Wellfound's embedded Apollo JSON and schema.org ld+json rather than rendered markup, a front-end restyle generally does not affect it at all β€” those JSON keys are far more stable than hashed CSS class names, and a DOM parser stands behind them as a fallback. Your field names and types stay the same either way.

Can I use Wellfound Jobs Scraper without managing proxies or browser infrastructure?

Yes. The stealth browser, the fingerprint, the residential session rotation and the retry ladder are all handled inside the Actor β€” you never install a browser, create a proxy account or rotate an IP. All you supply is your Apify token. Note that the residential traffic it uses counts toward your Apify proxy consumption.

Which Wellfound job fields work best for AI training data and RAG indexing?

For RAG indexing: description carries by far the most information per row and chunks cleanly, with job_title and company_name as metadata for filtering and citation. For training data or analysis, the most structurally consistent fields are jobId, job_type, isRemote and locations β€” a stable id, a fixed set of labels, a boolean and an array of short strings. salary and date are consistent in format but frequently empty, so treat them as optional features rather than columns you can rely on. Every value arrives as a typed primitive, an array or null, so no normalization pass is needed before indexing.

Scraper NameWhat it extracts
LinkedIn Jobs Scraper With Salary Range FiltersLinkedIn job postings with salary-range filtering and exact posting dates
LinkedIn Company URL - Mass Profile Finder With FirmographicsCompany pages and firmographics for the employers behind the listings
LinkedIn Post ScraperCompany and founder posts, useful as a hiring and launch signal
Google News Scraper By Publisher & Site FilterFunding and launch coverage for the companies you are tracking
Quora Search ScraperQuestion-intent results for role, salary and hiring research

πŸ’¬ Your feedback

Found a bug, or a Wellfound field that is not in the output? Open an issue on the Actor's Issues tab. Reports that include the exact input JSON and a Wellfound job or search URL are the fastest to reproduce and fix.