# Hacker News API: Stories, Comments, Who Is Hiring (`ucchiii/hacker-news-api`) Actor

Hacker News scraper on the official Algolia and Firebase APIs: search stories by keyword, date and points, or read top/new/best/ask/show/job lists. Optional comments and 'Who is hiring' postings. E-mails and phones removed. Empty input = free demo. $1 per 1,000 items.

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

## Pricing

from $0.70 / 1,000 story or postings

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 API: stories, comments and "Who is hiring" as clean rows

**For founders, marketers, researchers and recruiters who need Hacker News data in a spreadsheet instead of copying it by hand.**
Search stories by keyword, date and points, read the top/new/best lists, add comments, or turn the monthly "Ask HN: Who is hiring?" thread into one row per job posting. **$1.00 per 1,000 items**, you pay only for rows returned.

- **Official public APIs only**: the Algolia HN Search API (`hn.algolia.com/api/v1`) and the official Hacker News Firebase API (`hacker-news.firebaseio.com/v0`). No HTML scraping, no login, no proxies.
- **One flat row per story**: `id`, `title`, `url`, `domain`, `points`, `numComments`, `createdAt`, `type` (story, ask, show, job, poll), `hnUrl`, plus `by` (the public HN username).
- **Three modes**: `search` (query, story type, date range, minimum points, newest or most relevant first), `list` (top, new, best, ask, show, job lists) and `whoIsHiring`.
- **Optional comments**: add a capped list of comments per story (text, `createdAt`, `parentId`, `points`, `by`). Comments are free.
- **Who is hiring**: top-level postings of the latest (or a chosen) monthly thread with `company` (text before the first `|`), `remote` and `onsite` flags and a `location` guess.
- **Privacy**: e-mail addresses and phone numbers are removed from all text and replaced with `[removed]`.
- **Free demo**: leave the input empty and the Actor returns 3 sample stories without charging (`_demo: true`).

### Input

```json
{
  "mode": "search",
  "query": "apify",
  "storyType": "show",
  "dateFrom": "2026-01-01",
  "minPoints": 10,
  "sortBy": "date",
  "includeComments": true,
  "maxCommentsPerStory": 20,
  "maxItems": 50
}
```

- `mode`: `search`, `list` or `whoIsHiring`.
- Search: `query`, `storyType` (story, ask, show, job), `sortBy` (date or relevance), `dateFrom` / `dateTo` (UTC, `YYYY-MM-DD`), `minPoints`.
- List: `list` (top, new, best, ask, show, job); `query`, `minPoints`, `dateFrom` / `dateTo` filter the fetched stories.
- Who is hiring: `hiringMonth` (`latest`, `2026-10` or `October 2026`), `query` (all words must appear), `remoteOnly`.
- `maxItems`: hard cap, 1 to 1000 (default 10). Algolia serves at most 1000 hits per query; split longer histories by date range.

### Output (one item per story)

```json
{
  "id": 41234567, "title": "Show HN: A tool for web scraping", "url": "https://example.com/tool", "domain": "example.com",
  "points": 154, "numComments": 61, "createdAt": "2026-10-01T15:04:05Z", "type": "show",
  "hnUrl": "https://news.ycombinator.com/item?id=41234567", "by": "someuser", "text": null,
  "comments": [{"id": 41234999, "by": "other", "text": "Nice work. How do you handle ...", "createdAt": "2026-10-01T16:00:00Z", "parentId": 41234567, "points": null}]
}
```

Who-is-hiring rows have `type: "hiring_post"`, `title` = first line of the posting, `text` = the full posting, and:

```json
{"company": "Acme", "remote": true, "onsite": false, "location": "Berlin", "threadId": 45000000, "threadTitle": "Ask HN: Who is hiring? (October 2026)"}
```

- `url` and `domain` are `null` for text posts (Ask HN). `points` of comments is `null` when the API does not give it.
- `company`, `remote`, `onsite` and `location` are simple guesses from the posting header; the full `text` is always included so you can check.
- A run summary (mode, items returned, thread read) is saved to the key-value store as `SUMMARY`.

### Pricing

Pay per event: **$0.001 per story or posting returned** ($1.00 per 1,000). Comments are included free with their story. Filters are applied before charging. The empty-input demo is free. Set a max charge per run in the run options to cap spend.

### Use cases

- Brand and competitor monitoring: every new story that mentions your product or domain
- Trend and launch research: Show HN posts by date range and points
- Daily or weekly digests of the top stories with the first comments
- Hiring-market signals: companies, locations and remote share from the monthly Who is hiring thread

### Notes

- Data comes only from the public Algolia and Firebase Hacker News APIs. Requests are polite: serial or in small batches with a short delay, timeouts and retries with backoff on 429 / 5xx.
- HN usernames appear only as `by` on stories, postings and comments (public pseudonyms). E-mail addresses and phone numbers are stripped on a best-effort basis; unusual obfuscations may slip through.
- A Who-is-hiring month with no thread returns no rows and is not charged.
- Not affiliated with Y Combinator or Hacker News.

### More tools from the same developer

- [RSS Feed Reader & Aggregator](https://apify.com/ucchiii/rss-feed-reader) — many RSS / Atom feeds merged into one clean article list
- [Job Postings Normalizer](https://apify.com/ucchiii/job-postings-normalizer) — unify fields, salaries and dates from any job scraper and remove duplicates
- [Himalayas Remote Jobs API](https://apify.com/ucchiii/himalayas-jobs-api) — remote job listings from the official Himalayas API, with attribution links
- [Greenhouse Jobs Scraper](https://apify.com/ucchiii/greenhouse-jobs) — open jobs from any Greenhouse job board via the public Job Board API
- [Dataset Merge & Dedup](https://apify.com/ucchiii/dataset-dedup-merge) — merge Apify datasets and remove duplicates by the fields you choose

# Actor input Schema

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

search = Algolia HN Search (keyword, dates, points). list = official top/new/best/ask/show/job lists. whoIsHiring = postings of the monthly 'Ask HN: Who is hiring?' thread. Leave everything empty for a free demo.

## `query` (type: `string`):

Words to look for, e.g. 'apify'. In list and whoIsHiring modes all words must appear in the title or text. Empty = no keyword filter.

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

Restrict the search to one kind of story: story (all regular stories), ask (Ask HN), show (Show HN) or job (job ads posted to HN). Empty = story.

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

date = newest first (Algolia search_by_date). relevance = best match first. Empty = date.

## `dateFrom` (type: `string`):

Only items created on or after this day, format YYYY-MM-DD, e.g. 2026-01-01. Empty = no limit.

## `dateTo` (type: `string`):

Only items created on or before this day (inclusive), format YYYY-MM-DD. Empty = no limit.

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

Keep only stories with at least this many points. Empty or 0 = no limit.

## `list` (type: `string`):

Which official Hacker News list to read: top, new, best, ask, show or job. Empty = top.

## `hiringMonth` (type: `string`):

Which 'Who is hiring?' thread to read: 'latest' or a month such as 2026-10 or 'October 2026'. Empty = latest.

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

Keep only postings whose header mentions remote work.

## `includeComments` (type: `boolean`):

Add a 'comments' list to every story (comment text, createdAt, parent id, points, by). Not used in whoIsHiring mode. Comments are free.

## `maxCommentsPerStory` (type: `integer`):

Cap on comments kept per story (depth-first, thread order). Between 1 and 500. Empty = 20.

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

Hard cap on rows returned (and charged). Between 1 and 1000; Algolia serves at most 1000 hits per query. Empty = 10.

## Actor input object example

```json
{
  "mode": "search",
  "query": "apify",
  "remoteOnly": false,
  "includeComments": false,
  "maxCommentsPerStory": 20,
  "maxItems": 10
}
```

# Actor output Schema

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

One item per story: id, title, url, domain, points, numComments, createdAt, type, hnUrl, by, text, and comments when enabled. In Who-is-hiring mode: the posting text plus company, remote, onsite and location.

## `summary` (type: `string`):

Record SUMMARY: mode, items returned and, for Who is hiring, the thread that was read.

# 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 = {
    "mode": "search",
    "query": "apify",
    "maxCommentsPerStory": 20,
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("ucchiii/hacker-news-api").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 = {
    "mode": "search",
    "query": "apify",
    "maxCommentsPerStory": 20,
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("ucchiii/hacker-news-api").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 '{
  "mode": "search",
  "query": "apify",
  "maxCommentsPerStory": 20,
  "maxItems": 10
}' |
apify call ucchiii/hacker-news-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ucchiii/hacker-news-api"
        }
    }
}
```

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/5tUkoTubyUBsa2PMN/builds/3yViZ0A8KnHU3Qzn4/openapi.json
