Product Hunt API — Launch Comments as JSON
Documentation menu
FetchLayer FetchLayer API

Get a launch's comment threads

Pull the comment threads on a launch — the maker's own notes, the questions, and the feedback launch day produces. Replies come back nested underneath their parent comment rather than flattened into one list, so walk comments[].replies recursively. Sort by score, date or votes, and page through with a cursor.

POST /product-comments Launches
https://api.fetchlayer.dev/producthunt/product-comments
OpenAPI JSON

Headers

Authorization string required

Bearer token — your FetchLayer API key.

Parameters

product string required

Product slug, launch slug, or any Product Hunt product or launch URL.

launch string optional

A specific launch, instead of the product's most recent one.

limit number optional

Maximum comments returned (max 300), or -1 for everything available. Counts replies too. (default: 30)

pageSize number optional

Comment threads fetched per page (max 50). (default: 10)

sortBy string optional

SCORE, DATE, DATE_DESC, VOTES, or DEFAULT. (default: SCORE)

pages number optional

Pages of results to collect in one request (max 100), or -1 for the maximum allowed. Each page walked counts as one request. (default: 1)

cursor string optional

Resume from a previous response's nextCursor.

delayMs number optional

Milliseconds to wait between pages (max 30000).

format string optional

json or markdown. Markdown returns the same result rendered as text. (default: json)

timeoutMs number optional

Per-request time limit in milliseconds (max 600000).

Response Fields

product-comments

Get a launch's comment threads

launchSlug string

The launch the comments belong to.

launchName string | null

Name of that launch.

commentsCount number | null

Every comment on the launch, as Product Hunt counts them.

threadCount number | null

Top-level threads on the launch.

comments object[]

Top-level threads. Each one carries its replies nested underneath in comments[].replies — the tree is not flattened.

comments[].body string | null

The comment text with the markup removed. bodyHtml carries it as posted.

comments[].author object | null

Who wrote it: username, name and avatar.

comments[].badges string[]

Labels shown beside the author, such as "maker".

comments[].votes number | null

Upvotes on the comment.

comments[].isPinned boolean

Whether the comment is pinned to the top of the thread.

comments[].repliesCount number | null

How many replies the comment has, which can exceed the number nested in replies when a walk stopped early.

comments[].replies object[]

Replies, in the same shape, nested to whatever depth the thread reaches.

returnedCount number

Comments in this response, replies included.

pagesScraped number

Pages actually collected. Each page counts as one request against your plan.

pagesRequested number

Pages the request asked for.

nextCursor string | null

Pass back as cursor to continue, or null when the listing is exhausted.

hasNextPage boolean

Whether more results are available beyond this response.

requestedUrl string

The Product Hunt page this result corresponds to.

scrapedAt string

ISO timestamp the result was collected at.

notes string[]

Read this. Caveats about this specific result — a walk that stopped early, an upstream ceiling, or promoted entries that were dropped. An empty array means nothing was held back.

blocked boolean

Always false on a successful response.

Request

curl -X POST "https://api.fetchlayer.dev/producthunt/product-comments" \
  -H "Authorization: Bearer ss-your-key" \
  -H "Content-Type: application/json" \
  -d '{"product":"notion","sortBy":"SCORE","limit":50,"pageSize":20}'

Response

{
  "launchSlug": "notion-3-0",
  "commentsCount": 312,
  "threadCount": 128,
  "returnedCount": 50,
  "hasNextPage": true,
  "notes": [
    "Reply walk stopped at depth 3 on 2 threads."
  ],
  "comments": [
    {
      "body": "Congrats on the launch! How does this handle offline edits?",
      "author": {
        "username": "jane"
      },
      "badges": [],
      "votes": 24,
      "repliesCount": 2,
      "replies": [
        {
          "body": "Offline edits sync on reconnect.",
          "author": {
            "username": "ivan"
          },
          "badges": [
            "maker"
          ],
          "replies": []
        }
      ]
    }
  ]
}