Hacker News Search & Comments API
Pricing
$1.50 / 1,000 results
Hacker News Search & Comments API
Search Hacker News stories and comments, or retrieve the front page with bounded discussion expansion. Public APIs only.
Pricing
$1.50 / 1,000 results
Rating
0.0
(0)
Developer
Atesen Software
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Security
Limited permissionsShare
Hacker News Search & Comments API
Search Hacker News stories or comments by text, date and story score, or retrieve the current front page. Optional bounded comment expansion keeps parent and story context in flat rows. Uses the public Algolia HN Search and official Firebase HN APIs. No login, API key, browser, proxy or paid upstream API is needed.
Useful for developer trend monitoring, research datasets, mention tracking and sampling discussions. This is a point-in-time fetcher, not an exhaustive archive or continuous monitor.
Quick start
The default input returns at most 3 stories, without comments. For search:
{"mode": "query","query": "sqlite","itemType": "story","sort": "relevance","minScore": 20,"maxResults": 20,"maxPages": 3,"maxRequests": 30}
For the current front page with a bounded discussion sample:
{"mode": "frontpage","maxResults": 15,"includeComments": true,"maxCommentsPerStory": 2,"maxCommentDepth": 1,"maxRequests": 30}
For comment search, set itemType to comment, leave minScore at zero and includeComments false. Algolia returns available parent ID, story ID and story title directly; the actor does not fetch linked external articles or resolve missing search context.
Filters and bounds
| Input | Default | Behavior |
|---|---|---|
mode | query | query searches Algolia; frontpage loads Firebase topstories in ranked order. |
query | empty | Up to 500 characters. Empty search text lists records by the chosen order. Frontpage requires empty text. |
itemType | story | story or comment; frontpage requires story. Jobs, polls, dead and deleted items are excluded. |
sort | date | date or relevance for query mode. Frontpage uses upstream ranking. |
fromDate, toDate | unset | Inclusive UTC ISO timestamps, e.g. 2026-01-01T00:00:00Z. Applied to data rows, including expanded comments. |
minScore | 0 | Story score threshold, 0–100000. Comment scores are not public; comment search requires zero. |
maxResults | 3 | Hard combined story/comment row limit, 1–1000. Status row is additional. |
maxPages | 5 | Query page ceiling, 1–20. Algolia can impose a smaller result window. |
pageSize | 50 | Query records per page, 1–100. |
maxRequests | 200 | Shared hard HTTP attempt ceiling, 1–500, including retries and comment/story lookups. |
includeComments | false | Expand matching stories with Firebase replies. |
maxCommentsPerStory | 5 | Maximum comment IDs visited per story, 0–100, including missing/deleted/filtered entries. This can produce fewer rows. |
maxCommentDepth | 2 | Breadth-first expansion, 1–5. Top-level replies have depth 1. |
requestDelayMs | 200 | Sequential request spacing, 100–5000 ms. |
timeoutSecs | 15 | Per-attempt timeout including body read, 1–60 s. |
There are at most two retries (three attempts total) for network errors, HTTP 429 and 5xx. Access denial is not retried. Response bodies are capped at 2 MB. Every attempt counts toward maxRequests, including retries. Frontpage scans at most the 500 upstream top IDs; filtering can exhaust the request budget before enough matches are found.
Comment expansion happens immediately after each emitted story. Comments share the global result limit, so requesting three results with expansion can produce one story and two comments. Set the result and request limits accordingly. Nested replies preserve parentId, storyId, storyTitle, storyUrl and depth; direct comment search has depth=null because no tree is traversed.
Output
The default dataset contains flat records:
recordType:story,comment, or finalstatus.id,title,textHtml,author,createdAt(UTC),timestamp(Unix seconds).score(stories only),commentCount(when provided),url(external story link, never fetched),hnUrl.parentId,storyId,storyTitle,storyUrl,depth.source(algoliaorfirebase),apiUrl,fetchedAt.
Missing fields are null. Source HTML is stored unchanged as inert text; downstream applications must sanitize before rendering it. Link fields accept only HTTP(S). The actor never executes returned HTML or requests article URLs.
The final status row and SUMMARY key-value record include status, message, partial, resultCount and requests. Status values include completed, result_limit, page_limit, charge_limit, request_limit, invalid_input, access_denied, rate_limited, upstream_error, network_error, invalid_response, and response_too_large.
An empty successful result set has status=completed and resultCount=0. Access and rate failures have separate explicit statuses, and previously collected records remain available. A technically successful Actor process can therefore contain an upstream failure summary: integrations must inspect SUMMARY.status or the final status row. partial=true means a limit/error stopped collection; completed means this requested bounded operation finished, not that all HN history was retrieved.
How much does the Hacker News actor cost?
Pay per event: $0.0015 per result ($1.50 per 1,000 saved rows). Each saved data row is one result event. Status rows, error rows and empty lookups are not charged. The run stops when it reaches the maximum cost per run. No Apify proxy and no login.
FAQ
How complete is the history? The actor uses the two public Hacker News APIs: Algolia for search and Firebase for live items and comment expansion. Algolia's index can lag behind Firebase, and deleted or moderated items disappear or change after collection. This is a point-in-time fetcher with bounded limits, not an exhaustive archive - frontpage mode can only see the current top 500 IDs, and empty result sets are normal for dated or low-score queries.
Why can I not filter comments by score?
Comment vote scores are not public in either API. minScore applies to stories only; comment search requires minScore to stay at zero.
What are the hard limits?
maxResults caps combined story and comment rows at 1,000; maxRequests caps all HTTP attempts at 500 (including retries and comment expansions); maxPages caps query paging at 20. Comment expansion shares the same result budget, so a small maxResults plus includeComments yields few rows - raise both limits together.
What happens on rate limits or access errors?
Network errors, HTTP 429 and 5xx are retried up to twice; access denial is not retried. The run ends with an explicit status (rate_limited, access_denied, ...) and keeps every record collected so far. Check SUMMARY.status: a technically successful run can still report an upstream failure.
Is this allowed, and what about personal data? The actor reads Hacker News through the API that HN itself provides for public use (the Algolia HN Search API and the official Firebase API), with no scraping or login. Content is stored as text and never rendered or executed. Authors publish on HN under its own terms, but you are responsible for downstream use - handle author names as personal data under laws such as the GDPR where applicable. This tool is not affiliated with Hacker News.
Support
Questions, bugs or feature requests: use the Issues tab on the Actor page. Independent tool, not affiliated with, endorsed by or sponsored by Hacker News or Y Combinator.
Local use and verification
Requires Node.js 22 or newer. Install from the lockfile:
npm ci --ignore-scriptsnpm testnpm run check$env:LOCAL_MODE='1'node src/main.js input.example.json local-output.json
LOCAL_MODE=1 reads the first argument as input JSON and writes a JSON array to the second argument. It does not read Apify storage, initialize Apify, or need an Apify token. Invalid or malformed input JSON yields a free invalid-input status. A missing input file is a local filesystem error.
Runtime dependency apify is pinned to 3.7.2. A narrow basic-ftp override to 6.2.3 fixes the vulnerable FTP parser transitively included by the SDK; the actor itself does not use FTP. The exact override, lockfile and SDK paths used by charging integration tests should be reviewed together when upgrading the SDK.
Evidence in evidence/ includes unit/mock/SDK charging checks, syntax checks, npm audit output, and live Algolia/Firebase samples. These are local tests. Cloud build, platform billing configuration, and publication are separate deployment steps.
Data limitations and sources
Algolia indexing can lag behind Firebase. Search data and live discussion expansion can therefore disagree in counts or timing. Deleted/moderated records and scores can change after collection. Story text and title may contain HTML. Comment vote scores are deliberately absent, and missing parent/story context remains null rather than being fabricated. Date and score filters may yield fewer rows than requested.
API and SDK behavior were checked against primary documentation on 2026-10-21: