How to use it: 3 steps
- Make a free Apify accountApify is the cloud platform where our tools run. The free plan gives you $5 of usage every month, no credit card needed. You pay Apify, not us.
- Paste your input and press StartNo code needed: you fill in a form (the input). It already has a working example. For example:
{"url"…in Start URLs. Each start is one run. - Download the resultsWhen the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.
This tool is an Apify Actor: a small program that runs on Apify. You can also run it on a schedule, for example every Monday. New to it? Read how it works, step by step and the 8 words you need first.
What it does
Export public Wellfound startup jobs by role, location or job URL. Get one Dataset row per unique job, with stable IDs and the fields the source provides. Use the small prefilled search to check your first result. Filters or source access limits can leave fewer rows than your requested maximum.
- Reads public
/jobs, role, location and exact-job pages with direct HTTPS. - Builds role and location URLs from slugs, or accepts supported URLs.
- Removes duplicate numeric job IDs across pages and URLs. Keeps first-seen order and source information.
- Applies keyword, remote, employment-type and posting-age filters to fetched fields. It does not search a private API or a global database.
- Adds a public description from a bounded job-page request when needed.
- Records valid empty, partial, blocked, not-found and invalid outcomes in KVS.
Who uses it
Startup job boards
Build a public job feed and link back to Wellfound.
Market researchers
Compare startup hiring in one city or role.
Job seekers
Check remote startup roles and published pay.
Price
Pay per event: you pay for each result the tool saves, plus a small start fee for each run. The price includes Apify platform costs. Apify bills you, not us. Prices below are for the Apify free plan.
| What you pay for | Price | When |
|---|---|---|
| Wellfound job listing | $0.00025 | One validated public Wellfound job listing saved to the default Dataset. |
| Start fee | $0.0133 | Charged once per run. This tool uses 1 GB of memory or less by default; more memory costs more. |
Examples
- One job: about $0.01.
- 1,000 jobs: about $0.26.
- Every day 100 jobs, for 30 days: about $1.15 a month.
Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed. That is enough for about 18,000 jobs.
Prices checked on 24 October 2026. See the current price on Apify.
Questions
Is this the official Wellfound API?
No. It reads public pages and is not linked to Wellfound.
Do I need a Wellfound account?
No. There is no login, proxy or browser.
Will I get the full row limit I set?
Not always. Filters and source limits can give fewer rows.
Does a second run return only new jobs?
No. Each run is a fresh snapshot. Compare jobId in your own storage.
Does the keyword search all Wellfound jobs?
No. query filters the fetched title, company, role and verified description. Use role/location routes to choose the source window. remoteOnly also filters fetched rows; it does not prove global remote-job coverage.
Why can a job have no posting date or salary?
Those fields may not be published in the fetched source. Unknown values stay null. Pay is not converted across currencies or pay periods, and relative dates are not guessed as exact timestamps.
Can I fetch company pages or use a proxy?
Company routes are accepted for honest diagnostics, but the current challenge check does not prove working company coverage. Proxy transports, login and CAPTCHA solving are unavailable. No proxy subscription is needed for direct public routes.
Is a green run enough to trust the export?
Check both the Dataset and RUN_SUMMARY. PARTIAL can have useful rows; a valid EMPTY has none. A requested maximum and a source-reported total are not proof of complete coverage.
Details
Step by step on Apify
- Open Input in Apify Console. A new form suggests a small software engineer search in New York, with
maxItems: 3, one page and eight request attempts. - Leave the suggested input for your first run. Use the default 1 GB memory and 300-second platform timeout. Check the maximum cost before you start.
- Click Start. Open the Dataset and check
jobId,title,companyNameandjobUrl. Download CSV or JSON from the Dataset export menu. - Open
RUN_SUMMARYin the Key-Value Store. Checkstatus,itemsEmitted,diagnosticCodesandterminationReasonsbefore using the data.
Use cases
| Your task | Input | Useful fields and next step |
|---|---|---|
| Compare startup hiring in one place | roles and locations | Group companyName, title and locations in your exported CSV. |
| Build a public job-board feed | startUrls, bounded maxItems | Join on jobId; link to jobUrl; show missing values as unknown. |
| Check remote jobs | remoteOnly: true | Use remoteKind and acceptedRemoteLocations to see source limits. |
| Review published pay | A small role search | Keep compensationText; use parsed numbers only with their source currency and unit. |
| Verify a known listing | One exact jobUrl | Read description, postedAt and RUN_DIAGNOSTICS. A removed job is not a valid empty search. |
Tips for better results
- Use role slugs like software-engineer and location slugs like new-york.
- Company job pages can be blocked. Role and location searches work better.
- Check RUN_SUMMARY. A partial run can still have useful rows.
Limits and good to know
This tool is independent of Wellfound and AngelList. Check the current Wellfound site and the rules that apply to your use. It does not grant permission to collect or reuse data beyond your rights.
- Supported search routes are
/jobs,/role/r/<slug>,/role/l/<role>/<location>and/location/<slug>. Exact jobs use/jobs/<numeric-id>-<slug>; legacy company-prefixed exact URLs normalize to this route. Legacyangel.comust end on an allowed Wellfound route - A company route
/company/<slug>/jobscan return a login/access challenge. The current Chime check returned 403. Successful company listing coverage is not supported by that evidence. Use a public search or exact-job URL instead - Only exact
wellfound.comand legacyangel.coHTTPS hosts are accepted. Up to five allowlisted redirects are allowed. Private/service routes, credentials, arbitrary hosts and unsupported query parameters are rejected - The row cap is 1–1,000, but it is not a promise of 1,000 results. Pages stop on empty source state, repeated IDs, source page count or explicit limits. Collection counts unique candidates before local filters. A narrow filter can return fewer rows without scanning later pages
- Source work has an internal 240-second deadline. A larger platform timeout does not extend it. A shorter timeout reserves 15 seconds for output. Valid rows collected before a deadline can survive with
PARTIALdiagnostics - Default memory is 1 GB; 256–1024 MB is accepted. Lower memory can be slower. Invalid resources are recorded as
INVALID_RESOURCES, notINVALID_INPUT - Normal output is a
public_page_subset. Source totals are observations, not verified global totals. Jobs, order, page sizes and fields can change between requests. No permanent freshness or global completeness is promised
Troubleshooting
| Symptom | Check and safe action |
|---|---|
| Empty Dataset | Read RUN_SUMMARY.status. With EMPTY, check filters and fetched page limits. With FAILED, read diagnostic codes first. |
SOURCE_BLOCKED or login wall | Use an accessible public route. Do not add cookies or bypass the challenge. |
HTTP_404 | Check that the exact job still exists and that its numeric ID is correct. |
MALFORMED_STATE or DETAIL_FETCH_FAILED | The source changed or an optional detail could not be verified. Keep valid partial rows; report the run ID. |
INVALID_INPUT | Check types, bounds, slugs, URL route and mode. Keep one small known public input. |
INVALID_RESOURCES | Use supported memory and enough timeout for output; input fields are not the cause. |
| Fewer rows than requested | Check maxItems, page/request stops, local filters and unverifiable. Increasing a limit cannot remove a source access restriction. |
| Missing pay, remote or description | Treat null as unknown. Check the raw source text and description setting; values are not inferred. |
Recent updates
Update
- Closed the post-Publish release on public
latest0.1.18after a bounded default canary reconciled Dataset, KVS,Run.outputand 47 charge events; the annotated source tag isv0.1.18. - Fixed the public
/jobsparser to retain structuredJobListingand referenced startup/remote fields instead of degrading rows to links. - Enabled bounded exact-job enrichment by default for missing inline descriptions;
includeDescription=falseremains available for link-first output.
- Closed the post-Publish release on public
Version 0.1.0
- Added limited public HTTPS extraction with Apollo/SSR and JSON-LD parsing, stable IDs, dedupe, filters and diagnostics.
- Added a limited /jobs default for empty auto/search input and its regression coverage.
- Added procps to the slim runtime image so Apify memory metrics work without container snapshot errors.
Update · 9 October 2026
- Bound source work to 240 seconds independently of platform timeout, with output reserve and explicit resource diagnostics.
- Keep extracted rows on cancellation; propagate failed product outcomes through the production exit code.
- Keep HTTP deadlines active through response-body reads and handle cancellation during pacing.
For developers
Sample result
One result from a real test run, in JSON. Real values change from run to run. In Excel or CSV each field is a column.
{
"recordType": "JOB_LISTING",
"id": "wellfound:4787364",
"jobId": "4787364",
"title": "Software Engineer",
"jobUrl": "https://wellfound.com/jobs/4787364-software-engineer",
"companyName": "Chalk",
"jobType": "full-time",
"locations": ["New York City", "San Francisco"],
"remote": false,
"compensationText": "$170k – $250k",
"salaryMin": 170000,
"salaryMax": 250000,
"salaryCurrency": "USD",
"postedAt": "2026-09-30T23:42:54.000Z",
"description": "**About Chalk**",
"descriptionFormat": "markdown",
"sourceUrl": "https://wellfound.com/role/l/software-engineer/new-york",
"sourceMode": "search",
"sourcePage": 1,
"observedAt": "2026-10-09T14:49:16.673Z",
"coverage": "public_page_subset"
}Use it from code
Actor ID: cliqtomedia/wellfound-jobs-scraper. You need your Apify API token from Apify Console → Settings → API & Integrations.
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cliqtomedia/wellfound-jobs-scraper").call(run_input={
"mode": "auto",
"startUrls": [
{
"url": "https://wellfound.com/role/l/software-engineer/new-york"
}
]
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)curl -X POST "https://api.apify.com/v2/acts/cliqtomedia~wellfound-jobs-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"mode": "auto", "startUrls": [{"url": "https://wellfound.com/role/l/software-engineer/new-york"}]}'# pip install langchain-apify
# set APIFY_TOKEN in your environment
from langchain_apify import ApifyActorsTool
tool = ApifyActorsTool("cliqtomedia/wellfound-jobs-scraper")
result = tool.invoke({"run_input": {"mode": "auto", "startUrls": [{"url": "https://wellfound.com/role/l/software-engineer/new-york"}]}})
print(result)The cURL call waits for the results, up to 300 seconds. For longer runs, start a run (/runs) and get the results with a webhook or by checking the run. Apify API docs. LlamaIndex, MCP for AI agents and the JavaScript client: AI agents & MCP.
Data fields (37)
| Field | Type |
|---|---|
recordType | string |
id | string |
jobId | string |
title | string |
slug | string |
jobUrl | string |
companyId | string |
companyName | string |
companySlug | string |
companyUrl | string |
primaryRole | string |
jobType | string |
locations | array |
acceptedRemoteLocations | array |
remote | boolean |
remoteKind | string |
wfhFlexible | boolean |
compensationText | string |
salaryMin | number |
salaryMax | number |
salaryCurrency | string |
equityMinPercent | number |
equityMaxPercent | number |
compensationParseStatus | string |
experienceMinYears | number |
experienceMaxYears | number |
postedAt | string |
postedAtSource | string |
description | string |
descriptionFormat | string |
atsSource | string |
badges | array |
sourceUrl | string |
sourceMode | string |
sourcePage | number |
observedAt | string |
coverage | string |
Input settings (16)
The main fields of the input form. With the API you send them as JSON.
| Setting | Name in the API | Type | Example value |
|---|---|---|---|
| Mode | mode | string | "auto" |
| Start URLs | startUrls | array | [{"url": "https://wellfound.com/role/l/software-engineer/new-york"}] |
| Roles | roles | array | |
| Locations | locations | array | |
| Remote only | remoteOnly | boolean | false |
| Keyword | query | string | "" |
| Employment type | jobType | string | "any" |
| Posted within days | postedWithinDays | integer | |
| Include descriptions | includeDescription | boolean | true |
| Maximum items | maxItems | integer | 3 |
| Maximum pages per URL | maxPagesPerSeed | integer | 1 |
| Maximum request attempts | maxRequests | integer | 8 |
| Request timeout seconds | requestTimeoutSecs | integer | 20 |
| Request delay milliseconds | requestDelayMs | integer | 750 |
| Transient retries | maxRetries | integer | 2 |
| Transport | transport | string | "AUTO" |
Use cases with this tool
Each guide shows all the steps and the other tools.