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

Scrape Product Hunt daily, weekly and monthly leaderboards, product pages and topics: upvotes, comments, taglines, makers, website links and launch dates. No API key needed.

- **URL**: https://apify.com/tortuga/producthunt-scraper.md
- **Developed by:** [Trevor Ortega](https://apify.com/tortuga) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 launch or listing items

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Product Hunt Scraper

Scrape Product Hunt daily, weekly and monthly leaderboards, product pages and topics: upvotes, comments, taglines, makers, website links and launch dates. No API key needed.

Product Hunt Scraper reads the data Product Hunt's own pages are built from (the GraphQL results embedded in every page) and turns it into a clean dataset. Four modes cover the site: pull every launch from the **daily, weekly or monthly leaderboards** for any date range with rank, upvotes, comment count, topics and launch date; open **product pages** for description, makers, hunter, website, pricing type, rating, reviews summary, followers, launch history, awards and alternatives; list the products of a **topic or category**; or run a **product search**. Optional comment extraction gives you the launch discussion with author handles and maker/hunter flags. No Product Hunt account, API token or browser is needed, and it works on old leaderboards as well as yesterday's. Download JSON, CSV or Excel, or call it from Python, Node, n8n, Make or Google Sheets. You pay only for the items you get.

### What data does Product Hunt Scraper extract?

Every item has a `type` field: `launch`, `product` or `comment`.

#### Launch items (`type: "launch"`, mode `leaderboard`)

| Field | Description |
|---|---|
| `id`, `slug`, `name`, `tagline` | Launch identity as shown on Product Hunt |
| `url`, `productUrl`, `productSlug` | Launch page (`/products/<product>?launch=<slug>`) and the product it belongs to |
| `websiteUrl` | Outbound website link (needs **Include product details**; `null` on plain leaderboard rows) |
| `redirectUrl` | Product Hunt's `/r/p/<id>` redirect to the maker's site (always present) |
| `launchDate` | ISO 8601 with Pacific offset, e.g. `2026-09-03T00:01:00-07:00` |
| `rank`, `leaderboardPeriod`, `leaderboardDate` | Position on the leaderboard you scraped: `daily` + `2026-09-03`, `weekly` + `2026-W36`, `monthly` + `2026-08` |
| `upvotes`, `launchDayUpvotes` | Current upvote count and the count at the end of launch day |
| `commentsCount` | Number of comments |
| `topics` | Topic names, e.g. `["Sales", "SaaS", "Artificial Intelligence"]` |
| `thumbnailUrl` | Launch thumbnail |
| `dailyRank`, `weeklyRank`, `monthlyRank` | Ranks Product Hunt assigned for the day, week and month of the launch |
| `makers`, `hunter` | `[{name, username, url}]` and `{name, username, url}` (public profile handles; needs **Include product details**) |
| `description`, `pricingType`, `badges`, `promoCode`, `promoText` | Full launch description, `free` / `free_options` / `paid`, top-post badges, launch promo (needs **Include product details**) |
| `isFeatured`, `launchState`, `productState` | Featured flag and states as reported by Product Hunt |

#### Product items (`type: "product"`, modes `products`, `topic`, `search`, or **Include product details**)

| Field | Description |
|---|---|
| `id`, `slug`, `name`, `tagline`, `description`, `url` | Product identity and page |
| `websiteUrl`, `websiteDomain` | Maker's website |
| `rating`, `reviewsCount`, `founderReviewsCount`, `ratingDistribution`, `reviewsSummary`, `pros`, `cons` | Review score (0-5), review counts, star histogram, Product Hunt's AI review summary and the most cited pros/cons |
| `followersCount` | Product followers |
| `launchesCount`, `launches`, `latestLaunch`, `firstLaunchDate`, `totalUpvotes` | Number of launches, the most recent launches (`{id, slug, name, tagline, url, launchDate, upvotes, commentsCount, dailyRank, weeklyRank, monthlyRank, badges}`) and the sum of their upvotes |
| `makers`, `hunter`, `pricingType`, `topics` | Team handles, hunter and pricing of the focused launch |
| `categories`, `tags` | Product Hunt categories and tags |
| `alternatives`, `alternativesCount` | `[{slug, name, tagline, url, rating, reviewsCount}]` from the "Alternatives" block |
| `badges`, `goldenKittyAwards` | Top-post awards and Golden Kitty awards |
| `logoUrl`, `media`, `socialLinks`, `iosUrl`, `androidUrl` | Logo, gallery images, `{twitter, linkedin, instagram, github, ...}` and app store redirects |
| `employeeSize`, `fundingAmount`, `wasInYCombinator`, `isTopProduct`, `isClaimed`, `isNoLongerOnline` | Company facts when Product Hunt shows them |
| `source` | `product` (page opened), or `topic` / `category` / `search` for listing summaries, which carry `topicSlug`, `categorySlug` or `searchTerm` |

Listing summaries (`topic`, `search` modes without **Include product details**) contain the subset Product Hunt shows in the list: name, tagline, rating, reviews, followers, launches count, latest launch date, categories, tags, logo.

#### Comment items (`type: "comment"`, **Include comments**)

`id`, `postId`, `postSlug`, `productSlug`, `text` (plain text), `author` `{name, username, url}`, `upvotes`, `createdAt`, `isMaker`, `isHunter`, `parentId` (for replies), `repliesCount`, `isSticky`, `isPinned`, `award`, `url`.

### How to use Product Hunt Scraper

1. Pick a **Mode**.
2. `leaderboard`: set **Date from** / **Date to** (`YYYY-MM-DD`, default yesterday) and the **Leaderboard period**. `products` / `topic`: paste product, launch, topic or category URLs into **Start URLs**. `search`: enter **Search terms**.
3. Turn on **Include product details** for makers, website and product data, and **Include comments** for the discussion.
4. Set **Max items** to cap the run (and the cost). Click **Start**; results appear in the **Dataset** tab.

### Input example

```json
{
  "mode": "leaderboard",
  "leaderboardPeriod": "daily",
  "dateFrom": "2026-09-01",
  "dateTo": "2026-09-07",
  "includeProductDetails": true,
  "includeComments": false,
  "maxItems": 500
}
```

```json
{ "mode": "products", "startUrls": [{ "url": "https://www.producthunt.com/products/notion" }, { "url": "https://www.producthunt.com/posts/ai-toolbox-3-0" }], "includeComments": true, "maxCommentsPerLaunch": 50 }
```

```json
{ "mode": "topic", "startUrls": [{ "url": "https://www.producthunt.com/topics/artificial-intelligence" }], "maxItems": 300 }
```

### Output example

```json
{
  "type": "launch",
  "id": "1239953",
  "slug": "nex-4",
  "name": "Nex",
  "tagline": "Claude Cowork for high-volume GTM workflows",
  "url": "https://www.producthunt.com/products/nex-4?launch=nex-4",
  "productUrl": "https://www.producthunt.com/products/nex-4",
  "websiteUrl": "https://nex.ai",
  "launchDate": "2026-09-03T00:01:00-07:00",
  "rank": 1,
  "leaderboardPeriod": "daily",
  "leaderboardDate": "2026-09-03",
  "upvotes": 356,
  "launchDayUpvotes": 325,
  "commentsCount": 27,
  "topics": ["Sales", "SaaS", "Artificial Intelligence"],
  "thumbnailUrl": "https://ph-files.imgix.net/7d330afb-0e5a-48fa-8c93-85ff4b8e62e6.png?auto=format",
  "pricingType": "free_options",
  "makers": [{ "name": "Francisco Dias", "username": "frandias", "url": "https://www.producthunt.com/@frandias" }],
  "hunter": { "name": "Najmuzzaman Mohammad", "username": "najmuzzaman", "url": "https://www.producthunt.com/@najmuzzaman" },
  "dailyRank": 1,
  "weeklyRank": 10,
  "monthlyRank": 9,
  "badges": [{ "type": "TopPostBadge", "position": 1, "period": "daily", "date": "2026-09-03" }]
}
```

```json
{
  "type": "product",
  "slug": "notion",
  "name": "Notion",
  "tagline": "The all-in-one workspace",
  "url": "https://www.producthunt.com/products/notion",
  "websiteUrl": "https://www.notion.so",
  "rating": 4.83,
  "reviewsCount": 1393,
  "followersCount": 18552,
  "launchesCount": 25,
  "launches": [{ "slug": "ship-os-by-notion", "name": "Ship OS by Notion", "launchDate": "2026-07-10T00:01:00-07:00", "upvotes": 170, "dailyRank": 9 }],
  "makers": [{ "name": "Ryan Nystrom", "username": "_ryannystrom", "url": "https://www.producthunt.com/@_ryannystrom" }],
  "categories": ["Note and writing apps", "Project management software"],
  "alternatives": [{ "slug": "fibery", "name": "Fibery", "rating": 4.95, "reviewsCount": 37 }],
  "socialLinks": { "twitter": "https://x.com/notion", "linkedin": "https://www.linkedin.com/company/notionhq/" }
}
```

### How to scrape the Product Hunt daily leaderboard

Leave **Mode** on `leaderboard`, set **Date from** and **Date to** to the days you want (Product Hunt days roll over at midnight US Pacific time; yesterday is the latest complete day) and keep **Leaderboard period** on `daily`. Each day yields every featured launch in rank order with `rank`, `upvotes`, `commentsCount`, `topics` and `launchDate`. Use a **Schedule** to run it every morning and build a launch history, or pass leaderboard URLs such as `https://www.producthunt.com/leaderboard/daily/2026/9/3` in **Start URLs** instead of dates.

### Can I get the weekly and monthly leaderboards?

Yes. Set **Leaderboard period** to `weekly` or `monthly`; every ISO week or month touched by the date range is scraped, and the whole ranking is paged through (not just the first 20 rows that the page shows on load) until **Max items** is reached. `leaderboardDate` is `2026-W36` or `2026-08` accordingly.

### How to get makers, hunter and website of each launch

Turn on **Include product details**. The Actor opens each launch page (one extra request per launch) and fills `makers`, `hunter`, `websiteUrl`, `description`, `pricingType` and `badges` on the launch item, and also saves one `product` item per product with rating, reviews, followers, launch history and alternatives. Maker and hunter fields contain only the public display name and `@username` shown on Product Hunt; no emails, no private profile data.

### How to scrape Product Hunt comments

Turn on **Include comments** (in `leaderboard` or `products` mode). Each launch's discussion is saved as `comment` items with plain `text`, `author`, `upvotes`, `createdAt`, `isMaker` / `isHunter` flags and `parentId` for replies, up to **Max comments per launch**. The first page comes with the launch page; further pages are loaded through the site's own GraphQL endpoint.

### Does it work without a Product Hunt account or API key?

Yes. The Actor reads the public pages exactly as a logged-out visitor sees them; it does not use the official Product Hunt API, so there are no API tokens, rate-limit quotas or OAuth apps to manage. Pages are fetched with browser-grade TLS and retried with a fresh proxy session on 403/429, which is why it keeps working when simple HTTP scrapers get blocked.

### What does it cost?

Pay per item, no subscription and no start fee: a leaderboard launch or listing row costs a tenth of a cent, a product item (one page opened) a third of a cent, a comment a twentieth of a cent. A daily leaderboard with about 20 launches costs about 2 cents without details and about 8 cents with product details. Apify's free plan covers hundreds of leaderboards a month.

### Integrations and API

Use the run in Zapier, Make, n8n, Google Sheets, or call it from Python/Node with the Apify client. See the **API** tab for ready-made snippets, or schedule the Actor to keep a launch feed fresh.

### Is it legal to scrape Product Hunt?

This Actor collects only publicly available data that Product Hunt shows to anyone without an account: launches, products, upvote counts, topics, comments and the public handles of makers and hunters. It does not log in and does not collect emails, phone numbers or other private details. You are responsible for how you use the data and for complying with Product Hunt's terms and applicable law.

### Support

Found a bug or need a field added? Open an issue in the **Issues** tab; it is usually answered within a day.

# Actor input Schema

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

`leaderboard`: launches from the daily, weekly or monthly leaderboards between **Date from** and **Date to** (rank, upvotes, comments, topics). `products`: one product item per product/launch URL in **Start URLs** (description, makers, website, rating, launch history, alternatives). `topic`: products listed on topic or category pages in **Start URLs**. `search`: products matching each of **Search terms**.

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

First leaderboard date, `YYYY-MM-DD` (Product Hunt days are US Pacific time). Default: yesterday. Used by `leaderboard` mode.

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

Last leaderboard date, `YYYY-MM-DD` (inclusive). Default: same as **Date from**. Used by `leaderboard` mode.

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

`daily`: one leaderboard per day in the range. `weekly`: every ISO week touched by the range. `monthly`: every month touched by the range.

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

Product Hunt URLs, one per line. `products` mode: product or launch pages such as `https://www.producthunt.com/products/notion` or `https://www.producthunt.com/posts/notion-ai` (a bare slug like `notion` works too). `topic` mode: topic or category pages such as `https://www.producthunt.com/topics/artificial-intelligence` or `https://www.producthunt.com/categories/ai-coding-agents`. `leaderboard` mode: optional leaderboard URLs that replace the date range.

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

Queries for `search` mode, one per line, e.g. `notion`, `ai video editor`. Returns the products Product Hunt's own search shows, page by page, up to **Max items**.

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

Overall cap on dataset items for the run (launches + products + comments). Keeps cost predictable.

## `includeProductDetails` (type: `boolean`):

Open the page of every launch/product found (one extra request each). Launch items get makers, hunter, website URL, description, pricing type and badges, and one `product` item per product is added (rating, reviews, followers, launch history, alternatives, social links). Always on in `products` mode.

## `includeComments` (type: `boolean`):

Also save `comment` items for each launch: text, author handle, upvotes, date, maker/hunter flag, reply parent. Implies opening the launch page. Up to **Max comments per launch** per launch.

## `maxCommentsPerLaunch` (type: `integer`):

Cap on comments (threads + replies) saved per launch when **Include comments** is on. The first page (about 7 threads with replies) costs no extra request; further pages are loaded through Product Hunt's GraphQL API.

## `proxyConfiguration` (type: `object`):

Product Hunt blocks datacenter IPs, so residential Apify Proxy is the default. Proxy usage is billed to your account.

## Actor input object example

```json
{
  "mode": "leaderboard",
  "leaderboardPeriod": "daily",
  "startUrls": [
    {
      "url": "https://www.producthunt.com/products/notion"
    }
  ],
  "searchTerms": [
    "ai video editor"
  ],
  "maxItems": 200,
  "includeProductDetails": false,
  "includeComments": false,
  "maxCommentsPerLaunch": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "startUrls": [
        {
            "url": "https://www.producthunt.com/products/notion"
        }
    ],
    "searchTerms": [
        "ai video editor"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tortuga/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 = {
    "startUrls": [{ "url": "https://www.producthunt.com/products/notion" }],
    "searchTerms": ["ai video editor"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("tortuga/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 '{
  "startUrls": [
    {
      "url": "https://www.producthunt.com/products/notion"
    }
  ],
  "searchTerms": [
    "ai video editor"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call tortuga/producthunt-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tortuga/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/OoBOaufFaxMEnSlvo/builds/yTGPcn7S9NCiXCOGn/openapi.json
