# Hacker News Scraper - Stories, Points & Comments (`scrapers_lat/hacker-news-scraper`) Actor

Scrape Hacker News stories by keyword with points, comment counts, author, URL, tags and timestamps. Sort by relevance or newest. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/scrapers_lat/hacker-news-scraper.md
- **Developed by:** [Scrapers Lat](https://apify.com/scrapers_lat) (community)
- **Categories:** News, Developer tools, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $6.80 / 1,000 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/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 - Stories, Points & Comments](https://scrapers.lat/banners/hacker-news-scraper.png)](https://console.apify.com/actors/nGllAZvIJgljXrPcd/input)

## Hacker News Scraper - Stories, Points & Comments

This actor searches or lists stories and returns every published field, including title, author, points and comment count.

### Sample output

| Field | Example value |
|---|---|
| `objectID` | 18428497 |
| `title` | Google Kubernetes Engine's third consecutive day of service disruption |
| `author` | rlancer |
| `points` | 779 |
| `numComments` | 407 |
| `storyUrl` | `https://news.ycombinator.com/item?id=18428497` |
| `domain` | status.cloud.google.com |
| `createdAt` | 2018-11-11T20:47:57Z |

You can test it on a free Apify plan with up to 10 results per run.

Here is one real result, with every field the actor returns:

```json
{
  "objectID": "18428497",
  "title": "Google Kubernetes Engine's third consecutive day of service disruption",
  "author": "rlancer",
  "points": 779,
  "numComments": 407,
  "url": "https://status.cloud.google.com/incident/container-engine/18005",
  "storyUrl": "https://news.ycombinator.com/item?id=18428497",
  "domain": "status.cloud.google.com",
  "text": null,
  "tags": ["story", "author_rlancer", "story_18428497"],
  "createdAt": "2018-11-11T20:47:57Z",
  "topComments": [
    {
      "author": "rlancer",
      "text": "Status page is inaccurate as issues doesn't only affect the web UI, the same operations are not functioning via the CLI.",
      "points": null,
      "createdAt": "2018-11-11T20:53:35.000Z"
    },
    {
      "author": "base698",
      "text": "What operations? Status just shows node pool creation.",
      "points": null,
      "createdAt": "2018-11-11T21:17:17.000Z"
    }
  ],
  "source": "Hacker News",
  "observedAt": "2026-08-14T08:22:14.856Z",
  "aiSummary": "Google Kubernetes Engine (GKE) is experiencing its third consecutive day of service disruptions, affecting users' ability to create new clusters and node pools across multiple regions. The overall sentiment is frustration, with discussions highlighting the lack of accurate status updates from Google.",
  "aiTopics": ["Google", "Kubernetes", "GKE", "Cloud Services", "Service Disruption", "Infrastructure", "DevOps"]
}
```

> `topComments` holds the highest-voted comments (this story has 28 attached); it is trimmed to two above for readability. Every value shown is real, unedited run data.

The most complete Hacker News scraper available. It searches or lists stories, returns every field the story exposes (title, author, points, comment count, target URL, discussion URL, domain and tags), attaches the highest-voted comments with author and timestamp, and adds optional AI add-ons for a story-plus-discussion summary and topic tags, so you get the full conversation, not just the headline.

**[Input](https://apify.com/scrapers_lat/hacker-news-scraper/input-schema) | [Output](https://apify.com/scrapers_lat/hacker-news-scraper/output-schema) | [Pricing](https://apify.com/scrapers_lat/hacker-news-scraper/pricing) | ▶️ [Examples](https://apify.com/scrapers_lat/hacker-news-scraper/examples)**

![Apify](https://img.shields.io/badge/Platform-Apify-1CE1CE?logo=apify\&logoColor=white)
![Coverage](https://img.shields.io/badge/Coverage-Worldwide-blue)
![Output](https://img.shields.io/badge/Output-JSON%20%7C%20CSV%20%7C%20Excel-orange)
![Billing](https://img.shields.io/badge/Billing-Pay%20per%20result-brightgreen)

### Table of contents

- [What it does](#what-it-does)
- [Quickstart](#quickstart)
- [Input reference](#input-reference)
- [Output reference](#output-reference)
- [Example output record](#example-output-record)
- [Run via API and CLI](#run-via-api-and-cli)
- [Fetch results](#fetch-results)
- [Billing and limits](#billing-and-limits)
- [FAQ and troubleshooting](#faq-and-troubleshooting)

### What it does

The actor searches Hacker News for your keyword (or lists the latest stories when no keyword is set), orders results by relevance or date, and writes one normalized record per story to the run's dataset. Each record carries the title, author, points, comment count, the story's target URL, its discussion URL, the domain and tags. With `includeComments` on, it attaches each story's highest-voted comments with author, text and timestamp. Missing source values are returned as `null`, never invented.

Two optional AI add-ons run only on paid Apify plans and only charge when they produce output: `aiSummary` summarizes the story and the main points in its discussion (comments are fetched automatically when enabled), and `aiTopics` tags the story with concise topic keywords.

### Quickstart

Open the actor, paste this into the input, and press Run. It searches Kubernetes stories with both AI add-ons.

```json
{
  "searchQuery": "kubernetes",
  "sortBy": "relevance",
  "maxStories": 10,
  "withAiSummary": true,
  "withAiTopics": true
}
```

Leave `searchQuery` empty for the latest stories, and set `includeComments` to `true` to attach the top discussion comments to every story.

### Input reference

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `searchQuery` | string | no | `artificial intelligence` | Keyword to search Hacker News stories, for example `startup`, `rust`. Leave empty for the latest stories. |
| `maxStories` | integer | no | `10` | Maximum stories to collect. |
| `sortBy` | enum | no | `relevance` | Order the stories. One of `relevance`, `date` (newest first). |
| `includeComments` | boolean | no | `false` | Also attach each story's highest-voted comments (author, text, timestamp). |
| `withAiSummary` | boolean | no | `false` | Paid add-on. AI summary of the story and its discussion. Comments are fetched automatically when on. Requires a paid plan. |
| `withAiTopics` | boolean | no | `false` | Paid add-on. AI topic and technology keyword tags. Requires a paid plan. |

### Output reference

One dataset item per story. Types: `string`, `number`, `string[]`, `object[]`, or `null` when the source value is absent.

| Field | Type | Description |
|---|---|---|
| `objectID` | string | Hacker News story ID (unique per story). |
| `title` | string | Story title. |
| `author` | string | Username of the story submitter. |
| `points` | number | Story score in points. |
| `numComments` | number | Total number of comments on the story. |
| `url` | string | Target URL the story links to, or `null` for text posts. |
| `storyUrl` | string | Hacker News discussion URL for the story. |
| `domain` | string | Domain of the target URL, or `null`. |
| `text` | string | Body text for Ask HN or text posts, or `null`. |
| `tags` | string\[] | Hacker News tags, for example `story`, `author_<name>`. |
| `createdAt` | string | ISO 8601 timestamp when the story was posted. |
| `topComments` | object\[] | Highest-voted comments (with `includeComments` or AI summary). Each has `author`, `text`, `points`, `createdAt`. Empty or absent otherwise. |
| `source` | string | Always `Hacker News`. |
| `aiSummary` | string | AI story-plus-discussion summary (add-on), else absent. |
| `aiTopics` | string\[] | AI topic and technology tags (add-on), else absent. |
| `observedAt` | string | ISO 8601 timestamp of when the record was collected. |
| `error` | string | `null` on success. On a failed run, a single item with a populated `error` field is written instead. |

### Example output record

Real record from a live run (input `{"searchQuery":"kubernetes","sortBy":"relevance","withAiSummary":true,"withAiTopics":true,"maxStories":3}`). `topComments` trimmed to two entries:

```json
{
  "objectID": "18428497",
  "title": "Google Kubernetes Engine's third consecutive day of service disruption",
  "author": "rlancer",
  "points": 779,
  "numComments": 407,
  "url": "https://status.cloud.google.com/incident/container-engine/18005",
  "storyUrl": "https://news.ycombinator.com/item?id=18428497",
  "domain": "status.cloud.google.com",
  "text": null,
  "tags": ["story", "author_rlancer", "story_18428497"],
  "createdAt": "2018-11-11T20:47:57Z",
  "topComments": [
    {"author": "rlancer", "text": "Status page is inaccurate ...", "points": null, "createdAt": "2018-11-11T20:53:35.000Z"},
    {"author": "base698", "text": "What operations? Status just shows node pool creation.", "points": null, "createdAt": "2018-11-11T21:17:17.000Z"}
  ],
  "source": "Hacker News",
  "aiSummary": "Google Kubernetes Engine (GKE) is experiencing its third consecutive day of service disruptions ... the overall sentiment is frustration.",
  "aiTopics": ["Google", "Kubernetes", "GKE", "Cloud Services", "Service Disruption", "DevOps"],
  "observedAt": "2026-08-14T08:22:14.856Z"
}
```

### Run via API and CLI

Start a run and wait for it to finish, then read the dataset. Replace `<TOKEN>` with your Apify API token.

Run synchronously and get dataset items in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~hacker-news-scraper/run-sync-get-dataset-items?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchQuery":"rust","sortBy":"date","maxStories":25,"includeComments":true}'
```

Start a run asynchronously:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~hacker-news-scraper/runs?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchQuery":"artificial intelligence","maxStories":100}'
```

Apify CLI:

```bash
apify call scrapers_lat/hacker-news-scraper \
  --input '{"searchQuery":"kubernetes","maxStories":50,"includeComments":true}'
```

### Fetch results

Every run writes to a dataset. Fetch items as JSON, CSV, or Excel by changing `format`:

```bash
## JSON
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"

## CSV
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"

## Paginate large datasets
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&offset=1000&limit=1000"
```

`<DATASET_ID>` is returned as `defaultDatasetId` in the run object. Use `offset` and `limit` to page through large result sets. `clean=true` drops empty and internal fields.

### Billing and limits

- **Pay per result.** You are charged per story returned (`result` event). See the [pricing tab](https://apify.com/scrapers_lat/hacker-news-scraper/pricing) for the current per-result price.
- **Add-ons.** The AI summary and AI topics add-ons are priced separately and charge only when they produce output.
- **No charge on failure.** If a run errors, the actor writes a single item with a populated `error` field and does not charge for it. Empty runs cost nothing.
- **Spend cap respected.** Set `maxTotalChargeUsd` on the run; once reached, the actor stops emitting and charging further billable results.
- **Free Apify plans** are capped at 10 stories per run. Upgrade for higher `maxStories`.

### FAQ and troubleshooting

**A run returned 0 stories. Why?**
The keyword matched nothing on Hacker News. Broaden the keyword or leave it empty for the latest stories. Zero-result runs are not charged.

**How do I get the newest stories instead of the most relevant?**
Set `sortBy` to `date`. Leave `searchQuery` empty to list the latest stories overall.

**Why is `topComments` empty?**
`includeComments` was off and no AI summary was requested. Turn on `includeComments`, or enable `withAiSummary` which fetches comments automatically.

**Why is `url` null?**
The story is a text post (for example Ask HN) with no external link. The body appears in `text` and the discussion is at `storyUrl`.

**Why did the AI fields not appear?**
The AI add-ons require a paid Apify plan and are off by default. Enable `withAiSummary` or `withAiTopics` on a paid plan. They charge only when output is produced.

**Is this an official Hacker News tool?**
No. This actor is independent and not affiliated with Hacker News or Y Combinator. It reads only publicly available stories and comments.

### Related scrapers

- [Reddit Posts Scraper](https://apify.com/scrapers_lat/reddit-posts-scraper): Posts from any subreddit.
- [Google News Scraper](https://apify.com/scrapers_lat/google-news-scraper): Articles and headlines from Google News.
- [Product Hunt Scraper](https://apify.com/scrapers_lat/product-hunt-scraper): Product launches from Product Hunt.
- [GitHub Repositories Scraper](https://apify.com/scrapers_lat/github-repositories-scraper): Repositories and metadata from GitHub.
- [Medium Scraper](https://apify.com/scrapers_lat/medium-scraper): Articles from Medium.

### More scrapers at scrapers.lat

Built and maintained by [scrapers.lat](https://scrapers.lat), where we publish scrapers for US and Latin American public platforms: company registries, government data, finance, e-commerce and more. Browse the catalog or request a custom scraper at [scrapers.lat](https://scrapers.lat).

***

> Independent tool, not affiliated with Hacker News or Y Combinator. Accesses only publicly available stories and comments.

# Actor input Schema

## `maxStories` (type: `integer`):

Maximum number of stories to collect.

## `searchQuery` (type: `string`):

Keyword to search Hacker News stories (for example 'artificial intelligence', 'startup', 'rust'). Leave empty for the latest stories.

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

Order the stories by relevance or by newest first.

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

Also attach each story's highest-voted discussion comments (author, text, points). Slower but gives you the full conversation, not just the headline.

## `withAiSummary` (type: `boolean`):

Optional paid AI add-on, off by default. Summarizes each story and the main points in its comments (comments are fetched automatically when enabled). Requires a paid Apify plan. Billed only when a summary is produced.

## `withAiTopics` (type: `boolean`):

Optional paid AI add-on, off by default. Tags each story with concise topic/technology keywords. Requires a paid Apify plan. Billed only when topics are produced.

## Actor input object example

```json
{
  "maxStories": 10,
  "searchQuery": "artificial intelligence",
  "sortBy": "relevance",
  "includeComments": false,
  "withAiSummary": false,
  "withAiTopics": false
}
```

# Actor output Schema

## `results` (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 = {
    "maxStories": 10,
    "searchQuery": "artificial intelligence"
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers_lat/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 = {
    "maxStories": 10,
    "searchQuery": "artificial intelligence",
}

# Run the Actor and wait for it to finish
run = client.actor("scrapers_lat/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 '{
  "maxStories": 10,
  "searchQuery": "artificial intelligence"
}' |
apify call scrapers_lat/hacker-news-scraper --silent --output-dataset

```

## MCP server setup

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