# Y Combinator Jobs Scraper 🚀 (YC startup jobs, salary, equity) (`tagadanar/yc-jobs-scraper`) Actor

Every open job on Y Combinator's Work at a Startup board as flat rows: salary and equity ranges as numbers, visa, experience, role, remote flag, plus company batch, team size, industry and website. Filter by role, title, location or salary. Only-new mode. $1.25 per 1,000 jobs. No login.

- **URL**: https://apify.com/tagadanar/yc-jobs-scraper.md
- **Developed by:** [Tagada Data](https://apify.com/tagadanar) (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.88 / 1,000 jobs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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: every YC startup job with salary, equity and visa

Get every open job on Y Combinator's **Work at a Startup** board as clean rows: title, role, location and remote flag, salary range as numbers (with currency and pay period), equity range in percent, visa line, minimum experience, posting age, plus the company's YC batch, team size, industries, website and LinkedIn page. Filter by role, job title words, location, job type, visa, salary, experience, posting date or YC batch, or list the companies you care about.

Run it daily in **only-new mode** and you get a feed of YC jobs you have not seen before.

$1.25 per 1,000 jobs (Free plan; less on paid plans), platform usage included. Full descriptions cost nothing extra. No login.

### Why this one

The role pages on ycombinator.com/jobs show at most 39 postings each (5 of the 20 open legal jobs on 2026-10-25). This actor reads YC's own jobs sitemap and then every hiring company's job list, so a run can return the whole board: 6,416 open jobs at about 1,700 companies on 2026-10-25.

What you get that the board pages don't give you:

- the whole board, or only the companies you list;
- salary and equity as numbers (`salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`, `equityMinPercent`, `equityMaxPercent`), ready to sort and filter;
- company facts on every row: YC batch, team size, industries, website, LinkedIn, location and status;
- filters for role, title words, location, remote, job type, visa, minimum USD salary, experience, posting date and YC batch;
- an only-new monitor mode where a quiet day costs only the run start.

### What you get

One row per job:

| Field | Description |
| --- | --- |
| `jobId`, `title`, `jobUrl`, `applyUrl` | The job's YC ID, its title, the public job page and YC's apply link (applying needs a free Work at a Startup account) |
| `role`, `roleCode`, `roleSubtype` | `Engineering` / `eng`, and the sub-type when the company set one (`Full stack`, `Backend`, `Machine learning`...) |
| `jobType` | `Full-time`, `Internship`, `Contract` or `Co-founder` |
| `location`, `locations`, `isRemote` | The location as shown, split into a list (`San Francisco, CA, US` and `Remote (US)`), and a remote flag |
| `salaryRange`, `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | `$150K - $250K` becomes 150000, 250000, `USD`, `year`. Hourly and monthly pay keep their period (`hour`, `month`). Null when the company shows no salary |
| `equityRange`, `equityMinPercent`, `equityMaxPercent` | `0.30% - 0.70%` becomes 0.3 and 0.7 |
| `experience`, `minExperienceYears` | `5+ years` becomes 5; `Any (new grads ok)` becomes 0 |
| `visa` | YC's visa line: `US citizen/visa only`, `US citizenship/visa not required` or `Will sponsor` |
| `skills` | Skill tags, when the company added them |
| `postedAgo`, `postedDateApprox`, `lastActiveAgo` | YC shows the age in words (`17 days`, `about 1 month`); `postedDateApprox` is the matching calendar day (to the day for ages under a month, approximate beyond) |
| `updatedDate` | The last-modified date YC publishes for the job page in its sitemap |
| `companyName`, `companySlug`, `companyBatch`, `companyTeamSize`, `companyIndustries`, `companyOneLiner` | The startup, its YC batch (`W26`, `S24`...), headcount and industry tags |
| `companyWebsite`, `companyLinkedinUrl`, `companyLocation`, `companyCountry`, `companyFoundedYear`, `companyStatus`, `companyLogoUrl`, `companyYcUrl` | Where to find the company |
| `description` | The full job description (Markdown) when **Include the full job description** is on, otherwise null |
| `scrapedAt` | When the row was read |

#### Example row (real, 2026-10-25)

```json
{
  "jobId": 92562,
  "title": "Member of Technical Staff",
  "companyName": "Lance",
  "companySlug": "lance",
  "companyBatch": "W26",
  "companyTeamSize": 10,
  "companyIndustries": [],
  "companyOneLiner": "AI Agents That Run Hotel Operations.",
  "companyWebsite": "https://www.lance.live",
  "location": "San Francisco, CA, US",
  "locations": ["San Francisco, CA, US"],
  "isRemote": false,
  "jobType": "Full-time",
  "role": "Engineering",
  "roleCode": "eng",
  "salaryRange": "$160K - $260K",
  "salaryMin": 160000,
  "salaryMax": 260000,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "equityRange": "0.30% - 0.70%",
  "equityMinPercent": 0.3,
  "equityMaxPercent": 0.7,
  "postedAgo": "7 months",
  "jobUrl": "https://www.ycombinator.com/companies/lance/jobs/OCpozpZ-member-of-technical-staff"
}
```

(Shortened: every row carries all the fields in the table above.)

### Input

| Field | What it does |
| --- | --- |
| `roles` | Engineering, Design, Product, Science, Sales, Marketing, Support, Operations, Recruiting & HR, Finance, Legal. Several are combined (any of them) |
| `keywords` | Words that must appear in the job title (`Founding Engineer`, `Machine Learning`, `Account Executive`). Any line matches |
| `locations` | Matched against the job location: `San Francisco`, `New York`, `London`, `India`, `Remote`. Any line matches |
| `remoteOnly` | Only jobs whose location includes Remote |
| `jobTypes` | Full-time, Internship, Contract, Co-founder |
| `visa` | Any, Will sponsor, US citizenship or visa not required, US citizen or visa holders only |
| `minSalaryUsd` | Yearly USD floor on the top of the range (hourly x 2,080, monthly x 12). Jobs without a USD salary are dropped when set |
| `maxExperienceYears` | Jobs asking at most this many years; 0 = new grads welcome |
| `postedWithin` | Last 24 hours, 3, 7, 14, 30 or 90 days |
| `batches` | YC batches such as `W25`, `S24`, `F25`, `P26` |
| `companies` | Only these companies: a slug (`whatnot`), a `ycombinator.com/companies/...` URL, or a single job URL. Leave empty for the whole board |
| `includeDescription` | Adds the full description (one extra page per job, same price) |
| `maxResults` | Stop after this many jobs (default 100, up to 10,000) |
| `onlyNew` | Deliver only jobs earlier only-new runs with the same input have not delivered |

Filters combine with AND; several values inside one filter combine with OR.

#### Examples

Remote engineering jobs that sponsor visas and pay at least $150K:

```json
{ "roles": ["eng"], "remoteOnly": true, "visa": "sponsors", "minSalaryUsd": 150000, "maxResults": 500 }
```

A daily feed of new sales and marketing jobs at Winter and Summer 2025 startups:

```json
{ "roles": ["sales", "marketing"], "batches": ["W25", "S25"], "onlyNew": true, "maxResults": 1000 }
```

Every open job at a few companies, with descriptions:

```json
{ "companies": ["whatnot", "https://www.ycombinator.com/companies/astranis"], "includeDescription": true, "maxResults": 1000 }
```

### Pricing

$1.25 per 1,000 jobs on the Free plan ($1.125 Bronze, $1.00 Silver, $0.875 Gold), plus $0.005 per run to start. Platform usage is included and descriptions cost nothing extra. Filters or companies with no matching jobs cost nothing beyond the run start, and so does an only-new run with nothing new. You can cap spend with Apify's maximum-charge setting: the run stops cleanly when it is reached.

### FAQ

**Do I need a Y Combinator or Work at a Startup account?** No. The actor reads the public job pages ycombinator.com shows to visitors who are not logged in. Applying to a job (the `applyUrl`) needs a free Work at a Startup account.

**How many jobs are there?** About 6,400 open jobs at about 1,700 companies on 2026-10-25. A run over the whole board reads every hiring company's page, which takes about 3 minutes. Narrow filters such as one role read the whole board too, because YC publishes no role index; title keywords are faster, since YC's sitemap already carries every job title and only matching companies are opened.

**How does only-new mode work?** The actor keeps the IDs of jobs it delivered, filtered out or saw closed in a key-value store named `yc-jobs-scraper-monitor` in your account, one memory per set of filters and companies. The next run reads YC's jobs sitemap and opens only the companies that list a job it has not settled yet, so a day with nothing new costs only the run start. A new job therefore reaches the feed once YC's sitemap lists it. Delete the store to start over.

**Why is the salary empty on some rows?** About 1 in 5 postings shows no salary (1,327 of 6,416 on 2026-10-25). When one does, you get it as numbers with its currency and pay period.

**Why is the posting date approximate?** YC shows how long ago a job was posted in words (`17 days`, `about 1 month`, `over 1 year`), not a date. `postedDateApprox` turns that into a day; `updatedDate` is the exact last-modified date from YC's sitemap.

**Why no hiring manager or founder names?** They are private people. This actor delivers jobs and company facts only.

**Why fewer jobs than I asked for?** The run status says why: the board ran out of matches, a filter dropped the rest (with counts per filter), a company was not found, or the run time limit stopped it.

### Related actors

- [ATS Jobs Scraper](https://apify.com/tagadanar/ats-jobs-aggregator): jobs straight from Greenhouse, Lever, Ashby and Workable career pages, with a monitor mode.
- [Workday Jobs Scraper](https://apify.com/tagadanar/workday-jobs-scraper): any company's Workday career site, with full descriptions.
- [Remote Jobs Scraper & Aggregator](https://apify.com/tagadanar/remote-jobs-aggregator): remote jobs from seven job boards in one feed.
- [LinkedIn Company Jobs Scraper](https://apify.com/tagadanar/linkedin-company-jobs): every open LinkedIn role at one company.

Not affiliated with Y Combinator.

# Changelog

This Actor's version history is a separate document: https://apify.com/tagadanar/yc-jobs-scraper/changelog.md

# Actor input Schema

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

The Work at a Startup role categories. Several roles are combined (any of them). Leave empty for every role.

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

Words or phrases that must appear in the job title, for example Founding Engineer, Machine Learning, Account Executive. One per line; a job matches if its title contains any of them. Leave empty for every title.

## `locations` (type: `array`):

Cities, states or countries matched against the job location, for example San Francisco, New York, London, India, Remote. One per line; a job matches if its location contains any of them.

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

Keep only jobs whose location includes Remote (for example Remote (US) or San Francisco / Remote).

## `jobTypes` (type: `array`):

Full-time, internship, contract or co-founder roles. Leave empty for every type.

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

The visa line each YC job carries.

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

Keep only jobs paid in US dollars whose top of the range reaches this yearly amount (hourly and monthly pay are converted to a year). Jobs with no salary, or a salary in another currency, are dropped when this is set.

## `maxExperienceYears` (type: `integer`):

Keep jobs asking for at most this many years of experience. 0 = new grads welcome. Jobs that state no minimum are kept.

## `postedWithin` (type: `string`):

Keep jobs posted at most this many days ago. YC shows the age in words ("17 days", "about 1 month"); a job is kept only when its whole age bracket fits.

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

Keep only companies from these YC batches, for example W25, S24, F25 or P26. Leave empty for every batch.

## `companies` (type: `array`):

Only these YC companies: a slug (whatnot), a page URL (https://www.ycombinator.com/companies/whatnot or .../jobs) or a single job URL. Leave empty to scan the whole Work at a Startup board.

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

Opens each job page for the full description (Markdown). Same price per job; runs take longer.

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

Stop after this many jobs. The whole board holds a few thousand open jobs.

## `onlyNew` (type: `boolean`):

Deliver only jobs that earlier only-new runs with the same filters have not delivered. Schedule it daily for a feed of fresh YC jobs; a run with nothing new costs only the run start.

## Actor input object example

```json
{
  "roles": [
    "eng"
  ],
  "remoteOnly": false,
  "visa": "any",
  "postedWithin": "any",
  "includeDescription": false,
  "maxResults": 50,
  "onlyNew": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# 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 = {
    "roles": [
        "eng"
    ],
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("tagadanar/yc-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 = {
    "roles": ["eng"],
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("tagadanar/yc-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 '{
  "roles": [
    "eng"
  ],
  "maxResults": 50
}' |
apify call tagadanar/yc-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tagadanar/yc-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/afBz0K2ysIdS978AE/builds/qlasXs1vYjdZtVOhk/openapi.json
