Y Combinator Jobs — Enriched & Normalized avatar

Y Combinator Jobs — Enriched & Normalized

Pricing

from $0.90 / 1,000 y combinator job results

Go to Apify Store
Y Combinator Jobs — Enriched & Normalized

Y Combinator Jobs — Enriched & Normalized

Extract public Work at a Startup openings into nomad-agent-job-v1. Complete Inertia details provide descriptions, salary, equity, visa and company facts; optional owner-managed AI fills only missing description-backed fields.

Pricing

from $0.90 / 1,000 y combinator job results

Rating

0.0

(0)

Developer

Nomad Dev

Nomad Dev

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

14 hours ago

Last modified

Categories

Share

Y Combinator Work at a Startup — normalized job Actor

This Actor reads complete YC Work at a Startup jobs from an owner-maintained durable PostgreSQL inventory and emits strict nomad-agent-job-v1 records. It is the normalized successor to the legacy flat ycombinator-was-scraper; it deliberately retains identity.source: "ycombinator_was" so downstream job keys remain stable.

This public Actor never calls Work at a Startup. An owner-only scheduled ycombinator-private-collector performs fixed-scope discovery and identity- bound detail retrieval, then stores complete normalized records in the Netcup position inventory. Public runs fail closed if that inventory is unavailable or stale; there is no live-source fallback. The public host owns user filters, optional null-only enrichment, selected-field translation, transactional delivery inventory, PPE billing, delivery, analytics, and RUN-SUMMARY.

Source and completeness boundary

Work at a Startup exposes a public JSON search endpoint and public Inertia job pages. The private collector's hourly task fans out over 62 fixed ordered terms, deduplicates by source job ID, and durably queues new, changed, or refresh-due cards. A separate detail task writes only recognized, complete, identity-bound jobs. Neither collector mode performs enrichment or translation.

A search card is never exposed by the public Actor. Every inventory row has a recognized detail payload whose embedded job ID matches the requested URL and whose descriptionHtml produces a non-empty complete description. The public Actor scans a frozen inventory cursor and applies keyword, location, YC taxonomy, normalized, work-arrangement, and unseen filters locally.

YC's session-bound authentication links contain regenerated application codes and placeholder emails. They are neither used for candidate change detection nor stored as durable application URLs; when no stable direct apply URL is published, data.application.url points to the stable YC job page.

Input

The required shared contract marker is:

{
"schemaVersion": "nomad-agent-job-search-input-v1",
"keyword": "founding engineer",
"postedWithin": "24h",
"maxItems": 25
}

keyword is matched locally against cached normalized content. When blank, no keyword filter is applied. Multiple local search terms and YC taxonomy filters use the separately versioned extension:

{
"schemaVersion": "nomad-agent-job-search-input-v1",
"postedWithin": "7d",
"ycSearch": {
"schemaVersion": "nomad-agent-ycombinator-search-v1",
"queries": ["python", "founding engineer"],
"companyBatches": ["S23", "W24"],
"roleTypes": ["engineering"],
"jobTypes": ["Full-time"]
}
}

A non-empty keyword and non-empty ycSearch.queries are mutually exclusive. The queries array is an OR-list over cached content; unlike LinkedIn search partitions, it does not create separate upstream requests and its order has no meaning. companyBatches matches YC accelerator cohorts such as W24, roleTypes matches substrings in YC's published role category, and jobTypes matches YC's published job-type label with common full-time, part-time, contract, and internship aliases normalized.

YC exposes no source posting timestamp. The owner inventory assigns data.application.postedAt once, at the UTC hour when it first observes a new job, and preserves that timestamp across detail refreshes. postedWithin supports 1h, 24h, 7d, 30d, and any against that cache-admission time; the omitted default is any, so a first search is not silently restricted to jobs first observed during the last day. companyLastActiveAt remains separate company metadata. Top-level orderBy accepts newest or oldest and uses the same cache-admission hour, with unknown times last. maxItems accepts up to 1,000; 0 means the bounded 1,000-result window, never unlimited.

Other shared inputs are location, workArrangements, dedupe, filters, aiEnrichment, translateToEnglish, includeRaw, and analyticsEnabled. firstRunMode is an explicit opt-in to the same five-result paid evaluation preset as LinkedIn while preserving all search, taxonomy, ordering, and normalized-filter choices. Owner policy such as inventory freshness, query bounds, models, and credentials lives in scraper.yaml, not caller input.

Output semantics

Every dataset row has exactly these roots:

schemaVersion, identity, data, custom, llm, raw

Static source facts win. Optional AI enrichment may fill only still-null description-backed normalized paths. Translation touches only configured short display fields. Raw job description text and HTML remain unchanged unless the caller sets includeRaw: false, which produces raw: null after processing.

Important source rules:

  • null means unknown, unavailable, or not safely parsed.
  • [] means the complete detail explicitly supplied an empty collection.
  • Remote (...) is an explicit remote signal; a physical location does not prove onsite or hybrid.
  • A dollar symbol alone does not prove USD, and an amount without period text does not prove annual compensation.
  • One explicit salary amount maps to compensation.exact; a range maps to minimum/maximum.
  • Founders remain company metadata and never become hiringContacts.
  • YC roleType remains a job function/custom role label, not seniority.
  • Skills remain source tags, with provenance in custom.data.skills. When no stronger typed preference already exists, the Actor also mirrors non-empty tags to data.requirements.preferredSkills as positive-only ranking context. It never asserts these generic tags as requiredSkills.
  • Cleaned interview-process text maps to data.application.selectionProcess; custom.data.interviewProcessHtml preserves the YC-authored rich text because the canonical application contract has no HTML sibling.

The versioned custom contract is ../job_custom_schemas/ycombinator-v2.schema.json. It retains batch, slug, source location/job-type labels, raw equity/visa labels, source skills, interview HTML, bounded opaque structured custom questions, company hiring/technology descriptions, team size, last-active metadata, and founder profiles. Role category, salary text, and interview-process text live only in their canonical data fields.

YC company identity is already canonical where the shared contract has an exact destination: name, numeric YC source ID, website, logo, and industry map to data.company/data.classification. The remaining custom.data.company facts are company-wide metadata—tagline, headquarters, team size, activity, hiring/technology prose, and founders—with no safe v1 canonical destination. The private collector already reads the complete YC company block from each detail page, so LinkedIn's optional companyProfileEnrichment fetch is neither needed nor exposed. LinkedIn's companyFilters also remain source-specific: they filter facts from that optional LinkedIn company-page fetch, whereas shared filters operate only on canonical normalized fields.

Run summary and retries

The Actor writes the closed, minimal nomad-agent-run-summary-v4 contract under RUN-SUMMARY. It contains status, startedAt, finishedAt, resultsLimited, delivered, and one bounded retry recommendation. It never automatically starts another paid run and never falls back to YC when inventory access fails. A deadline or summary-persistence failure fails the run; it cannot be published as a successful empty result. The reviewed stage reserves leave search time at a 600-second caller cap even when enrichment is enabled.

Local verification

From the repository root:

apify/.venv/bin/python \
apify/ycombinator-enrich-translate-normalize-scraper/scripts/verify_core_wheel.py
cd apify/ycombinator-enrich-translate-normalize-scraper
PYTHONPATH=wheels/nomad_job_scraper_core-1.1.31-py3-none-any.whl \
../.venv/bin/python -m pytest -q
PYTHONPATH=wheels/nomad_job_scraper_core-1.1.31-py3-none-any.whl \
../.venv/bin/python \
scripts/generate_dataset_schema.py --check

After exporting one 600-second AI-enabled, translation-disabled canary as an object containing run, input, items, and runSummary, verify terminal classification plus complete text/HTML length and SHA-256 receipts with:

$python scripts/verify_canary_evidence.py canary-evidence.json

Local tests and schema checks do not authorize an Actor build, push, pricing change, deployment, or Store publication.