Looking for the overview — what this API returns, what it costs, and a call you can run without a key? See the Hacker News API page →
Media, Film & Knowledge

Hacker News API & Scraper

The Hacker News API returns stories, comments and user data as clean JSON.

9 actionsLive JSON1,000 free credits$0.67–$1.50 / 1,000 creditsMCP-ready
Get a free keyOpen in playground

🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.

The primary item endpoint returns a story or comment (id, type, author, time, title/text/url, score and kids), and you can pull a full comment tree, a user, story lists, search, a poll, the front page, updates and the max item id. It is built for tech-news apps, community analytics and research tools that need HN data with hydrated comment trees. One ReefAPI key, one shared credit pool, the standard envelope.

Reference

Two field vocabularies for the same Hacker News data

This engine speaks two dialects. The official item feed uses by, score, time and kids; the search-backed surfaces use author, points, created_at and children. The same story comes back with different key names depending on which action you called, which is the biggest source of undefined values here. Measured 2026-08-26 and 2026-08-27 on item 8863, the 2007 Dropbox post, plus live front-page data.

What you wantitem, stories, poll, user, updatessearch, front_page, item_tree
Authorbyauthor
Pointsscorepoints
Comment countdescendantsnum_comments on search and front_page; descendants on item_tree
Direct replieskids[] plus kids_countchildren[] plus children_count
Timestamptime (unix seconds) plus time_isocreated_at (ISO 8601) plus created_at_i (unix seconds)
Parentparentparent_id
Owning storynot returnedstory_id, which equals id on the story itself
Measured on item 8863score 104, descendants 71, kids_count 33points 104, descendants 71, children_count 32

kids_count 33 against item_tree's 32 direct children is not an arithmetic error: the tree drops dead and deleted replies that the official kids array still lists. Treat kids_count as an upper bound on what a tree walk will hand you.

Live example

Real request and response JSON

Captured from the indexed primary action, search, on .

Captured request
{
  "method": "POST",
  "url": "https://api.reefapi.com/hackernews/v1/search",
  "headers": {
    "x-api-key": "$REEF_KEY",
    "content-type": "application/json"
  },
  "body": {
    "query": "python",
    "tags": "story"
  }
}
Captured response
{
  "ok": true,
  "meta": {
    "api": "hackernews",
    "endpoint": "search",
    "mode": "live",
    "latency_ms": 1112.9,
    "record_count": 20,
    "bytes": 29495,
    "cache_hit": false,
    "completeness_pct": 100,
    "requests": 1,
    "nbHits": 539834,
    "nbPages": 50,
    "page": 0,
    "sort": "relevance"
  },
  "data": {
    "hits": [
      {
        "id": 45751400,
        "type": "story",
        "title": "Uv is the best thing to happen to the Python ecosystem in a decade",
        "url": "https://emily.space/posts/251023-uv",
        "author": "todsacerdoti",
        "points": 2214,
        "num_comments": 1324,
        "text": null,
        "story_id": 45751400,
        "parent_id": null,
        "created_at": "[redacted-phone]T18:57:29Z",
        "created_at_i": 1761764249,
        "tags": [
          "story",
          "author_todsacerdoti",
          "story_45751400"
        ],
        "hn_url": "https://news.ycombinator.com/item?id=45751400"
      },
      {
        "id": 20915746,
        "type": "story",
        "title": "Sunsetting Python 2",
        "url": "https://www.python.org/doc/sunset-python-2/",
        "author": "azizsaya",
        "points": 1616,
        "num_comments": 704,
        "text": null,
        "story_id": 20915746,
        "parent_id": null,
        "created_at": "[redacted-phone]T06:43:24Z",
        "created_at_i": 1568011404,
        "tags": [
          "story",
          "author_azizsaya",
          "story_20915746"
        ],
        "hn_url": "https://news.ycombinator.com/item?id=20915746"
      },
      {
        "id": 13319904,
        "type": "story",
        "title": "Grumpy: Go running Python",
        "url": "https://opensource.googleblog.com/2017/01/grumpy-go-running-python.html",
        "author": "trotterdylan",
        "points": 1411,
        "num_comments": 451,
        "text": null,
        "story_id": 13319904,
        "parent_id": null,
        "created_at": "[redacted-phone]T17:00:39Z",
        "created_at_i": 1483549239,
        "tags": [
          "story",
          "author_trotterdylan",
          "story_13319904"
        ],
        "hn_url": "https://news.ycombinator.com/item?id=13319904"
      }
    ],
    "count": 20,
    "nbHits": 539834,
    "page": 0,
    "nbPages": 50,
    "hitsPerPage": 20,
    "query": "python",
    "processingTimeMS": 12,
    "sort": "relevance"
  }
}
Actions

What the Hacker News API does

ActionDescriptionConcrete use caseKey params
itemsingle item by id (story/comment/job/poll/pollopt) — all official fields + time_iso/kids_count/hn_url; hydrate_kids=resolve top-level commentsContent platforms call item to get single item by id (story/comment/job/poll/pollopt).id, hydrate_kids, kids_limit
item_treefull nested comment TREE for a story in ONE call; recursive children + descendants countResearch tools call item_tree to get full nested comment TREE for a story in ONE call; recursive children + descendants count.id
useruser profile by id: karma/created/about/submitted; hydrate_submitted=resolve recent submissionsCommunity analysts call user to get user profile by id.id, hydrate_submitted, submitted_limit
storiesstory-list (list=top/new/best/ask/show/job) → ranked hydrated stories; offset/limit pagination, hydrate=false for ids onlyMedia monitors call stories to get story-list (list=top/new/best/ask/show/job) → ranked hydrated stories; offset/limit paginatio….list, limit, offset, hydrate
searchFull-text search: query + tags(story/comment/ask_hn/show_hn/poll/front_page/author_X/story_X) + min_points/max_points/min_comments/before/after + sort(relevance|date), paginatedContent platforms call search to get full-text search.query, tags, sort, page, hits_per_page, ...
pollPoll detail by id: the question + every voting option resolved and ranked by votes, with total_votes and the comment count. (Find poll ids via search with tags=poll.)Research tools call poll to get poll detail by id.id
front_pageStories that recently made the Hacker News front page (newest-first), paginated. Optional after/before date window. NOTE: the front-page index only retains ~the last 7 days — it is 'what's on / recently hit the front page', not a historical archive.Community analysts call front_page to get stories that recently made the Hacker News front page (newest-first), paginated.limit, page, after, before
updateslive changefeed: recently changed item ids + profiles + max_item; hydrate=resolve changed itemsMedia monitors call updates to get live changefeed.hydrate, limit
max_itemthe current largest item id on Hacker News — the newest id, useful for backfilling / id-range walksContent platforms call max_item to get the current largest item id on Hacker News.none
Code samples

Call search from your stack

curl -X POST https://api.reefapi.com/hackernews/v1/search \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"query":"python","tags":"story"}'
MCP one-liner
Ask your MCP-connected assistant: call reefapi.hackernews.search with {"query":"python","tags":"story"}.
Use cases

Who uses this API and why

  • Tech-news apps call stories and front_page to show the current Hacker News ranking.
  • Community-analytics tools use item_tree to analyze full discussion threads at once.
  • Research products use search and user to track topics and contributors over time.
FAQ

Questions developers ask before integrating

What is the difference between score, descendants and kids_count?

score is upvotes, descendants is every comment anywhere under the story, and kids_count is only the direct replies. Item 8863 measured on 2026-08-27 returned score 104, descendants 71 and kids_count 33. item_tree on the same story returned 71 records with direct_children 32, one fewer than kids_count, because the tree omits a reply the kids array still lists. On a comment, score and descendants are both null: only stories, jobs and polls carry them.

Why do item and item_tree use different field names for the same thing?

They come from two different Hacker News surfaces. item, stories, poll, user and updates follow the official item shape (by, score, time, time_iso, kids), while item_tree, search and front_page follow the search index shape (author, points, created_at, created_at_i, children, parent_id, story_id). The table above maps them. If a field reads undefined, the usual cause is reading by off a search hit, or author off an item.

Which fields are null for each item type?

The shape is uniform and the differences are explicit nulls, so you can branch on type safely. A link story has text null and url set. An Ask HN story is the reverse: url null and text carrying the body, measured on two current Ask HN posts. A comment has title, url, score and descendants all null, with parent set. A job has descendants null and kids an empty array, because jobs take no comments, and both measured jobs had score 1.

How do I tell a dead item from a deleted one?

Two separate booleans, and they hollow out different fields. Measured on 2026-08-26: item 49456664 came back dead true, deleted false, with by still "sona-coffee11", time intact and text set to the literal string "[flagged]". Item 49456656 came back deleted true, dead false, with by null and text null, keeping only id, type and time. Both returned ok:true with a full record, so filter on the flags rather than expecting an error.

What does the poll action return, and is score the vote count?

No, a poll carries two separate numbers. Poll 126809 measured 2026-08-27 returned score 47, which is upvotes on the poll itself, and total_votes 301, which is the sum of its three options at 179, 73 and 49. descendants 54 is the comment count, a third number again. options[] is ranked by votes and each option is a real pollopt item with its own id and hn_url, while parts[] lists the same option ids in the poll's original order.

How far back does front_page go?

About seven days. The front-page index is a rolling window of what recently hit the front page rather than an archive, and meta returns a window_note saying so. A request for an older date range comes back thin or empty rather than erroring. For anything historical use search with tags=front_page combined with before and after, and accept that the same retention limit applies to that tag.

How do I walk every item on Hacker News?

max_item gives you the current highest id, and ids are dense integers, so you count backwards. It returned 49456670 at 2026-08-26T22:16Z. The updates action gives you the ids that changed most recently plus the profiles that changed, which is the cheap way to keep a mirror fresh instead of rescanning. The list surfaces have ceilings the ids do not: top, new and best hold up to 500 entries, ask, show and job up to 200, and search is paged 0 to 50.

Is the text field plain text or HTML?

HTML, with entities left encoded. Measured bodies contain paragraph breaks as literal <p> tags and apostrophes as &#x27;, for example "We&#x27;ve been building open source embedded ADS-B receivers". Unescape entities and handle the tags before you index or display it. Titles are plain, and hn_url is always present so you can link back to the item without building the URL yourself.

What is the Hacker News API?

Hacker News API is a ReefAPI endpoint group for stories, comments, users and full-text search. It returns live JSON through POST requests under /hackernews/v1.

Is the Hacker News API free to try?

Yes. ReefAPI starts with 1,000 free credits, no card required. Hacker News calls use the same shared credit balance as every other ReefAPI engine.

Do I need a Hacker News login or account?

No login to Hacker News is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.

How fresh is the Hacker News data?

The page example is captured from a live item call, and production requests fetch live data through ReefAPI rather than a static sample.

How many credits does the Hacker News API use?

Hacker News actions currently cost 1-2 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.

Can I call Hacker News from an AI assistant or MCP client?

Yes. Connect ReefAPI once through MCP and your assistant can call hackernews actions with the same key, credit pool and JSON envelope used by normal REST requests.

docs / hackernews

Hacker News

Stories, comments, users and full-text search.

base /hackernews/v19 endpoints
post/hackernews/v1/item1 credit

single item by id (story/comment/job/poll/pollopt) — all official fields + time_iso/kids_count/hn_url; hydrate_kids=resolve top-level comments

ParameterAllowed / rangeDescription
idrequiredHackerNews item id (story/comment/job/poll/pollopt) — the digits in an item URL (news.ycombinator.com/item?id=...).
hydrate_kids = falseoptionalIf true, resolve the item's top-level comments into full objects instead of bare ids.
kids_limit = 30optional1–100When hydrate_kids=true, how many top-level comments to resolve (1-100).
Try in playground →
post/hackernews/v1/item_tree1 credit

full nested comment TREE for a story in ONE call; recursive children + descendants count

ParameterAllowed / rangeDescription
idrequiredHackerNews item id (story/comment/job/poll/pollopt) — the digits in an item URL (news.ycombinator.com/item?id=...).
Try in playground →
post/hackernews/v1/user1 credit

user profile by id: karma/created/about/submitted; hydrate_submitted=resolve recent submissions

ParameterAllowed / rangeDescription
idrequiredHackerNews username (case-sensitive), e.g. 'pg'.
hydrate_submitted = falseoptionalIf true, resolve the user's recent submissions into full objects instead of bare ids.
submitted_limit = 20optional1–100When hydrate_submitted=true, how many recent submissions to resolve (1-100).
Try in playground →
post/hackernews/v1/stories2 credits

story-list (list=top/new/best/ask/show/job) → ranked hydrated stories; offset/limit pagination, hydrate=false for ids only

ParameterAllowed / rangeDescription
list = topoptionaltop · new · best · ask · show · jobWhich HackerNews story list to return.
limit = 30optional1–100Stories to return (1-100, default 30). Out-of-range values are clamped.
offset = 0optional0–500Pagination offset into the story list (0-500). Skip N ranked stories.
hydrate = trueoptionalIf true, resolve each ranked story id into full objects instead of bare ids (default true).
Try in playground →
post/hackernews/v1/poll1 credit

Poll detail by id: the question + every voting option resolved and ranked by votes, with total_votes and the comment count. (Find poll ids via search with tags=poll.)

ParameterAllowed / rangeDescription
idrequiredHackerNews poll id (the digits in a poll's item URL). Find polls with the search action using tags=poll.
Try in playground →
post/hackernews/v1/front_page1 credit

Stories that recently made the Hacker News front page (newest-first), paginated. Optional after/before date window. NOTE: the front-page index only retains ~the last 7 days — it is 'what's on / recently hit the front page', not a historical archive.

ParameterAllowed / rangeDescription
limit = 30optional1–100Front-page stories to return (1-100, default 30). Out-of-range values are clamped.
page = 0optional0–500-based search results page (0-50). Page forward via meta.nbPages.
afteroptionalOnly front-page stories created on/after this date (unix ts or YYYY-MM-DD). Note: the front-page index only retains ~the last 7 days.
beforeoptionalOnly front-page stories created on/before this date (unix ts or YYYY-MM-DD).
Try in playground →
post/hackernews/v1/updates1 credit

live changefeed: recently changed item ids + profiles + max_item; hydrate=resolve changed items

ParameterAllowed / rangeDescription
hydrate = falseoptionalIf true, resolve the changed item ids into full objects instead of bare ids.
limit = 30optional1–100Changed items to hydrate (1-100, default 30). Out-of-range values are clamped.
Try in playground →
post/hackernews/v1/max_item1 credit

the current largest item id on Hacker News — the newest id, useful for backfilling / id-range walks

Try in playground →