Hacker News Search — Stories, Comments & Live Front Page avatar

Hacker News Search — Stories, Comments & Live Front Page

Pricing

from $0.35 / 1,000 result items

Go to Apify Store
Hacker News Search — Stories, Comments & Live Front Page

Hacker News Search — Stories, Comments & Live Front Page

Search all of Hacker News (stories, comments, Ask/Show/Launch HN, polls, jobs) by keyword with points, comments, date, author, domain and story filters, or pull the live top/new/best/ask/show/jobs lists. Optional nested comment trees and author profiles.

Pricing

from $0.35 / 1,000 result items

Rating

0.0

(0)

Developer

Samat Makatov

Samat Makatov

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

10 days ago

Last modified

Share

Search all of Hacker News since 2006 — stories, comments, Ask HN, Show HN, Launch HN, polls, job posts — by keyword with points / comments / date / author / domain filters, or pull the live top / new / best / ask / show / jobs lists exactly as the HN pages rank them. Optionally attach each story's discussion as a nested comment tree and the author's profile (karma, account age). Built for AI agents, brand monitors and researchers: clean JSON with plain-text bodies. No API key, no proxy, no browser.

Use cases

  • Brand & competitor monitoring — every story and comment mentioning your product (or a competitor) in the last N days, with points and discussion threads, on a schedule.
  • Launch research — pull all Show HN / Launch HN posts on a topic, sorted by points, to see what resonated and how people reacted (comments included).
  • Content & PR intelligence — which stories from a domain (arxiv.org, github.com, your blog) hit HN, when, and how big they got.
  • Expert & community research — find the most informed discussions about a technology; author profiles (karma, account age) help weigh how established a voice is.
  • Trend tracking for agents — a daily snapshot of the live front page / best list with a points floor, deduped by URL, trimmed to the fields you need.
  • Hiring signals — YC job posts (kind: job, searchable history, or live jobs) filtered by stack keywords.

Personal data. Usernames, author profiles and comment texts are personal data under the GDPR and similar laws, public or not. Collect only what your purpose needs, keep it briefly, and do not build contact or lead lists from it. includeAuthorProfile is off by default.

Input

FieldTypeDefaultNotes / allowed values
querystring—Keywords. Algolia syntax: "exact phrase", -excluded. Empty = list by date with the filters only.
queriesstring[][]Extra queries processed in the same run (batch monitoring). Each item carries its query. maxItems is the total.
kindenumstorySearch (Algolia): story, comment, ask_hn, show_hn, launch_hn, poll, job, front_page, newest, any. Live lists (Firebase): top, new, best, ask, show, jobs. See reference.
sortenumrelevancerelevance (text match → points → comments; falls back to date when there is no query or kind is newest), date (newest first), points, comments. Points/comments are sorted client-side: the actor fetches the whole reachable pool (up to 1,000 hits, 5 requests) and returns the top maxItems.
searchInenumallall, title, url, text, title_text, author → Algolia restrictSearchableAttributes. all also matches story text, URLs and (for kind: comment/any) comment text — right for mention monitoring, noisy for topic lists: use title for "stories about X".
typoToleranceboolfalseLet Algolia match misspellings. Off by default because it turns short terms into noise ("LLM" → "Limbo", "Limits", "GLM"; "Kafka" → "Kakapos"); turn on to also catch misspelled mentions.
minPointsint0Algolia numeric filter points>=. Ignored for comments (they have no points).
minCommentsint0Algolia numeric filter num_comments>=.
sinceDaysint0Last N days; 0 = all time. Overridden by dateFrom.
dateFrom / dateTodate—YYYY-MM-DD or ISO 8601 UTC, inclusive.
authorstring—Bare username (pg) → tag author_pg.
storyIdstring—Restrict to one thread → tag story_<id> (use with kind: comment).
domainstring—Keep items whose URL is on this domain or a subdomain (client-side). With an empty query it becomes the URL query, so "all submissions of a site" is one call.
maxItemsint501–5000, total across queries. Algolia serves at most 1000 hits per query; live lists hold 200–500 ids. Legacy alias limit still works.
includeCommentsboolfalseAttach nested comments per story (1 extra request per story that has comments).
maxCommentsPerStoryint201–500, breadth-first (top-level replies first).
commentsDepthint21–10 reply levels.
includeAuthorProfileboolfalseAttach authorProfile (karma, createdAt, about, submittedCount) — 1 request per distinct author, cached in the run.
textMaxLengthint2000100–50000 chars for text and comment texts.
dedupeByUrlboolfalseOne item per external URL (scheme/www/trailing slash ignored).
fieldsstring[][]Output fields, in this order; id is always kept (first, unless you list it elsewhere). Names are read ignoring case, spaces and _ (num_comments = numComments, score = points); an unknown name is left out and named in the status, and a list with no known field fails the run.

Filters are ANDed. Live Firebase kinds ignore query, author, storyId, dates and searchIn (they are not searchable) and apply minPoints / minComments / domain client-side — the run's status message names every input it ignored.

Reference

kind values

kindSourceWhat you getFilters
storyAlgolia tag storyStories (link + text posts), all timeall
commentAlgolia tag commentComments with parent story contextall except minPoints/minComments
ask_hn / show_hn / launch_hnAlgolia tagsAsk HN / Show HN / Launch HN (YC launches) postsall
pollAlgolia tag pollPolls (options are type pollopt)all
jobAlgolia tag jobYC job-board posts, full historyall
front_pageAlgolia tag front_page~30 stories currently on the front pageall
newestAlgolia search_by_date, tag storyAlias for story + sort: dateall
anyAlgolia, no type tagStories, comments, polls, jobs togetherall
topFirebase topstoriesLive HN front page ranking, up to 500minPoints, minComments, domain
newFirebase newstoriesLive newest, up to 500same
bestFirebase beststoriesLive "best" ranking, up to 200same
ask / show / jobsFirebase askstories / showstories / jobstoriesLive Ask HN / Show HN / jobs listssame

Algolia tags used under the hood (tags output field)

story, comment, poll, pollopt, job, show_hn, ask_hn, launch_hn, front_page, author_<username>, story_<id>. Tags are ANDed with commas; the actor builds them from kind, author and storyId.

Algolia numeric filters

points, num_comments, created_at_i (unix seconds) with <, <=, =, >=, >; built from minPoints, minComments, sinceDays / dateFrom / dateTo.

searchIn → restrictSearchableAttributes

searchInattributes
alltitle, url, story_text, comment_text, author (Algolia default)
titletitle
urlurl
textcomment_text, story_text
title_texttitle, story_text, comment_text
authorauthor

Topic vs mention searches. The default searchIn: "all" finds every item where the word appears anywhere — including self-post text and URLs — which is what brand monitoring needs (kind: "any" adds comments). For "the best stories about X" lists, set searchIn: "title": e.g. LLM stories of one week sorted by points returned 191 hits with all (among them a post about migrating prompts to Ollama and a "Pelican-bicycle alternatives" Show HN that mention LLMs only in their text) vs 140 with title, all with LLM in the headline.

Examples

Brand monitoring, last 30 days, stories with traction plus their discussion

{ "queries": ["apify", "crawlee"], "kind": "story", "sinceDays": 30, "minPoints": 5, "sort": "points", "includeComments": true, "maxCommentsPerStory": 10, "commentsDepth": 2, "maxItems": 100 }

What did people say about a topic? (comments, newest first)

{ "query": "\"vector database\"", "kind": "comment", "sinceDays": 90, "sort": "date", "maxItems": 200 }

All Show HN launches about a category, ranked by points, with founder profiles

{ "query": "MCP server", "kind": "show_hn", "dateFrom": "2026-01-01", "sort": "points", "includeAuthorProfile": true, "maxItems": 50 }

Every HN hit from a domain this quarter (PR report)

{ "domain": "arxiv.org", "dateFrom": "2026-07-01", "dateTo": "2026-09-30", "minPoints": 50, "sort": "points", "dedupeByUrl": true, "maxItems": 300 }

Daily snapshot of the live top list, compact fields

{ "kind": "top", "minPoints": 100, "maxItems": 30, "fields": ["title", "url", "domain", "points", "numComments", "createdAt", "hnUrl"] }

Whole thread of one story as flat comments (searchable)

{ "kind": "comment", "storyId": "4058874", "query": "scraping", "maxItems": 100 }

Output

One dataset item per story / comment. Example (trimmed):

{
"id": "46513489",
"type": "story",
"kind": "story",
"query": "apify",
"title": "Show HN: mcpc – Universal command-line client for Model Context Protocol",
"url": "https://github.com/apify/mcpc",
"domain": "github.com",
"hnUrl": "https://news.ycombinator.com/item?id=46513489",
"points": 50,
"numComments": 5,
"author": "jancurn",
"createdAt": "2026-01-06T14:03:11Z",
"text": null,
"storyId": "46513489",
"storyTitle": null,
"storyUrl": null,
"parentId": null,
"tags": ["story", "author_jancurn", "story_46513489", "show_hn"],
"comments": [
{ "id": "46513822", "author": "stinny", "createdAt": "2026-01-06T15:29:16.000Z", "text": "Pretty sweet tool…", "hnUrl": "https://news.ycombinator.com/item?id=46513822",
"children": [ { "id": "46514078", "author": "jancurn", "text": "Thank you! …", "children": [] } ] }
],
"authorProfile": { "username": "jancurn", "karma": 748, "createdAt": "2011-10-31T16:07:06.000Z", "about": "Jan Čurn — Founder & CEO @ Apify …", "submittedCount": 121, "hnUrl": "https://news.ycombinator.com/user?id=jancurn" },
"source": "algolia",
"sourceUrl": "https://hn.algolia.com/api/v1/search?query=apify&tags=story&numericFilters=points%3E%3D5%2Ccreated_at_i%3E%3D…&hitsPerPage=100&page=0",
"fetchedAt": "2026-09-12T23:32:10.512Z"
}
FieldTypeMeaning
idstringHN item id (stable; hnUrl = news.ycombinator.com/item?id=<id>)
typestringstory, comment, poll, pollopt, job
kind, querystringInput that produced the item (query null for live lists)
title, url, domainstring|nullSubmission title, external URL, hostname without www.
points, numCommentsint|nullScore and comment count (comments: points null)
author, createdAtstringUsername, ISO 8601 UTC
textstring|nullStory/comment body as plain text: HTML stripped, entities decoded, paragraphs kept, links as label (href), truncated to textMaxLength
storyId, storyTitle, storyUrl, parentIdstring|nullThread context (for stories storyId = id; the rest only on comments)
tagsstring[]Algolia tags (see reference)
commentsarrayOnly with includeComments: nested {id, author, createdAt, text, hnUrl, children[]}; [] when there are none or the tree could not be loaded (counted in the status)
authorProfileobject|nullOnly with includeAuthorProfile: {username, karma, createdAt, about, submittedCount, hnUrl}; null when unknown or not loadable (counted in the status)
source, sourceUrlstringalgolia or firebase and the exact API request
fetchedAtstringFetch timestamp

With fields, each item holds id plus the listed fields in your order. Dataset views: Overview (stories) and Comments.

Every run ends with one status line: how many items were saved, then every note — inputs that were ignored or read differently, failed queries, comment trees or profiles that could not be loaded, the 1,000-hit cap. The SUMMARY record in the run's key-value store has the same notes plus per-query counts and the ids behind each failure.

Use it from code / agents

curl (Apify API, run synchronously and get the dataset):

curl -X POST "https://api.apify.com/v2/acts/yadroo~hackernews-search/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H 'content-type: application/json' \
-d '{"query":"apify","kind":"story","sinceDays":30,"minPoints":5,"maxItems":50}'

JavaScript (apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('yadroo/hackernews-search').call({ query: 'apify', kind: 'story', sinceDays: 30, minPoints: 5, includeComments: true });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Python (apify-client):

from apify_client import ApifyClient
client = ApifyClient(token)
run = client.actor("yadroo/hackernews-search").call(run_input={"kind": "top", "minPoints": 100, "maxItems": 30})
items = client.dataset(run["defaultDatasetId"]).list_items().items

MCP: add https://mcp.apify.com to your agent (Claude, Cursor, custom) and call the tool yadroo/hackernews-search with the same JSON input.

Pricing

Pay per event: $0.001 per run start + $0.0005 per item (story or comment; nested comments and authorProfile are part of the item, not billed separately). Store discounts: Bronze −10 %, Silver −20 %, Gold and above −30 % on the item price; the start event is the same on every plan; platform usage is included.

Spending limit. A run never charges past your Maximum cost per run: it stops there and ends with "Stopped at your spending limit: N rows delivered". Comment trees and profiles are fetched only for items the limit still pays for.

Typical runs: a 30-day brand check with 40 hits ≈ $0.021; a 500-item topic export ≈ $0.251; a daily top-30 snapshot ≈ $0.016.

Limits & FAQ

  • Rate limits. HN Algolia allows about 10,000 requests per hour per IP and blocks IPs that go over. A search page is one request for up to 200 hits (with a short pause between pages), but includeComments adds one request per story with comments: a 5,000-item run with comments uses about half of that hourly allowance. The actor retries 429/5xx with backoff and waits as long as a Retry-After header asks, within the run's time. The official Firebase API has no published limit; live-list items are fetched 8 at a time.
  • 1000-hit cap. Algolia refuses to page past 1000 hits for one query. The actor caps per query and names the cap in the status with the true match count — split by dateFrom/dateTo windows or several queries to go deeper.
  • Freshness. Algolia indexes new items within minutes; points/comment counts are updated periodically, so very fresh stories may show lower numbers than the live site. Live top/new/best/ask/show/jobs kinds read the official API in real time.
  • Sorting by points/comments is done client-side: up to 1,000 matching hits are fetched per query and the top maxItems returned. Algolia never serves more than 1,000 hits, so for a global "top of all time" on a broad query narrow with minPoints or a date range.
  • Search precision. Matching is word-based with prefix and plural matching (LLM finds "LLMs"); typo matching is off unless typoTolerance: true. searchIn: "all" (default) matches text and URLs too — see the note under Reference for topic lists.
  • Comments and points. HN does not expose comment scores; points is null for comments and minPoints is ignored for kind: comment.
  • Errors. kind, sort and searchIn take only the listed values: Apify refuses anything else before the run starts (HTTP 400, nothing charged). Bad dates, dateFrom after dateTo or a fields list with no known field fail the run at once with a message naming the field, before any request. A failed query is named in the status and the other queries still run; failed comment trees and profiles leave comments: [] / authorProfile: null on those items and are counted in the status and SUMMARY. If every request failed and nothing was saved, the run fails with the source's error.
  • Run timeout. Items are saved page by page. Near the run timeout the actor stops starting new requests and ends SUCCEEDED with "Stopped before the run timeout: N rows saved"; raise the timeout or split the job for more.
  • Deleted / dead items are skipped; deleted comments are dropped from comments.
  • Roadmap. Poll options (pollopt) inline with polls; user-submission listing (author + empty query already covers most of it).

Sources: HN Search API by Algolia, official Hacker News API. Content belongs to its authors / Y Combinator.


Made by Yadroo — more data actors for agents: stackexchange-search · github-repo-intel · google-news-search · rss-to-json · crypto-news