# Product Hunt Scraper (`brilliant_gum/producthunt-scraper`) Actor

No-login Product Hunt scraper: daily/weekly/monthly/yearly leaderboards, full product & launch details, makers + hunter, comments, reviews & ratings, topic/category feeds, product search, and maker lead-gen (followers, Twitter, products). Optional BYO official API token.

- **URL**: https://apify.com/brilliant\_gum/producthunt-scraper.md
- **Developed by:** [Yuliia Kulakova](https://apify.com/brilliant_gum) (community)
- **Categories:** Business, Lead generation, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $9.00 / 1,000 record scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Product Hunt Scraper — launches, products, makers, reviews & collections (no login)

![Product Hunt Scraper](https://api.apify.com/v2/key-value-stores/IuFu0Cw6PpOkNkDV7/records/producthunt-banner)

Scrape Product Hunt without an account, cookies, or API key. This actor reads Product Hunt's public pages and returns clean, structured records for **launches, products, makers, hunters, comments, reviews, topics, categories, collections and search**.

It is built for teams that turn Product Hunt into an intelligence feed:

- **Startup & launch intelligence** — what launched today / this week / month / year, ranks, upvotes, comment velocity, topics and media.
- **Maker & founder lead-gen** — maker and hunter profiles with follower counts, Twitter handles, headlines, the products they made and the tools they use, plus optional website email harvesting and verification.
- **Market & trend research** — topic and category feeds, full-text product search, ratings and review counts.
- **VC / deal sourcing** — surface fast-climbing launches, prolific makers and the products behind them.

No login is required — the default path reads Product Hunt's public pages. Optionally paste **your own** free Product Hunt developer token to additionally enrich launches through the official Product Hunt API.

***

### Key features

- **8 scrape modes** — more surface area than any competing Product Hunt actor:
  - **Leaderboard** — daily, weekly, monthly and yearly ranked launches (single day, ISO week, month or year).
  - **Product / launch details** — full launch + product profile for any product or launch URL/slug.
  - **Product search** — Product Hunt search for one or more terms, paginated.
  - **Topic feed** — a topic's product feed (e.g. `artificial-intelligence`), paginated.
  - **Category feed** — a category's product feed (e.g. `ai-code-editors`), paginated.
  - **Collection** — the products inside curated collections.
  - **Maker profile** — maker / hunter lead-gen records.
  - **Mixed URLs** — paste any mix of Product Hunt URLs; each is auto-routed to the right handler.
- **Rich per-launch data** — `votes` (current upvotes) and `votesLaunchDay`, `commentsCount`, `reviewsRating` + `reviewsCount`, `makers[]`, `hunter`, `topics[]`, `media[]` (screenshots + video), `productLinks[]`, `badges[]`, ranks and full description.
- **Product `alternatives[]` and `launchHistory[]`** — the product's listed alternatives and its full visible launch history (unique among Product Hunt scrapers).
- **Product tech stack `builtWith[]`** (opt-in) — the tools/products a product is "built with", captured from its `built-with` tab (each with name, tagline, logo, ratings and a shoutout note). Distinct from a maker's personal `stacks[]`. Count varies per product and over time.
- **Deep maker lead-gen** — followers/following, Twitter handle + URL, headline, products made (`madeProducts[]`), products used (`stacks[]`), review activity, Kitty-coin ranks (`kittyCoin.allTime/year/month`) and visit streak.
- **Website email harvest + verification** — optionally fetch each product's own website and harvest public contact emails (`emails[]`), then optionally verify them with real MX + SMTP-RCPT checks (`emailsVerified[]`), with an honest MX-only fallback when outbound port 25 is blocked.
- **Robust slug routing** — accepts a **product** slug OR a **launch/post** slug; the wrong namespace is auto-corrected, so `/products/{slug}` and `/posts/{slug}` both work.
- **Optional BYO official API** — supply your own `apiToken` for higher-reliability enrichment and comment bodies at scale. Entirely optional.
- **Keyless & reliable** — no account and no setup. Proxies are included and configured automatically; the actor picks the right route for each page on its own.

***

### Input

Every field is optional except `mode`. Provide only the targets relevant to your chosen mode.

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `mode` | enum (**required**) | `leaderboard` | `leaderboard` / `product-details` / `search` / `topic` / `category` / `collection` / `maker-profile` / `urls`. |
| `leaderboardPeriod` | enum | `daily` | `daily` / `weekly` / `monthly` / `yearly`. |
| `date` | string `YYYY-MM-DD` | — | Daily leaderboard day (empty = today, US Pacific). |
| `dateFrom`, `dateTo` | string `YYYY-MM-DD` | — | Inclusive daily range (overrides `date`). |
| `week` | integer 1–53 | — | Weekly period (pair with `year`). |
| `month` | integer 1–12 | — | Monthly period (pair with `year`). |
| `year` | integer | — | Year for weekly / monthly / yearly. |
| `searchTerms` | array<string> | — | Search-mode queries (e.g. `["AI","note taking"]`). |
| `topics` | array<string> | — | Topic slugs (e.g. `artificial-intelligence`). |
| `categories` | array<string> | — | Category slugs (e.g. `ai-code-editors`). |
| `collectionUrls` | array<string> | — | Full collection URLs. |
| `productUrls` | array<string> | — | `/products/{slug}` or `/posts/{slug}` URLs. |
| `productSlugs` | array<string> | — | Bare product or launch slugs (e.g. `kilocode`). |
| `makerUsernames` | array<string> | — | `@usernames` (with or without `@`). |
| `makerUrls` | array<string> | — | `/@{username}` profile URLs. |
| `startUrls` | array (requestListSources) | — | Mixed Product Hunt URLs (urls mode). |
| `maxItems` | integer | `100` | Hard cap on saved records (0 = unlimited, safety-capped). |
| `maxPages` | integer | `0` | Max feed pages per query (0 = until `maxItems`). |
| `featuredOnly` | boolean | `false` | Leaderboards: keep only featured launches. |
| `includePromoted` | boolean | `false` | Include promoted / advertised rows. |
| `enrichLaunchDetails` | boolean | `true` | Leaderboard/urls: fetch each launch page for makers, media, links, description. |
| `enrichProductDetails` | boolean | `false` | Topic/category/search: upgrade each product card to a full launch record. |
| `includeMakers` | boolean | `true` | Include `makers[]` + `hunter`. |
| `includeMedia` | boolean | `true` | Include `media[]`. |
| `scrapeComments` | boolean | `false` | Attach `comments[]` from the public page (no token needed). |
| `maxComments` | integer | `20` | Cap comments per launch. |
| `scrapeReviews` | boolean | `false` | Attach detailed `reviews[]` + per-dimension ratings. |
| `maxReviews` | integer | `20` | Cap reviews per product. |
| `scrapeLaunchHistory` | boolean | `false` | Attach the product's past launches (`launchHistory[]`). |
| `scrapeAlternatives` | boolean | `false` | Attach listed `alternatives[]`. |
| `includeBuiltWith` | boolean | `false` | Attach the product tech stack `builtWith[]`. |
| `makerLeadEnrichment` | boolean | `true` | Maker-profile: include products made, stacks, socials, Kitty-coin. |
| `enrichWebsiteEmails` | boolean | `false` | Harvest public emails from each product's website → `emails[]`. |
| `verifyEmails` | boolean | `false` | Verify harvested emails via MX + SMTP → `emailsVerified[]`. |
| `apiToken` | string (secret) | — | Optional BYO official Product Hunt API bearer token. |
| `deduplicate` | boolean | `true` | Drop duplicate records within a run. |
| `maxConcurrency` | integer | `8` | Parallel detail fetches (6–10 recommended). |
| `maxRequestRetries` | integer | `5` | Retries per request on a block. |
| `proxy` | object | included | Optional. Proxies are included and auto-configured — leave empty. |

#### Input examples

**Daily leaderboard with makers, comments and reviews**

```json
{
  "mode": "leaderboard",
  "leaderboardPeriod": "daily",
  "date": "2026-09-01",
  "enrichLaunchDetails": true,
  "scrapeComments": true,
  "scrapeReviews": true,
  "maxItems": 50
}
```

**Product / launch details with tech stack, alternatives and verified emails**

```json
{
  "mode": "product-details",
  "productSlugs": ["kilocode", "lovable"],
  "includeBuiltWith": true,
  "scrapeAlternatives": true,
  "scrapeLaunchHistory": true,
  "enrichWebsiteEmails": true,
  "verifyEmails": true
}
```

**Maker profiles for lead-gen**

```json
{
  "mode": "maker-profile",
  "makerUsernames": ["chrismessina", "fmerian"],
  "makerLeadEnrichment": true,
  "maxItems": 5
}
```

**Product search**

```json
{
  "mode": "search",
  "searchTerms": ["AI code editor"],
  "enrichProductDetails": false,
  "maxPages": 3
}
```

***

### Output

Each record carries a `type` field — `launch`, `product` or `maker` — plus `sourceUrl` and `scrapedAt`. Fields Product Hunt does not expose for a given record are omitted rather than faked.

#### `launch` record (trimmed)

Leaderboard (enriched), `product-details` and `urls` modes.

```json
{
  "type": "launch",
  "postId": "…",
  "name": "Kilo Code",
  "slug": "kilocode",
  "url": "https://www.producthunt.com/posts/kilocode",
  "tagline": "Open-source AI coding agent for VS Code",
  "description": "…",
  "votes": 503,
  "votesLaunchDay": 498,
  "commentsCount": 87,
  "reviewsCount": 42,
  "reviewsRating": 4.9,
  "dailyRank": 1,
  "featured": true,
  "isTopLaunch": true,
  "launchNumber": 3,
  "launchState": "default",
  "leaderboardRank": 1,
  "createdAt": "2026-09-01T07:01:00Z",
  "featuredAt": "2026-09-01T07:01:00Z",
  "thumbnailUrl": "https://ph-files.imgix.net/…?auto=format&fit=crop&w=300&h=300",
  "topics": [
    { "id": "…", "name": "Developer Tools", "slug": "developer-tools" },
    { "id": "…", "name": "Artificial Intelligence", "slug": "artificial-intelligence" }
  ],
  "topicNames": "Developer Tools, Artificial Intelligence",
  "media": [
    { "type": "image", "imageUrl": "https://ph-files.imgix.net/…?auto=format&fit=max", "width": 1270, "height": 760 },
    { "type": "video", "platform": "youtube", "videoId": "…", "videoUrl": "https://www.youtube.com/watch?v=…" }
  ],
  "productLinks": [
    { "store": "Website", "website": "kilocode.ai", "redirectUrl": "https://www.producthunt.com/r/…" },
    { "store": "Github", "website": "github.com", "redirectUrl": "https://www.producthunt.com/r/…" }
  ],
  "websiteUrl": "https://kilocode.ai",
  "badges": [ { "type": "TopPostBadge", "period": "DAY", "date": "2026-09-01", "position": 1 } ],
  "hunter": {
    "id": "…",
    "name": "Chris Messina",
    "username": "chrismessina",
    "headline": "Inventor of the hashtag …",
    "avatarUrl": "https://ph-avatars.imgix.net/…",
    "profileUrl": "https://www.producthunt.com/@chrismessina"
  },
  "hunterUsername": "chrismessina",
  "makers": [
    { "id": "…", "name": "…", "username": "…", "headline": "…", "avatarUrl": "https://ph-avatars.imgix.net/…", "profileUrl": "https://www.producthunt.com/@…" }
  ],
  "makersCount": 2,
  "product": {
    "id": "…",
    "slug": "kilocode",
    "name": "Kilo Code",
    "url": "https://www.producthunt.com/products/kilocode",
    "websiteUrl": "https://kilocode.ai",
    "cleanUrl": "kilocode.ai",
    "description": "…",
    "logoUrl": "https://ph-files.imgix.net/…?auto=format",
    "followersCount": 1240,
    "reviewsCount": 42,
    "reviewsRating": 4.9,
    "postsCount": 3,
    "wasInYCombinator": false,
    "socialLinks": { "twitter": "https://twitter.com/…", "github": "https://github.com/…" },
    "categories": [ { "id": "…", "name": "AI Code Editors", "slug": "ai-code-editors" } ]
  },
  "sourceUrl": "https://www.producthunt.com/posts/kilocode",
  "scrapedAt": "2026-09-03T09:00:00.000Z"
}
```

> Notes: `product.employeeSize`, `product.fundingAmount` and `pricingType` are mapped but are not in Product Hunt's public payload, so they resolve to `null` and are dropped from the record (see Limitations). The `hunter`/`makers[]` objects on launch/product records typically carry `{id, name, username, headline, avatarUrl, profileUrl}` (a maker's `twitterUsername` and follower counts are additionally included only when the page exposes them, which for launch/product records is rare). **For reliable maker Twitter handles, follower counts and the products they made, use maker-profile mode** (a separate `type:maker` record).

**`launch` field list:** `type`, `postId`, `name`, `slug`, `url`, `tagline`, `description`, `votes`, `votesLaunchDay`, `commentsCount`, `reviewsCount`, `reviewsRating`, `dailyRank`, `weeklyRank`, `monthlyRank`, `leaderboardRank` (leaderboard mode), `featured`, `isTopLaunch`, `launchNumber`, `launchState`, `isPromoted`, `createdAt`, `featuredAt`, `scheduledAt`, `thumbnailUrl`, `topics[]`, `topicNames`, `media[]`, `productLinks[]` (`{store, website, redirectUrl, devices}`), `websiteUrl`, `badges[]`, `hunter{}`, `hunterUsername`, `makers[]`, `makersCount`, `product{}`, `leaderboard{period,url}` (leaderboard mode), and optionally `comments[]` + `commentsCaptured` + `commentsTruncated`, `reviews[]` + `reviewsCaptured` + `reviewsTruncated`, `launchHistory[]`, `alternatives[]`, `builtWith[]`, `emails[]`, `emailsVerified[]`, `apiEnriched` + `apiNote` (only with a BYO `apiToken`), `sourceUrl`, `scrapedAt`.

#### `builtWith[]` shape (opt-in via `includeBuiltWith`)

The product's tech stack, each entry a product Product Hunt lists under "built with":

```json
"builtWith": [
  {
    "id": "…",
    "name": "Claude",
    "slug": "claude",
    "url": "https://www.producthunt.com/products/claude",
    "tagline": "…",
    "logoUrl": "https://ph-files.imgix.net/…?auto=format",
    "reviewsRating": 4.8,
    "reviewsCount": 210,
    "followersCount": 5400,
    "categories": [ { "id": "…", "name": "…", "slug": "…" } ],
    "note": "We use it for the agent's reasoning loop"
  }
]
```

#### `emailsVerified[]` shape (opt-in via `enrichWebsiteEmails` + `verifyEmails`)

```json
"emails": ["hello@kilocode.ai", "support@kilocode.ai"],
"emailsVerified": [
  {
    "email": "hello@kilocode.ai",
    "status": "unknown",
    "confidence": 50,
    "mxFound": true,
    "mxHost": "aspmx.l.google.com",
    "smtpChecked": false,
    "smtpBlocked": true,
    "note": "SMTP unreachable (ETIMEDOUT); fell back to MX-only"
  }
]
```

`status` is one of `valid` / `invalid` / `catch-all` / `role` / `disposable` / `unknown`; `confidence` is 0–100. Outbound port 25 is blocked on the Apify platform (and most hosts), so in practice verification runs **MX-only**: `mxFound` true/false, `smtpChecked:false`, `smtpBlocked:true`, `confidence ~40–50` (role/company inboxes ~40). The `catchAll` field and a full mailbox verdict (`valid`/`invalid` at confidence ~95, `smtpChecked:true`) only appear where outbound port 25 is actually open. These are public **company/role** addresses from the product's own site (e.g. `sales@`, `hello@`) — not personal maker contacts.

#### `product` record (trimmed)

Topic / category / search / collection modes, when not upgraded with `enrichProductDetails`.

```json
{
  "type": "product",
  "id": "…",
  "name": "Cursor",
  "slug": "cursor",
  "url": "https://www.producthunt.com/products/cursor",
  "tagline": "The AI code editor",
  "reviewsRating": 4.7,
  "reviewsCount": 318,
  "logoUrl": "https://ph-files.imgix.net/…?auto=format",
  "rank": 1,
  "categorySlug": "ai-code-editors",
  "sourceUrl": "https://www.producthunt.com/categories/ai-code-editors",
  "scrapedAt": "2026-09-03T09:00:00.000Z"
}
```

`topicSlug` / `categorySlug` / `searchTerm` / `collectionUrl` identifies which query produced the card.

#### `maker` record (trimmed)

Maker-profile mode.

```json
{
  "type": "maker",
  "id": "…",
  "username": "chrismessina",
  "name": "Chris Messina",
  "url": "https://www.producthunt.com/@chrismessina",
  "headline": "Inventor of the hashtag. Product Hunt's #1 hunter …",
  "avatarUrl": "https://ph-files.imgix.net/…",
  "headerImageUrl": "https://ph-files.imgix.net/…?auto=format",
  "isMaker": true,
  "isAccountVerified": true,
  "isAmbassador": true,
  "twitterUsername": "chrismessina",
  "twitterUrl": "https://twitter.com/chrismessina",
  "followersCount": 41800,
  "followingsCount": 2100,
  "productsCount": 38,
  "submittedPostsCount": 2600,
  "collectionsCount": 40,
  "reviewsCount": 120,
  "stacksCount": 55,
  "kittyCoin": {
    "allTime": { "rank": 1, "value": "…" },
    "year": { "rank": 3, "value": "…" },
    "month": { "rank": 5, "value": "…" }
  },
  "visitStreak": { "emoji": "🔥", "duration": 365 },
  "stacks": [ { "id": "…", "name": "Notion", "slug": "notion" } ],
  "madeProducts": [
    { "type": "product", "id": "…", "name": "…", "slug": "…", "url": "https://www.producthunt.com/products/…", "tagline": "…" }
  ],
  "sourceUrl": "https://www.producthunt.com/@chrismessina",
  "scrapedAt": "2026-09-03T09:00:00.000Z"
}
```

**`maker` field list:** `type`, `id`, `username`, `name`, `url`, `headline`, `avatarUrl`, `headerImageUrl`, `isMaker`, `isAccountVerified`, `isAmbassador`, `twitterUsername`, `twitterUrl`, `followersCount`, `followingsCount`, `productsCount`, `submittedPostsCount`, `collectionsCount`, `reviewsCount`, `stacksCount`, `kittyCoin{allTime,year,month}`, `visitStreak{emoji,duration}`, `stacks[]`, `madeProducts[]`, `sourceUrl`, `scrapedAt`.

> The sample values above are illustrative and trimmed; field **names and shapes** match exactly what the actor emits.

***

### Pricing

This actor is billed **per record**: a small per-run start fee plus a flat rate for each record saved to the dataset (launches, products and makers), **plus Apify's standard platform usage** (compute and proxy) for the run. Enrichment options (comments, reviews, tech stack, email harvest/verification) add extra fetches per record but do not change what counts as a record — sub-objects such as `comments[]`, `reviews[]`, `builtWith[]`, `emails[]` and `emailsVerified[]` are attached to their parent record at **no additional per-record charge**. See the actor's pricing tab for the exact current rates.

Tip: keep `maxItems` and `maxPages` set to what you actually need, and leave heavy enrichment off unless you need it.

***

### Use cases

- **Launch & trend tracking** — pull the daily/weekly/monthly leaderboard on a schedule to watch what is launching, how fast it climbs, and in which topics.
- **Maker & founder lead-gen** — build lists of makers and hunters with follower counts, Twitter handles and the products they ship; optionally attach and verify contact emails from product websites.
- **Competitor launch monitoring** — track a competitor's product page for new launches, ratings, reviews, alternatives and its tech stack over time.
- **VC / deal sourcing** — surface fast-rising launches and prolific, well-followed makers early, with the product profile and links needed to reach out.
- **Market research** — topic and category feeds plus product search for ratings, review counts and positioning across a space (e.g. `ai-code-editors`).

***

### Honest limitations

We would rather set expectations correctly than oversell.

- **Proxies are included and automatic.** No proxy setup is required — the actor routes each page appropriately on its own. You can pin your own proxy in the input, but it is not necessary.
- **Each leaderboard returns its top band, not the entire board.** Every leaderboard — daily, weekly, monthly and yearly — returns roughly the **top ~15–20 launches** of that period (the complete featured set plus a partial non-featured tail). Launches further down the board are loaded only through on-page interaction and are not returned. In practice this is the ranked "leaderboard" people mean. To cover a whole month or year in depth, run the **daily** leaderboard across a `dateFrom`–`dateTo` range instead — each day contributes its own top band.
- **`product.employeeSize`, `product.fundingAmount` and `pricingType` are not in Product Hunt's public payload.** They are mapped for completeness but resolve to `null` (dropped from the record). Do not rely on this actor for company headcount, funding, or free/paid pricing figures.
- **`comments[]` and `reviews[]` are a sample, not the full set.** They contain the most relevant comments/reviews available on the public page — typically **far fewer** than the total `commentsCount`/`reviewsCount` (e.g. a launch with 79 comments / 46 reviews may return ~7 / ~3). Raising `maxComments`/`maxReviews` will not return more than the public page exposes (they only cap the sample, not expand it). Each record reports how many were captured via `commentsCaptured`/`reviewsCaptured` (with `commentsTruncated`/`reviewsTruncated:true` when below the total). Comments are ordered sticky/pinned-first then by votes, not in the site's native order.
- **Very large products fetched by bare slug** (e.g. `notion`, `figma` via `productSlugs`/`/products/{slug}`) return full product-level data (reviews, followers, socials, categories, alternatives, builtWith) but the top-level launch's **`makers`, `hunter`, `topics`, `media` and `description` may be absent** — the public page does not fully render the highlighted launch for these. Pass the exact launch URL (`/posts/{launch-slug}`) or use leaderboard mode to get the complete launch record with makers.
- **Email verification is MX-only in practice.** Outbound port 25 is blocked on the Apify platform (and most hosts), so `verifyEmails` returns an **MX-only** verdict (`mxFound` true/false, `smtpBlocked:true`, `confidence ~40–50`); full mailbox verdicts (`valid`/`invalid`) only occur where port 25 is open. Harvested emails are public **company/role** addresses from the product's own site, not personal maker contacts.
- **Topic / category / search return lightweight product cards** (name, tagline, rating, review count, logo) unless `enrichProductDetails` is on, which adds one fetch per product to upgrade it to a full launch record.
- **Emails are harvested from the product's own website only.** Product Hunt does not expose maker personal emails, so `enrichWebsiteEmails` reads public addresses published on the product site — and a JS-only SPA that exposes no address yields nothing.
- **The official-API path is optional and best-effort.** The no-login website path is the fully tested default and already returns makers, comments and reviews.

***

### FAQ

**Do I need to log in or provide an API key?**
No. The default no-login path reads Product Hunt's public pages and already returns launches, products, makers, comments and reviews. Optionally, you can paste your **own** free Product Hunt developer token (`apiToken`) to additionally enrich launches through the official API — it is never required.

**How are upvotes reported?**
`votes` is `Post.latestScore` — the current upvote number shown on the site. `votesLaunchDay` is the launch-day tally. There is no separate hidden vote count in the public payload.

**Can I pass a launch URL instead of a product URL (or vice versa)?**
Yes. Both `/products/{slug}` and `/posts/{slug}` URLs and bare slugs work; the actor auto-corrects the namespace.

**What's the difference between `builtWith[]` and a maker's `stacks[]`?**
`builtWith[]` is the **product's** tech stack (tools it is built with). A maker's `stacks[]` is the tools **a person** uses. They are separate.

**Why is a field missing from my records?**
Fields Product Hunt does not expose for a record are omitted rather than filled with fake values. Enable the matching option (e.g. `scrapeComments`, `scrapeReviews`, `includeBuiltWith`, `enrichWebsiteEmails`) to populate optional data.

**Is this allowed?**
The actor reads only public, logged-out Product Hunt pages; no authentication is bypassed. You are responsible for how you use personal data (maker names, Twitter handles, any harvested emails) and for complying with Product Hunt's terms and applicable law.

***

### Feedback & support

Maintained by **[brilliant\_gum](https://apify.com/brilliant_gum)**.

- ⭐️ **If this actor is useful, a rating on its Apify Store page really helps** other people find it.
- 🐛 **Something not working, or a field you need?** Open an issue on the actor's **Issues** tab — it is monitored and fixes ship fast.
- 💡 Feature requests are welcome the same way.

# Actor input Schema

## `mode` (type: `string`):

What to scrape. 'leaderboard' = a daily/weekly/monthly/yearly ranked list of launches. 'product-details' = full launch + product records for productUrls/productSlugs. 'search' = product search for searchTerms. 'topic' = a topic feed for topics\[]. 'category' = a category feed for categories\[]. 'collection' = the products in curated collections for collectionUrls\[]. 'maker-profile' = maker/hunter profiles for makerUsernames/makerUrls (lead-gen). 'urls' = mixed Product Hunt URLs in startUrls, auto-routed to the right handler.

## `leaderboardPeriod` (type: `string`):

Leaderboard mode only. Which leaderboard to read: daily (a single day), weekly (an ISO week), monthly, or yearly.

## `date` (type: `string`):

Daily leaderboard date in YYYY-MM-DD (e.g. 2026-09-01). Leave empty for today's leaderboard (Product Hunt's day rolls over at midnight US Pacific time).

## `dateFrom` (type: `string`):

Start date (YYYY-MM-DD) for an inclusive multi-day daily range. Overrides Date when set together with Date to.

## `dateTo` (type: `string`):

End date (YYYY-MM-DD) for an inclusive daily range. Used with Date from.

## `week` (type: `integer`):

ISO week number 1-53 for the weekly leaderboard. Pair with Year. Leave empty for the current week.

## `month` (type: `integer`):

Month number 1-12 for the monthly leaderboard. Pair with Year. Leave empty for the current month.

## `year` (type: `integer`):

Four-digit year for weekly, monthly and yearly leaderboards (e.g. 2026). Leave empty for the current year.

## `searchTerms` (type: `array`):

Search mode only. Product Hunt product search queries (e.g. "AI", "note taking"). One product-search record per result.

## `topics` (type: `array`):

Topic mode only. Product Hunt topic slugs (e.g. artificial-intelligence, developer-tools, productivity). Find them in a topic page URL /topics/<slug>.

## `categories` (type: `array`):

Category mode only. Product Hunt category slugs (e.g. ai-code-editors). Find them in a category page URL /categories/<slug>.

## `collectionUrls` (type: `array`):

Collection mode. Full Product Hunt collection URLs (e.g. https://www.producthunt.com/@user/collections/<slug> or /collections/<slug>). The products in each collection are returned.

## `productUrls` (type: `array`):

Product-details mode. Full Product Hunt URLs: https://www.producthunt.com/products/<slug> or /posts/<slug>.

## `productSlugs` (type: `array`):

Product-details mode. Bare product or launch slugs (e.g. kilocode or kilo-code-for-jetbrains-2), resolved as producthunt.com/products/<slug>.

## `makerUsernames` (type: `array`):

Maker-profile mode. Product Hunt usernames, with or without the leading @ (e.g. fmerian or @fmerian).

## `makerUrls` (type: `array`):

Maker-profile mode. Full Product Hunt profile URLs: https://www.producthunt.com/@<username>.

## `startUrls` (type: `array`):

URLs mode. Mixed Product Hunt URLs — leaderboard, product/post, topic, category, search, or /@maker — each auto-routed to the correct handler. Advanced alternative to the fields above.

## `maxItems` (type: `integer`):

Hard cap on the number of records saved for this run. 0 = unlimited (safety-capped). Counts launches + products + makers.

## `maxPages` (type: `integer`):

For search/topic/category, the maximum number of result pages to page through per query (each page ~10-15 items). 0 = until Max items is reached or results run out.

## `featuredOnly` (type: `boolean`):

Leaderboard mode: keep only launches Product Hunt marks as featured. Off = include every launch on the board.

## `includePromoted` (type: `boolean`):

Include promoted / advertised launches (flagged with isPromoted:true). Off = strip promoted rows.

## `enrichLaunchDetails` (type: `boolean`):

Leaderboard & URLs modes: fetch each launch's own page to add makers, hunter, media, product links, full description and product profile. One extra request per launch. Off = fast listing rows (rank, votes, comment count, topics, tagline, thumbnail).

## `enrichProductDetails` (type: `boolean`):

Topic, category and search modes return lightweight product cards (name, tagline, rating, review count, logo). Turn this on to fetch each product's page and upgrade it to a full launch record (votes, makers, description, media, socials). One extra request per product.

## `includeMakers` (type: `boolean`):

Include the makers\[] array and the hunter for each launch (name, username, headline, avatar, profile URL). Available on enriched launch/product-detail records.

## `includeMedia` (type: `boolean`):

Include the media\[] gallery for each launch (screenshot image URLs and video metadata). Available on enriched records.

## `scrapeComments` (type: `boolean`):

Attach the launch's comments (body, author, votes, badges, replies) parsed from the public page — no API token needed. Only for enriched launch / product-detail records.

## `maxComments` (type: `integer`):

Upper bound on comments attached per launch. The public page returns a sample of the most relevant comments (often far fewer than the total commentsCount); see commentsCaptured on the record.

## `scrapeReviews` (type: `boolean`):

Attach detailed product reviews: overall + per-dimension ratings (ease of use, reliability, value, customization), pros/cons, positive/negative feedback, author. Parsed from the public page.

## `maxReviews` (type: `integer`):

Upper bound on reviews attached per product. The public page returns a sample of reviews (often far fewer than the total reviewsCount); see reviewsCaptured on the record.

## `scrapeLaunchHistory` (type: `boolean`):

Attach the product's visible past launches (name, slug, date, votes) to product-detail records.

## `scrapeAlternatives` (type: `boolean`):

Attach Product Hunt's listed alternative products to product-detail records.

## `includeBuiltWith` (type: `boolean`):

Attach builtWith\[] to product-detail records: the tools/products this product is built with (Product Hunt's 'built with' / product stack block), each with name, slug, url, tagline, logo, ratings and a shoutout note. Distinct from a maker's 'stacks' (tools a person uses). Off by default.

## `makerLeadEnrichment` (type: `boolean`):

Maker-profile mode: include the maker's follower/following counts, Twitter handle, products they made, products they use (stacks), review activity and Kitty-coin rank for lead scoring.

## `enrichWebsiteEmails` (type: `boolean`):

For each launch/product with a website, fetch that website and extract public contact emails (mailto: + text patterns, junk filtered). Cached per domain. Product Hunt does not expose personal maker emails, so this reads the product's own site only. Off by default.

## `verifyEmails` (type: `boolean`):

Requires 'Harvest emails from product website'. Runs every harvested email through an MX + SMTP mailbox verifier (pure Node DNS/socket, no third-party service) and attaches emailsVerified\[] = { email, status (valid/invalid/catch-all/role/disposable/unknown), confidence 0-100, mxFound, mxHost, smtpChecked, smtpBlocked, catchAll, note }. When outbound port 25 is blocked from the run host it degrades honestly to an MX-only verdict (mxFound true/false, smtpBlocked:true). Off by default.

## `apiToken` (type: `string`):

Optional. YOUR OWN Product Hunt developer token (create free at producthunt.com/v2/oauth/applications -> Add an application -> Create developer token). When set, the actor can enrich launches via the official GraphQL API (api.producthunt.com/v2/api/graphql) for higher reliability and comment bodies at scale. Runs on your token / your rate limit. Left empty: the no-login website path is used, which already returns makers, comments and reviews.

## `deduplicate` (type: `boolean`):

Drop records whose dedup key was already produced within this run.

## `maxConcurrency` (type: `integer`):

Number of detail pages fetched in parallel. 6-10 is a good range.

## `maxRequestRetries` (type: `integer`):

How many times to retry a page that could not be retrieved on the first attempt.

## `proxy` (type: `object`):

Optional. Proxies are included and configured automatically — leave this empty and the actor picks the right route for each page on its own. Advanced users can pin their own proxy here.

## Actor input object example

```json
{
  "mode": "leaderboard",
  "leaderboardPeriod": "daily",
  "searchTerms": [
    "AI"
  ],
  "maxItems": 10,
  "maxPages": 0,
  "featuredOnly": false,
  "includePromoted": false,
  "enrichLaunchDetails": true,
  "enrichProductDetails": false,
  "includeMakers": true,
  "includeMedia": true,
  "scrapeComments": false,
  "maxComments": 20,
  "scrapeReviews": false,
  "maxReviews": 20,
  "scrapeLaunchHistory": false,
  "scrapeAlternatives": false,
  "includeBuiltWith": false,
  "makerLeadEnrichment": true,
  "enrichWebsiteEmails": false,
  "verifyEmails": false,
  "deduplicate": true,
  "maxConcurrency": 8,
  "maxRequestRetries": 5
}
```

# Actor output Schema

## `summary` (type: `string`):

What this run produced. Each dataset item is one record (type: launch, product or maker); comments, reviews, tech stack and emails are nested on their parent record. Per-mode counts and any blocked pages are stored under the RUN\_SUMMARY key 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 = {
    "mode": "leaderboard",
    "searchTerms": [
        "AI"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("brilliant_gum/producthunt-scraper").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 = {
    "mode": "leaderboard",
    "searchTerms": ["AI"],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("brilliant_gum/producthunt-scraper").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 '{
  "mode": "leaderboard",
  "searchTerms": [
    "AI"
  ],
  "maxItems": 10
}' |
apify call brilliant_gum/producthunt-scraper --silent --output-dataset

```

## MCP server setup

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

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/jsaTb8l4D1NhgZgfb/builds/drGsnrrZIvvQ4P8uh/openapi.json
