Wellfound Jobs Scraper: Startup Jobs to CSV & JSON avatar

Wellfound Jobs Scraper: Startup Jobs to CSV & JSON

Pricing

from $0.18 / 1,000 wellfound job listings

Go to Apify Store
Wellfound Jobs Scraper: Startup Jobs to CSV & JSON

Wellfound Jobs Scraper: Startup Jobs to CSV & JSON

Export public Wellfound startup jobs by role, location or job URL. Get stable job IDs, source salary text, descriptions and CSV or JSON output with explicit coverage limits.

Pricing

from $0.18 / 1,000 wellfound job listings

Rating

0.0

(0)

Developer

Cliqto Media

Cliqto Media

Maintained by Community

Actor stats

0

Bookmarked

4

Total users

0

Monthly active users

8 days ago

Last modified

Features

Limited permissions

Share

Export public Wellfound startup jobs by role, location or job URL. Get one Dataset row per unique job, with stable IDs, salary text, posting date and description, ready for CSV, JSON or your job board.

Wellfound Jobs Scraper: role and location search, stable job IDs, and CSV or JSON export

What it does

The Actor reads public Wellfound job search pages and job pages and saves each startup job as one clean row: title, company, locations, remote flag, employment type, published pay, posting date, description and job URL. It reads only what Wellfound shows without a login. It is not a full index of every Wellfound job.

Good fit

  • Track startup hiring for one role in one city, for example software engineers in New York.
  • Feed a job board or newsletter with fresh startup jobs and their links.
  • Compare published salary ranges for a role across startups.

👉 Try it now: open the input form

How it works

  1. You give a Wellfound search URL, or a role and a location, or one job URL.
  2. The Actor opens the public pages, removes duplicate jobs and applies your keyword, remote, job type and posting-age filters.
  3. It saves one row per job to the Dataset and a short run report (RUN_SUMMARY) with the status and any problems.

👉 Try it now: open the input form

Quick start

Input form: box 1 is the Wellfound search URL, box 2 the small limits, box 3 the Start button

  1. Open the Input tab. The form already has a Wellfound search URL for software engineers in New York (box 1 in the picture).

  2. Keep the small limits for your first run: Maximum items 3, Maximum pages per URL 1, Maximum request attempts 8 (box 2).

  3. Click Start (box 3).

  4. Open the Output tab. Check Job title and Company (box 1), Compensation, Posted and Job URL (box 2). Click Export (box 3) to download CSV, JSON or Excel.

    Output table: job title, company, pay, posting date and job URL for three New York software jobs

Expected result: three software engineering jobs in New York with company, pay range, posting date and link, in about 5 seconds. Jobs on Wellfound change, so your rows will differ.

The form values are a prefill, not API defaults. An API input {} reads the public /jobs feed with maxItems: 50, three pages and descriptions on.

👉 Try it now: open the input form

Use cases

Buyer jobInput pathOutput entityKey fieldsNext integration
Startup hiring in one cityroles + locationsjob rowcompanyName, title, locationsCSV export to a spreadsheet
Job board or newsletter feedstartUrls, maxItemsjob rowjobId, title, jobUrl, postedAtDataset API, scheduled task
Remote startup jobsremoteOnly: truejob rowremote, remoteKind, acceptedRemoteLocationsCSV or JSON export
Salary researchsmall role searchjob rowcompensationText, salaryMin, salaryMax, salaryCurrencyspreadsheet pivot
Check one known jobone job URL, mode: exact_jobjob rowdescription, postedAt, jobUrlRUN_SUMMARY status

👉 Try it now: open the input form

Input

No field is required. Roles and locations are Wellfound URL slugs (lowercase letters, numbers and hyphens, for example software-engineer, new-york), not free text. Invalid limits, types or slugs stop the run with INVALID_INPUT before any page is read. In a mixed list, a bad URL is reported and the valid URLs still return rows.

Input fields

FieldPlain nameTypeDefault / prefillAllowed valuesEffect
modeModestringautoauto, search, exact_job, company_jobsauto detects each URL; other modes require a matching URL.
startUrlsStart URLsarray of {url}[]; prefill: New York searchHTTPS URLs on wellfound.com or legacy angel.coPages to read. Empty and no role/location means the public /jobs feed.
rolesRolesstring[]noneup to 5 slugsAdds /role/r/<role> pages, or every role × location pair.
locationsLocationsstring[]noneup to 5 slugsAdds /location/<slug> pages, or every role × location pair.
remoteOnlyRemote onlybooleanfalseKeeps only jobs the source marks remote; unknown is excluded.
queryKeywordstring""Keyword match in fetched title, company, role and description. Not a site-wide search.
jobTypeEmployment typestringanyany, full-time, part-time, contract, internship, cofounderFilters fetched jobs; unknown type does not match.
postedWithinDaysPosted within daysintegernone0–3650Keeps jobs posted in the last N days; unknown dates do not match.
includeDescriptionInclude descriptionsbooleantrueOpens one job page per row when the search page has no description.
maxItemsMaximum itemsinteger50; prefill 31–1000Rows for the whole run.
maxPagesPerSeedMaximum pages per URLinteger3; prefill 11–50Search pages per URL.
maxRequestsMaximum request attemptsinteger200; prefill 81–1500All page requests, including retries and descriptions.
requestTimeoutSecsRequest timeout secondsinteger205–60Time for one page.
requestDelayMsRequest delay millisecondsinteger750500–10000Pause between requests, plus up to 25% jitter.
maxRetriesTransient retriesinteger20–2Retries for timeouts, 429 and some 5xx. Never for 401/403/404.
transportTransportstringAUTOAUTO, DIRECTBoth read pages directly over HTTPS.
deliveryConnectorSend results to (optional)MCP connectornoneyour Slack or Notion connectorSends a short run summary after the data is saved.
deliveryTargetNotion page or channel (optional)stringnoneNotion page link or Slack channel IDWhere the summary goes.

Interacting settings

WhenInput AInput BEffective behavior
Both URLs and slugsstartUrlsroles / locationsCombined and deduplicated, at most 25 unique pages to start from.
Roles and locationsroleslocationsEvery role × location pair becomes one search page.
Filtersquery, remoteOnly, jobType, postedWithinDaysmaxItemsCollection stops at maxItems unique jobs before filters, so a narrow filter can return fewer rows.

Input examples

Remote software jobs in New York

{
"roles": ["software-engineer"],
"locations": ["new-york"],
"remoteOnly": true,
"maxItems": 20,
"maxPagesPerSeed": 1,
"maxRequests": 8
}

Expected output: up to 20 job rows with remote: true.

Check one job

{
"mode": "exact_job",
"startUrls": [
{ "url": "https://wellfound.com/jobs/3628014-software-engineer" }
],
"maxItems": 1,
"maxRequests": 3
}

Copy a fresh jobUrl from a search run: a job can close after you copy it.

👉 Try it now: open the input form

Output

The Dataset has job rows only, no error or billing rows. Every field is always present: unknown text and numbers are null, unknown lists are []. Nothing is guessed: no salary, date or remote flag is filled in when the source does not show it.

Output fields

FieldMeaningTypeCan be empty?
recordTypealways JOB_LISTINGstringno
idwellfound:<jobId>stringno
jobIdWellfound numeric job ID, as textstringno
titlejob titlestringno
slugjob slug from the URLstringyes
jobUrlhttps://wellfound.com/jobs/<id>-<slug>URLno
companyId, companyName, companySlug, companyUrlpublic employer detailsstring / URLyes
primaryRolerole label shown by the sourcestringyes
jobTypefull-time, part-time, contract, internship, cofounderstringyes
locationslisted work locationsstring[]empty list if none
acceptedRemoteLocationsregions the job hires remotely fromstring[]empty list if none
remotesource marks the job remotebooleanyes
remoteKindREMOTE, ONSITE_OR_REMOTE, ONSITEstringyes
wfhFlexiblesource work-from-home flagbooleanyes
compensationTextpay as published, for example $176k – $204kstringyes
salaryMin, salaryMaxparsed pay range, only when clearnumberyes
salaryCurrencyUSD, EUR, GBP or source code; never convertedstringyes
equityMinPercent, equityMaxPercentequity range in percentnumberyes
compensationParseStatusnot_present, parsed, partial, ambiguousstringno
experienceMinYears, experienceMaxYearsrequired experiencenumberyes
postedAtposting time, ISOstringyes
postedAtSourceliveStartAt, jsonld, source_text, absentstringno
descriptionpublic job descriptionstringyes
descriptionFormatmarkdown, html_text, absentstringno
atsSourcepublic applicant-tracking label; not openedstringyes
badgespublic company and job labelsstring[]empty list if none
sourceUrl, sourceMode, sourcePagepage that produced the rowmixedsourcePage yes
observedAttime the row was read, UTCstringno
coveragealways public_page_subsetstringno

Pay keeps the source scale and period: it is not turned into a yearly amount or converted between currencies. Equity is in percent, not a fraction.

Output entities and surfaces

SituationWhereWhat you seeWhat to do
Normal runDataset, RUN_SUMMARYjob rows; status: SUCCEEDEDexport CSV or JSON
No matching jobsRUN_SUMMARYempty Dataset; status: EMPTYloosen filters or pick another role/location
Some pages failedDataset, RUN_DIAGNOSTICSrows kept; status: PARTIALread the diagnostic codes
Blocked or invalidRUN_SUMMARY, RUN_DIAGNOSTICSstatus: FAILED, run exits with an errorsee Troubleshooting

RUN_PROGRESS shows the current page and counters while the run is going. A green platform status is not enough: check RUN_SUMMARY.status.

Output example

One row from the Quick start run on 3 November 2026, description shortened:

{
"recordType": "JOB_LISTING",
"id": "wellfound:3628014",
"jobId": "3628014",
"title": "Software Engineer",
"jobUrl": "https://wellfound.com/jobs/3628014-software-engineer",
"companyName": "January",
"jobType": "full-time",
"locations": ["New York"],
"remote": false,
"compensationText": "$176k – $204k",
"salaryMin": 176000,
"salaryMax": 204000,
"salaryCurrency": "USD",
"postedAt": "2026-10-19T16:30:33.000Z",
"descriptionFormat": "markdown",
"sourceMode": "search",
"coverage": "public_page_subset"
}

Send results to Slack or Notion

Pick your connector in the optional deliveryConnector field. After the run saves its data, the Actor posts a short summary (up to 25 rows and a link to the full dataset) there. Put a Notion page link or a Slack channel ID in deliveryTarget: in Notion every run is added on top of that one page, so your workspace does not fill up with new pages. A delivery error never fails the run and costs nothing extra. Connect a service once in Apify Console → MCP connectors. The result is in RUN_SUMMARY.delivery.

👉 Try it now: open the input form

Pricing

You pay per result. Platform usage is included in the price.

EventFreeBronzeSilverGold+
Job listing saved to the Dataset, per 1,000$0.25$0.225$0.20$0.175
Actor start, per GB of memory$0.0133$0.0133$0.0133$0.0133
  • The start fee is charged once per started GB of run memory, at least once. The default 256 MB run pays it once.
  • Example: 100 jobs on the Free plan with default memory cost about $0.0133 + 100 × $0.00025 = $0.038.
  • Empty, filtered, duplicate and failed results have no row fee. A run that saves nothing pays only the start fee.
  • Set Maximum cost per run in Run options to cap what one run can spend.

👉 Try it now: open the input form

Limits

  • Supported pages: /jobs, /role/r/<role>, /role/l/<role>/<location>, /location/<slug> and job pages /jobs/<id>-<slug>. Only wellfound.com and legacy angel.co HTTPS URLs; up to 5 redirects inside Wellfound.
  • Company job pages (/company/<slug>/jobs) often return a login wall (HTTP 403). They are accepted and reported, but company coverage is not promised. Use a search or job URL instead.
  • Up to 1,000 rows and 25 start pages per run. This is a cap, not a promise: pages stop when the source runs out, repeats jobs or hits your limits.
  • One search URL gave about 49 unique jobs in our tests; later pages repeated the same jobs. For more jobs, add several role or location URLs.
  • By our estimate one run makes about 200–250 page requests in 240 seconds at the default delay. A job whose search card has no description takes one more request, so several URLs together give up to about 200 jobs with descriptions per run (an estimate, not a tested maximum).
  • Source work stops after 240 seconds even with a longer run timeout; rows found before that are kept with PARTIAL. The run needs more than 15 seconds left to start.
  • maxRequests accepts up to 1,500 (default 200), but the 240-second limit usually stops a run first.
  • Busy or failing pages (HTTP 429 and 5xx) are retried a few times with a pause.
  • One page may be up to 8 MB; larger pages are skipped with BODY_TOO_LARGE.
  • Memory 256–512 MB, default 256 MB. The Actor uses about 120 MB, so 512 MB does not make it faster; it only doubles the platform cost of the run.
  • Results are a sample of public pages (coverage: public_page_subset), not every Wellfound job. Jobs, order and fields can change between runs.
  • No login, cookies, proxy, browser or CAPTCHA solving.
  • Each run is a fresh snapshot: there is no "only new jobs" mode. Compare jobId in your own storage.

This tool is independent of Wellfound and AngelList. Use the data in line with the Wellfound terms and the rules that apply to you.

👉 Try it now: open the input form

API, export and integrations

  • API: start a run with the same JSON input as the form. A small run:

    curl --request POST \
    'https://api.apify.com/v2/acts/cliqtomedia~wellfound-jobs-scraper/runs?memory=256&timeout=300&maxTotalChargeUsd=0.05' \
    --header "Authorization: Bearer $APIFY_TOKEN" \
    --header 'Content-Type: application/json' \
    --data '{"roles":["software-engineer"],"locations":["new-york"],"maxItems":3,"maxPagesPerSeed":1,"maxRequests":8}'

    Then read the run's default Dataset. See the Run API.

  • Export: the Dataset Export button gives CSV, JSON, Excel and other formats.

  • Scheduling: save your input as a task and add a schedule in Apify Console. Use jobId to compare snapshots.

  • Slack or Notion: see Send results to Slack or Notion.

Use with AI agents (MCP)

  • MCP server with only this Actor: https://mcp.apify.com?tools=cliqtomedia/wellfound-jobs-scraper.
  • Smallest useful input: {"startUrls":[{"url":"https://wellfound.com/role/l/software-engineer/new-york"}],"maxItems":3,"maxPagesPerSeed":1,"maxRequests":8}.
  • Key output fields: title (job title), companyName (employer), compensationText (pay as published), postedAt (posting time), jobUrl (link to apply).
  • The Quick start input takes about 5 seconds and costs about $0.014 on the Free plan. Keep maxItems small; one run returns at most 1,000 rows.

👉 Try it now: open the input form

Troubleshooting

RUN_SUMMARY.status tells how the run ended:

  • SUCCEEDED: all pages were read.
  • PARTIAL: rows are saved, but something was skipped, for example one job description could not be read (DETAIL_FETCH_FAILED) or the time or request limit was reached. The saved rows are valid.
  • EMPTY: the pages worked but no job matched. Loosen filters.
  • FAILED: nothing could be read. Check the codes below.
Code or symptomWhat it means and what to do
SOURCE_BLOCKED or login wallWellfound refused the page. Use a public search or job URL. Do not add cookies.
SOURCE_EMPTYThe page had no jobs. Try a wider role or location.
HTTP_404The job was closed or the ID is wrong. Copy a fresh jobUrl.
HTTP_ERRORWellfound returned an error after retries. Try again later.
TIMEOUTA page or the 240-second source limit ran out. Lower maxItems or pages.
REQUEST_BUDGET_EXHAUSTEDmaxRequests was used up. Raise it or narrow the search.
BODY_TOO_LARGEA page was over 8 MB and was skipped.
REDIRECT_OUTSIDE_ALLOWLIST or REDIRECT_LIMITA link left Wellfound or redirected more than 5 times. Use a direct Wellfound URL.
MALFORMED_STATE or MISSING_STABLE_IDThe page layout changed or a job had no ID. Valid rows are kept; report the run ID.
DETAIL_FETCH_FAILEDOne job description could not be read. The row is saved without it.
DUPLICATE or FILTEREDRepeated or filtered jobs were skipped. They are not charged.
INVALID_INPUTCheck slugs, limits, URL and mode. Start from the Quick start input.
INVALID_RESOURCESUse 256–512 MB memory and leave more than 15 seconds of run time.
TRANSPORT_UNAVAILABLE or INTERNAL_ERRORA temporary run problem. Start again; if it repeats, report the run ID.
CHARGE_LIMIT_REACHEDYour maximum cost per run was reached. Raise it or lower maxItems.
Fewer rows than maxItemsFilters, page limits and source end can stop early. A larger limit cannot remove a login wall.
Missing pay, remote or descriptionnull means the source did not show it.

👉 Try it now: open the input form

FAQ

Do I need a Wellfound account or a proxy?

No. The Actor reads public pages without login and without a proxy.

Does the keyword search all Wellfound jobs?

No. query filters the jobs read from your search pages. Choose the role and location to set the search window.

Why do some jobs have no salary or date?

The source did not show them. Unknown values stay null; nothing is guessed.

Will a repeat run return only new jobs?

No. Each run is a new snapshot and each saved row is charged again. Compare jobId in your own storage.

Is this an official Wellfound API?

No. It is an independent tool that reads public pages.

👉 Try it now: open the input form

👉 Try it now: open the input form

Support

For a bug, question or feature request, open the Issues tab of this Actor on Apify. Include the run ID, product status and diagnostic code. Never post tokens, cookies or private data.

👉 Try it now: open the input form