# Hacker News Watch — Keyword Mentions & Trend Monitor (`oneshotventure/hn-trends`) Actor

Scheduled change feed of new Hacker News stories matching keywords.

- **URL**: https://apify.com/oneshotventure/hn-trends.md
- **Developed by:** [Nick](https://apify.com/oneshotventure) (community)
- **Categories:** Agents, Developer tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 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.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Hacker News Monitor — Keyword Mentions & Trend Tracker

Track **new Hacker News stories matching your keywords**, with points and comment counts. Set a
minimum score to filter out noise, or leave keywords empty for the newest stories. Official Algolia
Hacker News Search API, watermarked so each run flags exactly what is new.

### What does this Actor do?

You give it keywords. It queries the official Algolia Hacker News search index — the same one that
powers HN's own search — once per keyword, sorted newest-first in the New feed or from the current
front page, merges the results, de-duplicates by story ID, applies your score and comment thresholds,
and emits what is left.

Two design choices matter. **Each keyword is a separate query**, and each emitted story records which
keyword caught it in `matchedKeyword` — so one scheduled run can drive several different alerts
without you having to re-derive why a story matched. And it keeps a **list of story IDs it has
already seen**, so `newSinceLastRun` tells you truthfully whether a story is new to you, even when a
story sits in the window across two consecutive runs.

The score threshold is the practical part. Hacker News posts hundreds of stories a day and most go
nowhere; `minPoints: 5` or `minComments: 3` turns a firehose into something a human will actually
read.

### Who is it for?

- **Founders and product teams** who want to know the moment their product is mentioned.
- **Developer-relations and marketing teams** tracking how a technology is being discussed.
- **Competitive analysts** watching a rival's launches and the comment threads about them.
- **Investors and scouts** monitoring Show HN for early-stage projects in a category.
- **AI agent builders** who want a tech-news tool with a stable output schema.

### Use cases

- Alert me when my product or company is mentioned on Hacker News.
- Track what HN says about a competitor, filtered to threads with real discussion.
- Find Show HN launches in my category and route them to a scouting channel.
- Monitor a technology keyword and post matches to Slack every morning.
- Watch the newest stories unfiltered as a raw front-page-adjacent feed.
- Give an agent a tool that answers "what is Hacker News saying about this right now?"

### What you get

One row per story. Any value the source does not publish is `null` — the field is always present, and
a trimmed copy of the source hit stays in `raw`.

| Field | Type | Description |
|---|---|---|
| `storyId` | string | Hacker News item ID — the unique key the seen-list tracks |
| `title` | string | Story title |
| `url` | string | The linked article URL. `null` for text posts such as Ask HN |
| `hnUrl` | string | Link to the Hacker News discussion thread |
| `points` | integer | Score at the time this row was fetched |
| `numComments` | integer | Comment count at the time this row was fetched |
| `author` | string | Submitter's HN username |
| `createdAt` | string | When the story was posted |
| `matchedKeyword` | string | Which of your keywords matched this story; `null` when running without keywords |
| `raw` | object | Trimmed copy of the source search hit |
| `newSinceLastRun` | boolean | `true` if this story ID had not been seen on an earlier successful run |
| `retrievedAt` | string | ISO 8601 timestamp of when this row was fetched |

#### Sample output record

```json
{
  "storyId": "41938201",
  "title": "Show HN: A self-hosted change feed for government data",
  "url": "https://example.com/blog/change-feeds",
  "hnUrl": "https://news.ycombinator.com/item?id=41938201",
  "points": 87,
  "numComments": 34,
  "author": "someuser",
  "createdAt": "2026-08-22T14:03:11.000Z",
  "matchedKeyword": "change feed",
  "raw": { "objectID": "41938201", "…": "…" },
  "newSinceLastRun": true,
  "retrievedAt": "2026-08-23T10:15:22.907Z"
}
```

### How to use it

#### Watch keywords with a noise filter

```json
{
  "keywords": ["AI agents"],
  "minPoints": 5,
  "maxResults": 25
}
```

#### Track several topics at once

Each keyword is queried separately and the matching keyword is recorded on every row.

```json
{
  "keywords": ["apify", "web scraping", "change feed"],
  "minComments": 3,
  "maxResults": 100
}
```

#### The newest stories, unfiltered

```json
{
  "maxResults": 100
}
```

#### Current front-page feed

```json
{
  "feed": "front_page",
  "minPoints": 10
}
```

### Input parameters

| Input | Type | Description |
|---|---|---|
| `keywords` | array | Terms, each searched separately. Empty fetches the newest stories without a query |
| `feed` | string | `new` (default) searches newest-first; `front_page` returns the current front page and ignores `postedSince` |
| `minPoints` | integer | Only return stories with at least this many points. Default: `0` |
| `minComments` | integer | Only return stories with at least this many comments. Default: `0` |
| `maxResults` | integer | Maximum records per run (1–1000). Default: `100` |
| `postedSince` | string | ISO date or timestamp. Overrides the previous successful run's watermark |

### How monitoring works (first run and scheduling)

The first run covers the **last seven days** unless `postedSince` is supplied. To keep the watermark
and the seen-story list across runs, **schedule this Actor as a saved Task** so runs share the same
storage — both live in the task's key-value store. A fresh unsaved run starts a fresh baseline.

**The dataset contains the window, not a strict delta.** A story can appear in two consecutive runs;
`newSinceLastRun` is `false` on the second. Filter on that flag downstream if you only want to alert
once per story.

### Honest limitations

- **Points and comment counts are a snapshot.** They are whatever the search index held at fetch
  time. A story fetched twenty minutes after posting shows a low score even if it later hits the front
  page — which is exactly why `minPoints` can hide a story that has not accumulated votes yet.
- **Each run emits the window, not a strict delta.** Use `newSinceLastRun` to alert once.
- **Keywords are queried separately, then merged.** Two keywords means two searches and a union of
  the results, not an AND across both terms.
- **Stories only — no comments.** This Actor returns story records. The text of comment threads is not
  retrieved; `hnUrl` links to the discussion.
- **`url` is `null` for text posts.** Ask HN and similar self-posts have no external link; use `hnUrl`.
- **Search relevance is Algolia's.** A keyword match is whatever the HN search index considers a
  match, which includes matches on the story text as well as the title.
- **Front page is a current feed, not history.** `feed: "front_page"` returns stories currently on
  the front page; it does not include rank or historical front-page membership.

### Reliability

Diagnostics are written to the `RUN_SUMMARY` key-value record — never into the dataset. A failed
upstream request leaves the watermark and the seen-story list unchanged, so a transient outage cannot
silently skip a window.

Every record carries `retrievedAt` and an `hnUrl` back to the thread, so you can check any row against
Hacker News yourself.

Maintained against the upstream API. If the search API changes its schema or an endpoint moves, report
it through the Issues tab and it gets fixed.

### Integrations

Connect this Actor to Make, Zapier, n8n, Slack, Google Sheets, Airtable or any HTTP endpoint through
Apify integrations. A scheduled Task can post every new mention of your product into a Slack channel,
or fire a webhook so a summarization job runs the moment a thread takes off. Datasets export as JSON,
CSV, Excel, XML, RSS or HTML.

### API usage

```bash
curl -X POST "https://api.apify.com/v2/acts/oneshotventure~hn-trends/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"keywords": ["AI agents"], "minPoints": 5, "maxResults": 25}'
```

Python, JavaScript, PHP and CLI clients are documented under
[Apify API clients](https://docs.apify.com/api/client).

### Use with AI agents (MCP)

This Actor is callable from any MCP-compatible client — Claude, Cursor, VS Code or your own agent —
through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp). The input schema is
fully described and every record uses one stable, flat JSON shape, so an agent can call it and read
the result without a parsing step. Because it reads the official Hacker News search API rather than a
rendered page, the answer an agent gets is the same one the source publishes — and `url` plus `hnUrl`
give the agent both the article and the discussion to fetch.

### Frequently asked questions

#### Is there a Hacker News API?

Yes — Hacker News search is powered by a public Algolia index that anyone can query without a key.
This Actor is the scheduling, multi-keyword and change-feed layer over it.

#### How do I get alerts when my startup is mentioned on HN?

Put your company and product names in `keywords`, save the Actor as a Task, schedule it hourly or
daily, and connect the Task to Slack or a webhook. Set `minPoints: 0` so you catch mentions before
they accumulate votes.

#### How do I monitor Show HN posts?

Add `Show HN` to `keywords`, optionally alongside your category terms. Each row records which keyword
matched in `matchedKeyword`.

#### Can I send HN mentions to Slack?

Yes — connect the scheduled Task to Slack through Apify integrations, and filter on
`newSinceLastRun` so each story is announced only once.

#### Why does a story show fewer points than I see on the site?

Because `points` is a snapshot from when the row was fetched. Scores climb after posting; re-running
later returns an updated count for the same story ID.

#### Does it return comments?

No, only story records. `hnUrl` links to the discussion thread if you want to read or fetch it
separately.

#### Why did the same story appear twice?

The window is inclusive of its start, so a story can fall into two consecutive runs. The second
appearance carries `newSinceLastRun: false`.

### Related actors

- [App Store Review Monitor](https://apify.com/oneshotventure/app-review-watch) — new iOS reviews for
  your app or a competitor's.
- [SEC EDGAR Filings Monitor](https://apify.com/oneshotventure/sec-filings) — new company filings from
  EDGAR.
- [US Building Permits API](https://apify.com/oneshotventure/permits-search) — recently issued
  building permits across 10 US cities.

### Disclaimer

This independent tool uses the public Algolia Hacker News Search API and is not affiliated with Y
Combinator, Hacker News, or Algolia.

# Actor input Schema

## `keywords` (type: `array`):

Terms to search separately. Empty fetches the newest stories without a query.

## `feed` (type: `string`):

New searches newest-first. Front page returns the current Hacker News front page and ignores Posted since.

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

Only return stories with at least this many points.

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

Only return stories with at least this many comments.

## `maxResults` (type: `integer`):

Maximum records per run (1-1000).

## `postedSince` (type: `string`):

ISO date or timestamp. Overrides the previous successful-run watermark.

## Actor input object example

```json
{
  "keywords": [
    "AI agents"
  ],
  "feed": "new",
  "minPoints": 0,
  "minComments": 0,
  "maxResults": 25
}
```

# Actor output Schema

## `records` (type: `string`):

Matching Hacker News stories in the default dataset.

## `runSummary` (type: `string`):

Run diagnostics stored as RUN\_SUMMARY in the key-value store.

# 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 = {
    "keywords": [
        "AI agents"
    ],
    "maxResults": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("oneshotventure/hn-trends").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 = {
    "keywords": ["AI agents"],
    "maxResults": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("oneshotventure/hn-trends").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 '{
  "keywords": [
    "AI agents"
  ],
  "maxResults": 25
}' |
apify call oneshotventure/hn-trends --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,oneshotventure/hn-trends"
        }
    }
}
```

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/pilqqxLIKeNdKgMkU/builds/4nXamJQ3d1Fu4CMUe/openapi.json
