# Hacker News Scraper — Who Is Hiring Jobs, Stories & Comments (`northbell/hacker-news-scraper`) Actor

Hacker News scraper: the monthly "Who is hiring?" thread as clean job rows (company, role, location, remote, salary, visa, apply links), YC job posts, stories (front page, Show HN, Ask HN, search) and comments. Only new posts since your last run. No login, no API key.

- **URL**: https://apify.com/northbell/hacker-news-scraper.md
- **Developed by:** [Northbell](https://apify.com/northbell) (community)
- **Categories:** Jobs, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 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

## Hacker News Scraper — Who Is Hiring Jobs, Stories & Comments

Every month Hacker News runs **"Ask HN: Who is hiring?"** — hundreds of startups and tech companies post their open roles in one thread. This Actor turns each post into a **clean job row**: company, role, location, remote / onsite / hybrid, salary range, visa sponsorship, employment type, seniority and apply links. Filter it like any job board, and schedule it daily to get **only the posts added since yesterday** — the thread keeps growing all month.

It also returns **YC job posts**, **stories** (front page, Show HN, Ask HN, or any search) and **comments** (by search, or every comment of a story).

### What you get (Who is hiring)

| Field | What it is |
|---|---|
| `company`, `companyUrl` | the company, from the first line of the post |
| `title`, `roles` | the roles named in the post (a post often lists several) |
| `location`, `remote`, `onsite`, `hybrid` | where, as written, and whether it says REMOTE / ONSITE / HYBRID |
| `salaryText`, `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | pay, when the post states it (about 1 post in 4 does) |
| `visaSponsorship` | `true` when the post offers it, `false` when it says it cannot sponsor, `null` when it does not say |
| `employmentTypes`, `seniority` | the same words as every northbell job scraper: full-time / part-time / contract / internship, intern … executive |
| `applyUrls` | the links in the post (careers pages, application forms) |
| `description` | the whole post as plain text |
| `postedAt`, `url`, `threadMonth` | when, the post on Hacker News, and which month's thread |
| `isNewSinceLastRun` | `true` when this post was not returned on your previous run |

Measured on the October 2026 thread (233 posts on October 7): every one with a company, 9 in 10 with a location, 7 in 10 with a role, 1 in 4 with a salary range.

`postedBy` is the poster's public Hacker News username. Turn on **Leave out people's names** (`omitPersonalNames`) and it stays empty: useful for GDPR-minded projects in the EU that should hold no personal data. Email addresses in posts are replaced with `[email removed]` — apply through the links instead. "Who wants to be hired?" (people looking for work) is not collected.

### Use it for

- **Job search** — every remote Rust, Python or ML role posted this month, with salary and visa, in one sheet
- **Sales and recruiting leads** — which startups are hiring, for what, and where, refreshed daily
- **Hiring-market research** — 24 months of threads: remote share, salary ranges, which stacks are in demand
- **Tech news monitoring** — front page, Show HN or any keyword, with points and comment counts

### Input

```json
{ "mode": "hiring", "searches": ["rust", "python"], "remoteOnly": true, "onlyNew": true }
```

```json
{ "mode": "stories", "storyType": "show-hn", "minPoints": 50, "postedWithinDays": 7 }
```

Data comes from the public Hacker News search API (Algolia) — no login, no API key.

Looking for more roles? See the [Jobs API](https://apify.com/northbell/job-aggregator-scraper) — 461 companies' own job boards, with **Industries** (Y Combinator, startups, AI…) and **Remote roles only** — same columns, same filters.

### Pricing

**$1.00 per 1,000 job rows** (Who is hiring and YC jobs), **$0.20 per 1,000 stories or comments**, plus $0.01 per run. A whole month of Who is hiring (230–260 posts in August and September 2026) costs about $0.26. Error rows are free. The $0.01 run-start fee is the one charge every run pays, even one that returns nothing.

### For AI agents

`{"mode": "hiring", "searches": ["typescript"], "remoteOnly": true}` returns this month's remote TypeScript roles. Rows have `type`: `job`, `story`, `comment` or `error`.

# Actor input Schema

## `mode` (type: `string`):

"Who is hiring?" turns each top-level post of the monthly thread into a job row. Replies and "Who wants to be hired?" are not collected.

## `searches` (type: `array`):

Stories / comments: what to search for. Who is hiring / YC jobs: keep only posts that mention any of these words, e.g. "rust", "python", "machine learning".

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

Who is hiring: keep only posts that say REMOTE.

## `locationKeywords` (type: `array`):

Who is hiring: keep posts whose location or first line mentions any of these, e.g. "London", "Berlin", "EU", "NYC".

## `visaSponsorshipOnly` (type: `boolean`):

Who is hiring: keep posts that offer visa sponsorship (posts that say they cannot sponsor are left out).

## `experienceLevels` (type: `array`):

Keep only these levels, read from the roles in the post (the same words on every northbell job scraper; each row also gets a seniority column).

## `employmentTypes` (type: `array`):

From the first line of the post. Posts that do not state a type are left out when you set this, and counted in OUTPUT.

## `months` (type: `integer`):

1 = the current month's thread. Up to 24 months back.

## `storyType` (type: `string`):

Which stories to list when you are not searching: all, the current front page, Show HN or Ask HN.

## `storyUrls` (type: `array`):

news.ycombinator.com/item?id=… links. Returns every comment of the story with its depth in the thread.

## `sortBy` (type: `string`):

For keyword searches: newest first, or most relevant first. Hacker News search returns at most 1,000 results per query when sorted by relevance.

## `postedWithinDays` (type: `integer`):

Keep only posts, stories or comments from the last N days.

## `minPoints` (type: `integer`):

Skip stories with fewer points than this. 0 keeps every story.

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

Caps what you pay for. Default: all posts of the hiring thread, 200 for stories and comments.

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

From the second run on, return only posts this Actor has not returned before for the same thread or search. The hiring thread grows all month, so schedule it daily.

## `omitPersonalNames` (type: `boolean`):

Off: names and handles are returned as shown publicly. On: they are left out (empty), for GDPR-minded projects that need no personal data.

## Actor input object example

```json
{
  "mode": "hiring",
  "searches": [],
  "remoteOnly": false,
  "visaSponsorshipOnly": false,
  "months": 1,
  "storyType": "all",
  "sortBy": "date",
  "minPoints": 0,
  "maxItems": 200,
  "onlyNew": false,
  "omitPersonalNames": false
}
```

# Actor output Schema

## `jobs` (type: `string`):

Who is hiring posts and YC job posts as job rows.

## `stories` (type: `string`):

Stories with points and comment counts.

## `comments` (type: `string`):

Comments with their story.

# 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 = {
    "searches": [],
    "maxItems": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("northbell/hacker-news-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 = {
    "searches": [],
    "maxItems": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("northbell/hacker-news-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 '{
  "searches": [],
  "maxItems": 200
}' |
apify call northbell/hacker-news-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,northbell/hacker-news-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/bqrNdq22qaJR8LGrI/builds/yiZW74xLg6lib68ql/openapi.json
