Product Hunt at a glance
Product Hunt is a ready-to-run Apify actor from abotapi for collecting lead generation data. Its documented output includes type, name, tagline, slug and maker username, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $1.80 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify.
- Runs on
- Apify cloud: console, API, schedules and integrations
- Data type
- Lead Generation, Ecommerce, Automation
- Pricing
- $1.80 per 1,000 results (Free plan), from $1.00 on paid plans
- Output
- Documented below · JSON, CSV, Excel
- Inputs
- 31 options
Extract producthunt.com data including products, launches, keyword search results, maker profiles, reviews, categories, media, social links, product websites, and optional public contact emails.
What Product Hunt can do
- Two ways to find products. Pick keyword mode to auto-generate Product Hunt search URLs, or url mode to paste homepage, search, leaderboard, topic, collection, product, or maker profile links directly.
- Three record types, one dataset. Product listings and single product pages, maker profiles, and (optionally) individual reviews all land in the same dataset with a rowType field to tell them apart.
- Optional detail enrichment on demand. Turn on public contact-email discovery on each product's own website, and/or pull the reviews already published on its Product Hunt page, and only pay the enrichment surcharge on rows actually returned.
- Record-level filters. Keep only products above a minimum review or follower count, or that expose a website or a social/source-code link, so a run returns only what you need.
- Built for recurring runs. Incremental mode returns only new and changed products on repeat runs against the same search or URL set, and unchanged rows are not billed.
- Resume a big pull. Point resumeFromRunId at an interrupted run or dataset and the next run skips everything it already collected, so a large crawl never restarts from zero.
Choose what to collect
These inputs let you configure Product Hunt – Products, Launches, Makers & Reviews. Open the actor on Apify to enter your values and review the current options.
| Input | What it controls |
|---|---|
modestring | Select URL list for fixed Product Hunt pages or Keyword search for generated search pages. Precedence: the selected mode decides which input is used; Start URLs are ignored in Keyword search mode and keyword fields are ignored in URL list mode. |
startUrlsarray | Paste Product Hunt homepage, search (including &page=N), leaderboard (daily, weekly, monthly), topic or topics index, category or categories index, collection, product (legacy /posts/ links are mapped to /products/), or maker profile URLs. Listing pages expand into product records. Maker profiles sit behind an access challenge on some connections: a profile that cannot be read logs a warning and returns no row. |
searchTermsarray | Product Hunt keywords to search. Each term is converted to a Product Hunt search URL and expanded into product rows. |
searchSortstring | Sort applied to generated keyword search URLs. |
searchCategoriesarray | Restrict generated keyword searches to one or more common Product Hunt categories. Leave empty to search all categories. |
searchCategorySlugsarray | Advanced: Product Hunt categories not listed above, as a name shown on the Product Hunt categories page (for example AI Engineer) or a slug (ai-engineer). Names are resolved against the live categories page; an unknown name stops the run with a clear error. Combined with Keyword categories. |
enrichEmailsboolean | When enabled, the Actor checks each product website for public contact emails. Disable for faster Product Hunt-only metadata. |
Show 24 more inputs
| Input | What it controls |
|---|---|
includeReviewsboolean | Include review summaries that are publicly present on Product Hunt product pages. |
outputReviewsAsRowsboolean | When enabled, each extracted review is also saved as its own dataset row after the product row. |
maxReviewsPerProductinteger | Upper bound on review rows per product. The product page embeds only about 3 reviews, so more are loaded from the product's reviews pages (10 per page) until this cap or the product's review count is reached. Defaults to 20; set 0 to omit review details while keeping review counts. Capped at 100. |
maxItemsinteger | Hard cap on total dataset rows. This is the only finite default cap. |
maxSearchResultsPerTerminteger | Maximum search candidates scanned per keyword before record-level filters are applied. Leave empty to scan enough candidates to satisfy Max items. |
minReviewsCountinteger | Only keep product rows with at least this many Product Hunt reviews. Leave empty for no review-count filter. |
minFollowersCountinteger | Only keep product rows with at least this many Product Hunt followers. Leave empty for no follower-count filter. |
websiteRequiredboolean | Only keep products that expose an external website URL. |
socialLinkRequiredboolean | Only keep products that expose at least one external social or source-code link. |
scrapeMakersboolean | Include the launch makers (name, username, profile URL, avatar) on every product row, read from the product page. No extra requests are made. |
saveWebsiteContentboolean | Also save the visible text of each product's own website (first 5,000 characters) in websiteRawText. Off by default; adds one website fetch per product when email harvesting is off. |
archiveDatestring | Scrape that day's leaderboard (adds https://www.producthunt.com/leaderboard/daily/YYYY/M/D to the URLs). Works in any input mode. |
archiveWeekinteger | Scrape that week's leaderboard. The year comes from Archive year, or the current year when empty. |
archiveYearinteger | Alone: the yearly leaderboard. With Archive week: the year of that week. |
filterobject | Optional launch filter: minVotes and maxVotes keep products whose latest launch upvotes fall in the range; topNProducts caps the number of products (never above Max items). |
resumeFromRunIdstring | Paste a previous run ID or dataset ID to continue a large crawl without returning or charging for rows already collected there. Use this after an interrupted run, or when continuing a big pull across another run. For recurring monitoring of the same search, use Incremental mode below instead. |
incrementalModeboolean | Turn this on for daily or recurring monitoring. The first run returns all matching products as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED products. Turn on "Emit unchanged" or "Emit expired" only when you also want those products returned (and billed). Maker and review rows are never suppressed by this mode. State is kept separately for each search/URL and filter/enrichment setup; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above. A product counts as UPDATED when any returned field changes (for example description, tagline, topics, links, followers, review count, rating or reviews). Scrape timestamps, rotating image URL query strings and the order of harvested emails never count; use "Ignore fields when detecting changes" to exclude more. |
stateKeystring | Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the search/URL and filter/enrichment settings, different searches then never mix state with each other. |
emitUnchangedboolean | Off by default. Turn on to also return products that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you specifically want the full snapshot every run. |
emitExpiredboolean | Off by default. Turn on to also return products that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search/URL set, not when Max items or Max search candidates capped it, when a pasted URL starts at a page after the first, or when Resume was used. This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking. |
ignoreFieldsForChangesarray | Field names that must NOT make a product count as UPDATED in incremental mode, for example reviews, media or followersCount. Matches top-level and nested field names; the fields are still returned in the output. Rotating image/CDN URL query strings, scrape timestamps and the order of harvested emails are already ignored automatically. Leave empty to compare every field. |
mcpConnectorsarray | Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON; the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com). |
notionParentPageUrlstring | URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors. |
maxNotifyListingsinteger | Cap on items written to each connector per run. Does not affect the dataset. |
Fields in the output
The documented dataset includes the fields below. Availability can depend on the source page and selected mode.
rowTypeType (text)nameName (text)taglineTagline (text)slugSlug (text)usernameMaker username (text)headlineMaker headline (text)authorNameReview author (text)reviewTextReview text (text)ratingReview rating (number)ratingMaxRating max (number)reviewDateReview date (text)reviewsCountReviews (number)Show 51 more fields
averageRatingAvg rating (number)followersCountFollowers (number)postsCountLaunches (number)productsCountMaker products (number)reviewsExtractedReviews extracted (number)productSlugProduct slug (text)websiteUrlWebsite (link)avatarUrlMaker avatar (link)authorUrlAuthor URL (link)reviewUrlReview URL (link)canonicalUrlProduct Hunt URL (link)sourceUrlSource URL (link)changeTypeChange type (incremental mode) (text)changedFieldsChanged fields (incremental mode) (array)firstSeenAtFirst seen (incremental mode) (date)lastSeenAtLast seen (incremental mode) (date)scrapedAtScraped at (date)votesCountLaunch upvotes (number)commentsCountLaunch comments (number)upvotesUpvotes (number)shortDescriptionShort description (text)launchNameLaunch name (text)dateLaunch date (text)urlURL (link)websiteWebsite (link)imagesImages (array)youtubeVideoUrlVideo (link)makerMakers (array)websiteRawTextWebsite text (text)launchesCountLaunches (number)launchDayScoreLaunch day score (number)dayRankDay rank (number)weekRankWeek rank (number)monthRankMonth rank (number)isPromotedPromoted (boolean)pricingTypePricing (text)wasInYCombinatorY Combinator (boolean)employeeSizeCompany size (text)fundingAmountFunding (text)appStoreUrlApp Store link (link)googlePlayUrlGoogle Play link (link)easeOfUseRatingEase of use (number)reliabilityRatingReliability (number)valueForMoneyRatingValue for money (number)customizationRatingCustomization (number)viewsCountReview views (number)reviews.authorNamereviews authorName (text)reviews.ratingreviews rating (number)reviews.reviewTextreviews reviewText (text)reviews.reviewDatereviews reviewDate (text)reviews.reviewUrlreviews reviewUrl (link)Example output
An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.
{
"rowType": "product",
"id": "product:sample-ai-assistant",
"sourceUrl": "https://www.producthunt.com/products/sample-ai-assistant",
"canonicalUrl": "https://www.producthunt.com/products/sample-ai-assistant",
"slug": "sample-ai-assistant",
"name": "Sample AI Assistant",
"tagline": "Ship features while you sleep",
"description": "An AI pair programmer that opens pull requests for you.",
"logoUrl": "https://ph-files.example.com/sample-logo.png",
"websiteUrl": "https://sample-ai-assistant.example.com",
"twitterUrl": "https://twitter.com/sampleaiassistant",
"githubUrl": "https://github.com/sample-org/sample-ai-assistant",
"votesCount": 350,
"upvotes": 350,
"commentsCount": 10,
"followersCount": 1240,
"reviewsCount": 18,
"postsCount": 3,
"media": [
{
"type": "image",
"url": "https://ph-files.example.com/shot-1.png",
"alt": "Product screenshot",
"width": 1280,
"height": 800
}
],
"mediaCount": 1,
"categories": [
{
"name": "AI Coding Agents",
"path": "/topics/ai-coding-agents",
"slug": "ai-coding-agents"
}
],
"reviews": [
{
"rowType": "review",
"id": "review:sample-ai-assistant:https://www.producthunt.com/products/sample-ai-assistant#review-1",
"productSlug": "sample-ai-assistant",
"productUrl": "https://www.producthunt.com/products/sample-ai-assistant",
"reviewId": "https://www.producthunt.com/products/sample-ai-assistant#review-1",
"reviewUrl": "https://www.producthunt.com/products/sample-ai-assistant#review-1",
"rating": 5,
"ratingMax": 5,
"reviewText": "Cut our release time in half.",
"positiveNotes": [
"Fast setup",
"Great support"
],
"negativeNotes": [],
"reviewDate": "2026-01-14",
"dateModified": "2026-01-14",
"authorName": "Jordan Reviewer",
"authorUrl": "https://www.producthunt.com/@jordan_reviewer",
"authorImage": "https://ph-avatars.example.com/jordan.png",
"scrapedAt": "2026-01-20T09:15:00+00:00"
}
],
"reviewsExtracted": 1,
"averageRating": 4.6,
"searchContext": {
"sourceType": "search",
"discoveryUrl": "https://www.producthunt.com/search?q=ai%20assistant",
"resultPosition": 3,
"keyword": "ai assistant"
},
"scrapedAt": "2026-01-20T09:15:00+00:00",
"harvestedEmails": [
"hello@sample-ai-assistant.example.com"
]
}Ways to use this data
- Lead generation and outreach: collect maker names, product websites and public contact emails for tools in a category you sell into.
- Market and competitor research: track which products launch or gain traction in a topic or category over time.
- Content and newsletter curation: pull recent launches, taglines and descriptions to summarize a day's or week's top products.
- Investor and trend scouting: filter by minimum followers or reviews to surface products gaining real traction, not just noise.
- Directory and profile building: collect maker profiles and the full list of products each maker has shipped.
Before you run
Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.
Questions about this actor
What data does Product Hunt return?
The documented output for Product Hunt includes type, name, tagline, slug, maker username, maker headline, review author and review text. Availability of each field depends on the source page and the selected mode.
How much does Product Hunt cost?
It costs $1.80 per 1,000 results on the Apify Free plan and from $1.00 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.
Can I get only new or changed launches on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Repeat runs against the same search or URL set then return only new and updated products; unchanged ones are suppressed and not billed unless you turn on Emit unchanged.
What do votesCount, upvotes and commentsCount mean?
Product Hunt counts votes and comments per launch. The actor reports the figures of the product's latest launch. They change constantly, so they are left out of change detection in Incremental mode and never mark a product as UPDATED on their own.
Why did my run return an empty dataset instead of failing?
A page that fails to load, or a product page the actor could not read after retries, is logged and skipped rather than failing the whole run: you still get every product that did load. The run stops outright in three cases: an unreadable resumeFromRunId; turning on Incremental mode with resumeFromRunId against a search that already has saved incremental state; or invalid input, such as URL mode with no startUrls, keyword mode with no searchTerms, or an unrecognized mode. Each case gives a clear error message telling you what to change.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
