# Y Combinator Jobs Scraper: Salary, Equity, Founders (`mochiboo/yc-startup-jobs-scraper`) Actor

Every open Y Combinator startup job in one run: salary and equity parsed into numbers, visa, remote flag, full description, plus company batch, team size, website and founders' public LinkedIn profiles. Filter by role, location, salary or batch. No proxy, no login, no emails.

- **URL**: https://apify.com/mochiboo/yc-startup-jobs-scraper.md
- **Developed by:** [mochi](https://apify.com/mochiboo) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Y Combinator Jobs Scraper: Salary, Equity, Founders

**Every open Y Combinator startup job, with salary, equity, visa and company/founder context, in one run.**

Pulls the jobs YC companies list on ycombinator.com (the "Work at a Startup" postings): one row per job, with the salary and
equity parsed into numbers, the full job description, and who runs the company. No login, no proxy, no emails.

- **All of them, not capped at 200.** A full export on 2026-10-17 returned 6,351 jobs at about 1,400 companies (see "How many
  jobs there are"). Filter by role, title keyword, location, remote, visa, job type, minimum salary, YC batch, or give a list of
  companies.
- **Salary and equity as numbers.** Min, max, currency and period (year, month or hour) are parsed out of the employer's own
  text, which is kept next to them.
- **Company context on every row.** Batch, status, team size, year founded, HQ, website, LinkedIn, Twitter, GitHub,
  Crunchbase, tags, and the founders' names, titles and public LinkedIn / Twitter profile links.

### Example input

```json
{
  "roles": ["eng"],
  "remoteOnly": true,
  "minSalaryUsd": 200000,
  "batches": ["W24", "S24", "W25"],
  "maxResults": 100
}
```

### Input

| field | what it does | default |
|---|---|---|
| `roles` | Engineering, Design, Product, Science, Sales, Marketing, Support, Operations, Recruiting & HR, Finance, Legal. Empty = all | all |
| `keywords` | Keep jobs whose title contains any of these words (case-insensitive) | all |
| `locationContains` | Case-insensitive text match on the location, e.g. `San Francisco`, `London` | all |
| `remoteOnly` | Only locations that say "remote" | off |
| `visa` | `Will sponsor`, `US citizenship/visa not required`, `US citizen/visa only` | any |
| `jobType` | `Full-time`, `Contract`, `Internship` or `Co-founder` | any |
| `minSalaryUsd` | Keep jobs whose USD **yearly** salary maximum is at least this. Jobs without a USD yearly salary are skipped when set | not set |
| `onlyWithSalary` | Only jobs that publish a salary range | off |
| `batches` | Short YC batch codes, e.g. `W26`, `S25`, `F24` | all |
| `companySlugs` | Only these companies, as in `ycombinator.com/companies/<slug>`, e.g. `whatnot`, `kombo` | every hiring YC company |
| `includeDescription` | Open each job page for the full description (one extra request per job, included in the price) | on |
| `maxResults` | Number of jobs to return, 1 to 10,000 | 200 |

### Output

One row per job, 41 fields:

- **Job:** `jobId`, `title`, `jobUrl`, `location`, `isRemote`, `jobType`, `role`, `roleLabel`, `roleSpecialty`, `minExperience`,
  `visa`, `skills`, `postedAgo`, `description`
- **Pay:** `salaryRaw`, `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`, `equityRaw`, `equityMinPct`, `equityMaxPct`
- **Company:** `companyName`, `companySlug`, `companyUrl`, `companyOneLiner`, `batch`, `batchName`, `companyStatus`, `teamSize`,
  `yearFounded`, `companyLocation`, `companyCountry`, `companyWebsite`, `companyLinkedin`, `companyTwitter`, `companyGithub`,
  `companyCrunchbase`, `companyTags`
- **Founders:** `founders`, a list of `{name, title, linkedinUrl, twitterUrl}`
- `scrapedAt`

```json
{
  "jobId": 110272,
  "title": "Android Engineer",
  "jobUrl": "https://www.ycombinator.com/companies/whatnot/jobs/TYkux4y-android-engineer",
  "location": "Remote (US)",
  "isRemote": true,
  "jobType": "Full-time",
  "role": "eng",
  "roleLabel": "Engineering",
  "visa": "US citizen/visa only",
  "salaryRaw": "$170K - $290K",
  "salaryMin": 170000,
  "salaryMax": 290000,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "equityRaw": null,
  "postedAgo": "about 1 month",
  "companyName": "Whatnot",
  "batch": "W20",
  "teamSize": 1500,
  "companyWebsite": "https://www.whatnot.com/careers/discover",
  "founders": [
    {"name": "Grant LaFontaine", "title": "Founder/CEO", "linkedinUrl": "https://www.linkedin.com/in/grantlafontaine/", "twitterUrl": null}
  ],
  "description": "## **🚀 Join the Future of Commerce with Whatnot!** ..."
}
```

(Shortened. Every row carries all 41 fields.)

### How the numbers are read

- **Salary text is the employer's own.** It is parsed literally and never "fixed": a posting that says `$240 - $300` is read as
  240 to 300 dollars a year, because that is what it says. `K` and `M` suffixes are expanded (`$170K` is 170000). A text with
  `/ hourly` is `hour`, `/ monthly` is `month`, anything else is `year`. Currency comes from the symbol or code
  (`EUR`/`€`, `GBP`/`£`, `INR`/`₹`, `CAD`, otherwise `$` is USD). The original text is always in `salaryRaw`.
- **Equity** is read from percentages in the text (`0.25% - 1.00%` is 0.25 to 1.0). About 29% of postings publish an equity range
  (1,858 of 6,351 in a full export on 2026-10-17).
- **`postedAgo`** is YC's own relative text ("about 1 month"), not a date.
- **`minSalaryUsd`** compares against the salary maximum, and only for salaries in USD per year.

### People and contact data

Founders are listed with their name, title and public LinkedIn / Twitter links only. The actor does not output email addresses,
phone numbers, hiring managers or founder bios. Email addresses and phone numbers that appear inside job descriptions are
replaced with `[email redacted]` and `[phone redacted]`. That includes addresses written out to dodge scrapers (`name at company
dot com`, `name (at) company.com`, `name @ company.com`, `name\[at\]company.com`) and addresses percent-encoded inside a link
(`?email=name%40company.com`). Links themselves are left intact. This is best effort: an address in an unusual form can slip
through. A company domain mentioned in a description, such as `@acme.com`, is not an email address and is left as written.

### How many jobs there are

A full export on 2026-10-17 returned 6,351 jobs at about 1,400 companies. YC's job sitemap lists more job URLs (7,135 that day)
than there are open jobs: 79 of them belong to 41 companies whose page no longer exists, and 705 belong to 299 companies whose
page loads but lists no jobs. In a sample of those URLs almost all were dead links; at least one company has live job pages that
its company page does not list, and the actor does not return those. The actor returns the jobs the company pages list.

### What a run looks like

A full export on 2026-10-17 (no filters, descriptions on) returned 6,351 jobs at 1,407 companies. Share of those jobs with each
field filled: title, link, company name, location, visa and description 100%; batch 99.8%; a salary range 79.7% (66.2% in USD per
year); an equity range 29.3%; team size 98.3%; year founded 94.3%; company LinkedIn 95.3%, Twitter 67.9%, Crunchbase 40.2%, GitHub
29.2%; at least one founder 99.6%. Reading one company without descriptions (`companySlugs: ["whatnot"]`, `includeDescription:
false`) returned all 149 of its open jobs in 9 seconds.

### Large exports

A full export of every open job with descriptions makes one request per company plus one per job, so it takes a long time. A very
large run may stop early: the actor stops starting new requests shortly before the run timeout, keeps every row already
delivered, and saves a `RUN_SUMMARY` record in the key-value store: `{ "complete": true | false, "terminationReason": ..., "rowsPushed": ... }`.
`terminationReason` is one of `finished`, `max_results`, `charge_limit`, `time_budget` or `blocked`. If `complete` is `false`,
split the export with `batches` or `roles` and run the parts separately. `complete` is also `false` if a company page could not be
read after retries. In a test with a deliberately short 60 second timeout, the actor stopped starting new requests at 45 seconds,
delivered the 447 jobs it had, and finished normally with `terminationReason: "time_budget"`.

If ycombinator.com refuses the requests (a 403, a challenge page, or a page that is not the expected one) the actor stops, keeps
the rows already delivered and fails with the reason. It does not retry around a block and does not use proxies.

### Price

Pay per result, at the rate shown in the pricing panel of this page, plus a very small per-run start fee. You are charged only for the results delivered.

### Notes

- Data comes from public pages on ycombinator.com. A few companies in the sitemap no longer have a page; they are skipped.
- A job that is listed on a company page but whose job page cannot be opened is still returned, with `description: null`.

**Keywords:** y combinator jobs, yc jobs, work at a startup, startup jobs, ycombinator scraper, yc companies, startup salary data,
equity, visa sponsorship jobs, founders linkedin, hiring startups.

# Actor input Schema

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

Leave empty for all roles.

## `keywords` (type: `array`):

Keep jobs whose title contains any of these words (case-insensitive). Leave empty for all.

## `locationContains` (type: `string`):

Case-insensitive text match on the job location, e.g. "San Francisco", "New York", "London".

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

Keep only jobs whose location says remote.

## `visa` (type: `string`):

Filter on the visa line YC shows for the job. Any = no filter.

## `jobType` (type: `string`):

Job type as YC lists it. Any = no filter.

## `minSalaryUsd` (type: `integer`):

Keeps only jobs with a USD yearly salary whose maximum is at least this. Jobs without a USD yearly salary are skipped when set.

## `onlyWithSalary` (type: `boolean`):

Keep only jobs that publish a salary range.

## `batches` (type: `array`):

Short batch codes, e.g. W26, S25, F24. Leave empty for all.

## `companySlugs` (type: `array`):

YC company slugs as in ycombinator.com/companies/<slug>, e.g. whatnot, kombo. Leave empty to scan every hiring YC company.

## `includeDescription` (type: `boolean`):

Opens each job page (one extra request per job). Included in the price.

## `maxResults` (type: `integer`):

Maximum number of jobs to return, 1 to 10,000.

## Actor input object example

```json
{
  "roles": [],
  "keywords": [],
  "locationContains": "",
  "remoteOnly": false,
  "visa": "any",
  "jobType": "any",
  "onlyWithSalary": false,
  "batches": [],
  "companySlugs": [],
  "includeDescription": true,
  "maxResults": 200
}
```

# Actor output Schema

## `results` (type: `string`):

One row per open job: salary and equity as numbers, visa, remote flag, full description, plus the company's batch, team size, website and founders' public LinkedIn profiles.

## `runSummary` (type: `string`):

What the run wrote and how it ended (the RUN_SUMMARY record in the default key-value store).

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("mochiboo/yc-startup-jobs-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

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

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

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

```

## CLI example

```bash
echo '{}' |
apify call mochiboo/yc-startup-jobs-scraper --silent --output-dataset

```

## MCP server setup

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

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Ab9vlweXxGvLLsaIb/builds/pBa0LqGv2ikRpbjdA/openapi.json
