# Hacker News Scraper (`dami_studio/hacker-news-scraper`) Actor

Hacker News scraper for stories, Show HN, Ask HN and comments, or the live front page. Each row has the title, link, author, points, comment count, the text and the HN thread link. Filter by minimum points or comments. No account. $1.00 per 1,000 items.

- **URL**: https://apify.com/dami_studio/hacker-news-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** News, Developer tools, Integrations
- **Features:** Limited permissions
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.97 / 1,000 items

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 for stories, Show HN, Ask HN and comments**: type a query, pick what kind of item
you want, and the matches come back as rows with points, author, comment count, the story's own link
and the HN thread link. Or pull whatever is sitting on the front page right now. No account, no API
key.

One thing to know before the first run. The search box on the input form starts out filled in with
`openai`, and the query is applied to the front page as well. Leave it there with **Front page**
selected and you get the few front-page items that mention OpenAI, not the front page.

| | |
|---|---|
| **Input** | A search query and an item type |
| **Output** | One row per story, post or comment: title, link, author, points, comment count, text, thread link |
| **Ceiling** | 1,000 items per run |
| **Account needed** | None, and no API key |
| **Price** | $1.00 per 1,000 items on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 5,000 |

### 🔍 What Hacker News Scraper does

Pick the item type and you get stories, Show HN posts, Ask HN posts, comments, or the current front
page. Leave the query empty and you get the newest items of that type instead of a keyword search.
Sort by relevance or by date. Set a minimum score, or a minimum number of comments, to drop the
quiet stories before they reach your dataset.

It pages through results 50 at a time until it has what you asked for or the results run out. Items
that appear on two pages are dropped once, so the same story cannot land twice in one run.

There is nothing to sign up for and no quota to watch.

### 📋 What data you get from each Hacker News item

| What you get | Field |
|---|---|
| The item's id and what kind of item it is | `objectId`, `type` |
| The title and the link it points to | `title`, `url` |
| Who posted it and when | `author`, `createdAt` |
| Points and comment count | `points`, `numComments` |
| The post or comment body, as plain text | `text` |
| The thread on news.ycombinator.com | `hnUrl` |

### ▶️ How to scrape Hacker News

1. Open [Hacker News Scraper](https://apify.com/dami_studio/hacker-news-scraper) and click
   **Try for free**.
2. Type your keywords into **Search query**, or clear the box to get the newest items instead.
3. Pick an **Item type**. Stories is the default, comments is the one you want for mention tracking.
4. Set **Max items**. Start around 20 to see the shape of the output, then click **Start**.
5. Download the dataset as JSON, CSV or Excel, or read it from the Apify API.

### 💰 How much does it cost to scrape Hacker News?

**$1.00 per 1,000 items** on the Free plan. Paid plans pay a little less: $0.99 on Starter, $0.98 on Scale and $0.97 on Business. On the free plan, the $5 Apify
gives you each month covers about 5,000 items.

You pay per row delivered, so `maxItems` is your budget dial and the default of 50 is deliberately
small. Items dropped by `minPoints` or `minComments`, duplicates removed inside a run, and diagnostic
rows are not charged. A query that matches nothing writes one diagnostic row and costs you nothing.

### 📥 What you give it

```json
{
  "query": "rust async",
  "tags": "story",
  "sortBy": "date",
  "minPoints": 50,
  "maxItems": 200
}
```

| Field | Default | What it is |
|---|---|---|
| `query` | none | Keywords. The form starts with `openai` in the box so it runs out of the box, but the API sends nothing unless you set it. Empty means the newest items for the type you picked. |
| `tags` | `story` | `story`, `show_hn`, `ask_hn`, `comment` or `front_page`. |
| `sortBy` | `relevance` | `relevance` for best match, `date` for newest first. |
| `minPoints` | none | Only items with at least this many points. Applied before the row reaches you, so filtered items are not billed. |
| `minComments` | none | Only items with at least this many comments, applied the same way. Refused with the `comment` type, because a comment has no comment count of its own. |
| `maxItems` | `50` | 1 to 1,000 per run. This is the dial that sets what a run costs. |
| `notionConnector` | none | Optional. Write every item into Notion as a page when the run finishes. Authorize the connector once under Settings, API and Integrations, MCP connectors, then pick it here. |
| `notionParentId` | none | Optional. The Notion data source to write into. Empty creates the pages privately in your workspace. |
| `proxyConfiguration` | off | Optional and not needed for a normal run. |

### 📤 What you get back

A real row from a recent run:

```json
{
  "ok": true,
  "objectId": "38309611",
  "type": "story",
  "title": "OpenAI's board has fired Sam Altman",
  "url": "https://openai.com/blog/openai-announces-leadership-transition",
  "author": "davidbarker",
  "points": 5710,
  "numComments": 2530,
  "createdAt": "2023-11-17T20:28:50Z",
  "text": "",
  "hnUrl": "https://news.ycombinator.com/item?id=38309611"
}
```

| Field | How to read it |
|---|---|
| `objectId` | The item's Hacker News id, as a string. Stable, so use it as your dedupe key across runs. |
| `type` | `story`, `show_hn`, `ask_hn`, `poll` or `comment`. |
| `title`, `url` | The item's own on a story. On a comment row both belong to the parent story. `url` is `null` on a text post that links nowhere. |
| `text` | The post or comment body with the HTML stripped out. Empty string on a plain link story, the post body on an Ask HN. |
| `points`, `numComments` | Often `null` on comment rows. |
| `createdAt` | When the item was posted, in UTC. |
| `hnUrl` | The thread on news.ycombinator.com, built from `objectId`. |

### 🧾 Reading the output

Data rows carry `ok: true`. When something goes wrong, or a search matches nothing, you get one row
with `ok: false` and an `errorCode` instead of an empty dataset, and that row is not charged.

| Code | What it means |
|---|---|
| `NO_RESULTS` | The search matched nothing. Check the spelling, or widen it by clearing `minPoints` or `minComments`. |
| `BAD_INPUT` | The input asks for something the search cannot do, like a comment minimum on comments. Nothing was searched; the row's `note` says what to change. |
| `RATE_LIMITED` | Too many requests in a short window. Wait a little and run it again. |
| `NOT_SERVED` | This request was not served this run. Re-run it later. Runs before 13 October 2026 wrote `BLOCKED` here, and runs from 13 to 17 October wrote `NETWORK`. |
| `NOT_FOUND` | The address the run asked for came back missing. |
| `SERVER_ERROR` | The search answered with an error of its own. |
| `NETWORK` | The search was unreachable or answered badly. Re-run it. |
| `TIME_LIMIT` | The run stopped just before its time limit. The items written before it are yours and charged; give the run more time to get the rest. The run still ends as succeeded, with an amber status message, even when the time limit stopped it before any item came back. |
| `UNEXPECTED_ERROR` | The run stopped early on an unexpected error. The results before this row are kept. |

One more thing about the Console's **overview** table: it shows title, author, points, comments and
the two links, and it has no column for `text`. So a comments run looks odd there, every row showing
its parent story's title with no comment body. Switch to all fields, or export the JSON, and the
text is there.

### 💡 What people use it for

- Mention tracking. Put your product name in the query, set the type to comments, sort by date and
  run it every few hours, deduping on `objectId`. Threads move fast and hearing about yours from a
  customer is worse.
- A feed of new launches: Show HN, sorted by date, no query needed.
- The monthly "Who is hiring" lists. Those are comments under a post rather than the post itself, so
  search `hiring` with the type set to comments.
- A front-page digest on a schedule, with the query box cleared.
- Checking how a topic has been received over the years, sorted by points.

### 🚧 What it does not do

- **1,000 rows per run.** Split a bigger job across several queries or date ranges.
- **No full threads.** You get the comments that match your search, not every reply under a story.
- **No user profiles**, no karma totals, no submission history for a person.
- **The front page is filtered by your query too.** For a plain digest, clear the query.
- **A minimum score does nothing useful on comments.** Comment rows carry no score, so a run with
  both usually comes back with nothing at all. A minimum number of comments is refused on comments
  outright, for the same reason.
- **Scores are a snapshot.** A story read an hour after it was posted has the points it had then.
- **No comment counts on comments.** Those fields are for stories.
- **Relevance ordering is not something this actor can change.**
- It is not an official Hacker News tool. Dami's Studio is independent and is not affiliated with or endorsed by Hacker News or Y Combinator, or by any other company named on this page.

### 🧭 Which developer scraper do you need?

| If you want | Use |
|---|---|
| Articles from DEV.to by tag or author, with the full text on request | [DEV.to Scraper](https://apify.com/dami_studio/devto-scraper) |
| Hacker News stories, Ask and Show HN posts, and comments | This one |
| Stack Overflow questions with the body and the accepted answer | [Stack Overflow Scraper](https://apify.com/dami_studio/stackexchange-scraper) |
| Repositories and developer profiles from a GitHub search | [GitHub Scraper](https://apify.com/dami_studio/github-scraper) |
| npm and PyPI package details and download counts | [npm + PyPI Package Scraper](https://apify.com/dami_studio/package-registry-scraper) |
| Product launches and their upvotes | [Product Hunt Scraper](https://apify.com/dami_studio/producthunt-scraper) |
| Posts from a Substack publication | [Substack Publication Scraper](https://apify.com/dami_studio/substack-publication-scraper) |

### ❓ Questions people ask

#### Do I need a Hacker News account or an API key?

Neither. Nothing to apply for.

#### What happens when my Hacker News search matches nothing?

You get one row with `ok: false` and `errorCode: NO_RESULTS`, and you are not charged for it.

#### Why did my front-page run come back nearly empty?

The query is applied to the front page as well, and the form starts with `openai` in the box. Clear
it.

#### Can I pull a whole Hacker News comment thread?

No. Search returns matching comments, not the tree under a story. The `hnUrl` on each row opens the
thread if you want to read it.

#### Can I call it from code or connect it to an AI assistant?

The [API tab](https://apify.com/dami_studio/hacker-news-scraper/api/python) has code for Python, JavaScript and the
CLI. MCP clients like Claude and ChatGPT use
`https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/hacker-news-scraper`; coding assistants can load [our
skill file](https://api.apify.com/v2/key-value-stores/BTBHU3DdiuoF4JOsK/records/apify-social-communities-SKILL.md).
All three bill your Apify account at the same price.

#### Is it legal to scrape Hacker News?

These are public posts on a public site. Usernames are personal data under GDPR and similar laws
when they point to a person, so have a reason for collecting them. Apify's write-up on
[the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) is a good starting
point, and we are not lawyers.

### 🆘 If something breaks

Open the **Issues** tab on the actor page. Send the query you used and the run ID. The `errorCode`
on the diagnostic row usually names the problem on its own.

# Actor input Schema

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

Keywords to search Hacker News for (e.g. "openai", "rust async"). Leave empty to get the newest/front-page items for the chosen tag.

## `tags` (type: `string`):

Which kind of Hacker News items to return: stories, Show HN, Ask HN, comments, or current front page.

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

Order results by relevance (best match) or by date (newest first).

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

Only return items with at least this many points (upvotes). Leave empty for no minimum. Applies mainly to stories.

## `minComments` (type: `integer`):

Only return items with at least this many comments. Leave empty for no minimum. Not for the Comments item type: a comment has no comment count of its own, so that pair is refused before anything is searched.

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

Maximum number of items to return. The actor paginates the API until it has this many (or runs out).

## `notionConnector` (type: `string`):

Optional. Write each item as a page into your Notion when the run finishes. Authorize a Notion connector once in Settings → API & Integrations → MCP connectors, then pick it here. Leave empty to skip (default), results are always saved to the dataset regardless.

## `notionParentId` (type: `string`):

Optional. The Notion data source ID of the database to write into (only used if a Notion connector is set). Leave empty to create the pages privately in your workspace instead.

## `proxyConfiguration` (type: `object`):

Optional, and not needed for a normal run.

## Actor input object example

```json
{
  "query": "openai",
  "tags": "story",
  "sortBy": "relevance",
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Scraped rows are stored in the default dataset (one row per result). Empty or failed runs return a single uncharged diagnostic row instead.

# 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 = {
    "query": "openai"
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/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 = { "query": "openai" }

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/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 '{
  "query": "openai"
}' |
apify call dami_studio/hacker-news-scraper --silent --output-dataset

```

## MCP server setup

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