# Y Combinator Jobs Scraper — Work at a Startup (1,000+ Jobs) (`nomad-agent/ycombinator-was-scraper`) Actor

Scrape the whole Work at a Startup board — 1,000+ live YC jobs, not just engineering. Each posting carries parsed salary, equity, visa policy, skills, full description and the hiring company's profile (industry, website, team size, founders). Filter by YC batch, role, type or remote. No start fee.

- **URL**: https://apify.com/nomad-agent/ycombinator-was-scraper.md
- **Developed by:** [Nomad.Dev](https://apify.com/nomad-agent) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 35 total users, 22 monthly users, 67.4% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 job results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Y Combinator Jobs Scraper — Work at a Startup

Fetch live openings at Y Combinator startups from Work at a Startup (workatastartup.com) as structured JSON.

> **Claude / Codex skill to describe and setup this actor: [SKILL.md](https://github.com/Exdenta/OinkAIJobSearch/blob/main/skill/ycombinator-was-scraper/SKILL.md)**

Work at a Startup (workatastartup.com) is Y Combinator's official jobs marketplace, where current YC-backed companies post engineering, product, sales, design and operations roles. This Actor queries its public search API to find openings, then enriches each one from its public detail page — so every YC job comes back as a flat JSON record with structured **salary, equity, visa, skills, full description** and the hiring **company's profile**, without scraping HTML yourself or logging in.

### What Y Combinator jobs data does this scraper extract?

Each result is one flat JSON record per job posting:

| Field | Meaning |
|---|---|
| `title` | Job title as posted |
| `company` | Hiring company / organisation |
| `companySlug` | Company's slug on Work at a Startup |
| `companyBatch` | YC batch code (e.g. `S23`) |
| `location` | Location / duty station (may include remote hints) |
| `isRemote` | `true` when the location advertises a remote option |
| `roleType` | Role category as tagged by the source (e.g. `Machine learning`) |
| `jobType` | Employment type, normalised (`Full-time`, `Contract`, `Internship`, `Part-time`) |
| `salary` | Salary text exactly as published (e.g. `$150K - $220K`) |
| `salaryMin` / `salaryMax` | Numeric salary bounds parsed from the text (`K` expanded) |
| `salaryCurrency` / `salaryPeriod` | ISO currency (`USD`, `INR`, …) and period (`year`, `month`, …) |
| `equity` | Equity range (e.g. `0.10% - 0.50%`) — detail enrichment |
| `visaSponsorship` | Visa policy (e.g. `Will sponsor`) — detail enrichment |
| `experience` | Minimum experience (e.g. `3+ years`) — detail enrichment |
| `skills` | Skill tags array (e.g. `["Figma", "Machine Learning"]`) — detail enrichment |
| `description` / `descriptionHtml` | Full job description, plain text and HTML — detail enrichment |
| `companyTagline` | Company one-liner |
| `companyDescription` / `companyDescriptionHtml` | Company hiring pitch — detail enrichment |
| `companyIndustry` | YC industry classification — detail enrichment |
| `companyLogo` | Company logo URL |
| `companyWebsite` | Company website — detail enrichment |
| `companyLocation` / `companyTeamSize` | Company HQ + headcount — detail enrichment |
| `founders` | Founder profiles (name, avatar, LinkedIn, past companies) — detail enrichment |
| `applyUrl` | Work at a Startup application link |
| `url` | Direct link to the posting |
| `postedAt` | Always `null` — the source exposes no per-listing posting date (see `companyLastActiveAt`) |
| `snippet` | Short context excerpt |
| `id` | Stable source-side identifier (also used for delta mode) |
| `source` | Fixed value `"ycombinator_was"` |

Detail-enrichment fields are populated when `includeJobDetails` is on (the default). Turn it off for a faster, cheaper list-only run.

### Coverage — the whole board, not just engineering

Work at a Startup's public search endpoint returns only ~20-30 hits per search term and offers
no pagination, so a scraper's coverage is decided entirely by how many terms it fans out across.
This Actor sweeps **60 role, stack, function and seniority terms**, then deduplicates by job ID:

- **~1,050 unique live jobs** in a single `maxItems: 0` run, in ~95 seconds.
- Every role family the board tags — not just engineering. Sales, marketing, design, recruiting,
  finance, operations, QA, hardware and embedded roles are all reachable.
- Every returned job is detail-enriched by default (descriptions, skills, equity, visa, founders),
  fetched concurrently rather than one at a time.

Set `maxItems` to cap the run — it stops fanning out as soon as the cap is met, so a 50-job run
takes about 7 seconds and only touches the first few search terms.

### How to scrape Y Combinator jobs with this Actor

1. Click **Try for free** / **Run** — no login to the target site, no cookies, no proxies to configure.
2. Adjust the input (keyword, filters, `maxItems`) or keep the defaults.
3. Run it and export the dataset as JSON, CSV or Excel, or read it over the [API](https://docs.apify.com/api/v2).

Run it from your own code:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("nomad-agent/ycombinator-was-scraper").call(run_input={"maxItems": 50})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], "—", item["company"], item["url"])
```

Or a single HTTP call that runs the Actor and returns items in one response:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/nomad-agent~ycombinator-was-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"maxItems": 50}'
```

### Integrations

Chain this Actor with [Zapier, Make, Slack, Airtable and Google Sheets via Apify's built-in integrations](https://docs.apify.com/platform/integrations), schedule recurring runs with the [Apify Scheduler](https://docs.apify.com/platform/schedules), or pull results straight into your own pipeline with the [Apify API](https://docs.apify.com/api/v2).

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `queries` | array | *(built-in set)* | Role-specific search terms to fan out across; each fetches an independent page, merged and deduplicated by job ID. |
| `includeJobDetails` | boolean | `true` | Enrich each posting from its detail page (description, skills, equity, visa, company profile). Off = fast list-only run. |
| `titleExclude` | array | `[]` | Skip postings whose title contains any of these terms (case-insensitive). |
| `jobTypes` | array | `[]` | Keep only these employment types (`Full-time`, `Contract`, `Internship`, `Part-time`). |
| `companyBatches` | array | `[]` | Keep only these YC batches (e.g. `S23`, `W24`). |
| `roleTypes` | array | `[]` | Keep only role categories containing these terms (e.g. `machine learning`, `frontend`). |
| `remoteOnly` | boolean | `false` | Keep only postings whose location advertises a remote option. |
| `maxItems` | integer | `50` | Max unique postings to return. Set 0 for no limit. |
| `onlyNewSinceLastRun` | boolean | `false` | Delta mode: return only postings not seen in a previous run (records carry `isNew: true`). Ideal for schedules. |
| `cacheTtlSeconds` | integer | `1800` | Cache upstream fetches (search + detail) for this many seconds; re-runs within the window skip the network. `0` disables. |

### Output example

```json
{
  "id": "73211",
  "title": "Founding Engineer",
  "company": "Lindy",
  "companySlug": "lindy",
  "companyBatch": "S23",
  "location": "San Francisco, CA, US / Remote (US)",
  "isRemote": true,
  "roleType": "Machine learning",
  "jobType": "Full-time",
  "salary": "$150K - $220K",
  "salaryMin": 150000,
  "salaryMax": 220000,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "equity": "0.10% - 0.50%",
  "visaSponsorship": "Will sponsor",
  "experience": "3+ years",
  "skills": ["Python", "Machine Learning"],
  "description": "We're building an AI executive assistant…",
  "descriptionHtml": "<p>We're building an AI executive assistant…</p>",
  "companyTagline": "AI executive assistant for busy professionals.",
  "companyIndustry": "B2B -> Engineering, Product and Design",
  "companyLogo": "https://bookface-images.s3.amazonaws.com/small_logos/…png",
  "companyWebsite": "https://www.lindy.ai/",
  "companyTeamSize": 25,
  "founders": [{"name": "Flo Crivello", "linkedin": "https://www.linkedin.com/in/…"}],
  "applyUrl": "https://www.workatastartup.com/jobs/73211",
  "postedAt": null,
  "url": "https://www.workatastartup.com/jobs/73211",
  "source": "ycombinator_was"
}
```

`postedAt` is always `null` — neither the Work at a Startup search API nor the detail page exposes a per-listing posting date. `companyLastActiveAt` is included as a company-level freshness proxy where the source provides it.

### Pricing

Pay per event, **per job returned — and no Actor start fee.**
Until **27 July 2026** the price is **$0.90 / 1,000 jobs**. From 27 July 2026:

| Your Apify plan | Price per 1,000 jobs |
|---|---|
| Free | $2.50 |
| Starter | $2.20 |
| Scale | $2.00 |
| Business | $1.80 |

No subscription, no rental, no start fee — you pay only for the jobs you actually get.
Because there is no start fee, a scheduled delta run (`onlyNewSinceLastRun`) that finds
nothing new costs you **$0.00**.

### Use cases

- Startup job boards and newsletters
- Tracking YC-company hiring by batch
- Sourcing candidates who want startup roles
- VC portfolio talent intelligence

### FAQ

**Is it legal to scrape Y Combinator jobs?**
This Actor reads only publicly available job postings — data any visitor can see without logging in. No personal data behind authentication is touched. Review the target site's terms and your local regulations for your specific use case.

**Do I need an account on the target site?**
No. Postings are fetched from public pages/APIs — no login, cookies or session tokens.

**How fresh is the data?**
Every run fetches live listings. Results are cached for `cacheTtlSeconds` (default 30 min, set 0 to always hit the source live). For scheduled runs, enable `onlyNewSinceLastRun` to receive only postings that weren't returned by a previous run.

**How many jobs can I get?**
`maxItems` caps the run (set 0 for no cap). The Work at a Startup search endpoint returns a fixed, unpaginated result set per query, so coverage is widened by fanning out across more `queries` terms, not by raising `maxItems`.

**Does it cover every YC batch?**
Yes — results span all companies currently posting on Work at a Startup, across every batch. Use `queries` to target roles, `companyBatches` / `roleTypes` / `jobTypes` / `remoteOnly` to filter, and `titleExclude` to drop titles you don't want.

**Something broken or missing?**
Open an issue on the Actor's **Issues** tab — it is monitored and reliability fixes ship fast.

**Is this Actor useful to you?**
A quick ⭐ review on the Actor's **Reviews** tab helps other startup-job hunters find it — and tells us what to build next.

### Related Actors

- [Web Developer Jobs Scraper — 10 Boards in One](https://apify.com/nomad-agent/web-dev-bundle)
- [AI & ML Engineer Jobs Scraper — 8 Boards in One](https://apify.com/nomad-agent/ml-ai-dev-bundle)
- [Hacker News Who Is Hiring Scraper — HN Jobs](https://apify.com/nomad-agent/hackernews-scraper)
- [Built In Jobs Scraper — US Tech & Startup Jobs](https://apify.com/nomad-agent/builtin-scraper)

***

**From the maker of [Oink](https://github.com/Exdenta/OinkAIJobSearch)** — an open-source, AI-powered job-search bot for Telegram that runs on these Actors. [Try the free bot](https://t.me/job_search_everyday_bot), get a managed instance at [oinkjobsearch.com](https://oinkjobsearch.com), or browse the [full catalog of 50+ Actors](https://apify.com/nomad-agent).

# Actor input Schema

## `queries` (type: `array`):

Search terms to fan out across. Work at a Startup returns only ~20-30 hits per term and has no pagination, so the number of terms decides how much of the board you see. Each term is fetched independently, then results are merged and deduplicated by job ID. Leave empty to use the built-in 60-term sweep, which covers every role family on the board (engineering, AI/ML, sales, marketing, design, recruiting, finance, ops) and yields ~1,050 unique jobs.

## `includeJobDetails` (type: `boolean`):

Fetch each posting's public detail page to add full description/descriptionHtml, skills, equity, visa sponsorship, experience and the hiring company's profile (industry, website, team size, founders). Turn OFF for a faster, cheaper list-only run (id, title, company, batch, location, salary, apply URL). One extra request per returned job when ON.

## `titleExclude` (type: `array`):

Skip postings whose title contains any of these terms (case-insensitive). Applied after fetching, on top of the queries above.

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

Keep only postings of these employment types (case-insensitive). Recognised values: "Full-time", "Contract", "Internship", "Part-time". Leave empty for all types.

## `companyBatches` (type: `array`):

Keep only postings from companies in these Y Combinator batches (case-insensitive exact match, e.g. "S23", "W24"). Leave empty for all batches.

## `roleTypes` (type: `array`):

Keep only postings whose Work at a Startup role category contains one of these terms (case-insensitive substring, e.g. "machine learning", "frontend", "design"). Leave empty for all categories.

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

Keep only postings whose location advertises a remote option.

## `maxItems` (type: `integer`):

Maximum number of unique job postings to return. The run stops fanning out across search terms as soon as the cap is met, so a small cap is fast and cheap (50 jobs ≈ 7 seconds). Set to 0 for no limit — the full board, ~1,050 unique jobs in ~95 seconds.

## `onlyNewSinceLastRun` (type: `boolean`):

Delta mode: skip postings already delivered by a previous run of this Actor (tracked by job ID in a named key-value store). Returned records carry isNew=true. Great for scheduled runs that should surface only fresh openings.

## `cacheTtlSeconds` (type: `integer`):

Cache the upstream fetches (search + detail pages) in the key-value store for this many seconds; re-runs within the window skip the network calls. Set 0 to disable.

## Actor input object example

```json
{
  "queries": [
    "machine learning",
    "data engineer",
    "react"
  ],
  "includeJobDetails": true,
  "titleExclude": [
    "intern",
    "sales"
  ],
  "jobTypes": [
    "Full-time",
    "Contract"
  ],
  "companyBatches": [
    "S23",
    "W24"
  ],
  "roleTypes": [
    "machine learning",
    "frontend"
  ],
  "remoteOnly": false,
  "maxItems": 50,
  "onlyNewSinceLastRun": false,
  "cacheTtlSeconds": 1800
}
```

# 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 = {
    "queries": [],
    "maxItems": 50,
    "cacheTtlSeconds": 1800
};

// Run the Actor and wait for it to finish
const run = await client.actor("nomad-agent/ycombinator-was-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 = {
    "queries": [],
    "maxItems": 50,
    "cacheTtlSeconds": 1800,
}

# Run the Actor and wait for it to finish
run = client.actor("nomad-agent/ycombinator-was-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "queries": [],
  "maxItems": 50,
  "cacheTtlSeconds": 1800
}' |
apify call nomad-agent/ycombinator-was-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=nomad-agent/ycombinator-was-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/1JDUBKElJkIKoCkgG/builds/Rn8CzskCLMQjcc3CJ/openapi.json
