# Product Hunt Launches Scraper (`automation-lab/product-hunt-launch-feed-scraper`) Actor

Export the public Product Hunt Atom feed with launch titles, URLs, content, authors, and timestamps for one-time research or recurring daily monitoring.

- **URL**: https://apify.com/automation-lab/product-hunt-launch-feed-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.76 / 1,000 item extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Launches Scraper

Export the current public **Product Hunt launches** feed as structured JSON, CSV, Excel, or API-ready dataset records.

The Actor reads Product Hunt's public Atom feed and returns each launch's title, product URL, content, author, published time, and updated time. Optional keyword and recency filters make the same feed useful for one-time research or scheduled daily product monitoring.

### What does Product Hunt Launches Scraper do?

Product Hunt Launches Scraper turns the public feed at `https://www.producthunt.com/feed` into normalized dataset rows.

It can:

- export the current launch feed without a Product Hunt API key or login;
- filter launches by words found in the title, content, or author;
- select records updated or published within a rolling number of hours;
- keep both normalized text and the original feed HTML;
- preserve Product Hunt's stable entry and post identifiers;
- run on an Apify schedule for recurring monitoring;
- feed results into webhooks, datasets, spreadsheets, or another Actor.

This is a focused feed exporter. It does not scrape votes, comments, topics, maker profiles, historical rankings, or arbitrary product-detail pages.

### Who is it for?

**Product and market researchers** can collect a repeatable daily snapshot of launch names, summaries, links, and timestamps.

**Competitive-intelligence teams** can filter the feed for categories, technologies, or competitor terms and compare scheduled datasets downstream.

**Developers** can use the Actor as a credential-free Product Hunt API alternative for the fields exposed by the public Atom feed.

**No-code operators** can schedule a run and connect its dataset to Zapier, Make, Google Sheets, Slack, or a webhook.

**Newsletters and content teams** can collect current launches before editorial review. Always verify source content before republishing it.

### Why use this Actor?

- **No Product Hunt credentials:** the source is the public Atom feed.
- **Direct structured route:** no browser, residential proxy, or page rendering is needed.
- **Typed output:** dates are normalized to ISO 8601 UTC and identifiers have stable fields.
- **Monitoring controls:** rolling updated/published windows work naturally with schedules.
- **Useful content choices:** retain source HTML or request plain text only.
- **Fail-closed behavior:** malformed input and invalid upstream responses fail clearly rather than returning misleading rows.

### What Product Hunt data is extracted?

| Field | Type | Meaning |
| --- | --- | --- |
| `entryId` | string | Stable Product Hunt Atom entry ID |
| `productId` | string or null | Numeric post ID parsed from the entry ID |
| `title` | string | Product or launch title |
| `url` | string | Product Hunt product page URL |
| `content` | string or null | Normalized plain-text summary and feed links |
| `contentHtml` | string or null | Original HTML summary when enabled |
| `author` | string or null | Author name exposed by the feed |
| `publishedAt` | ISO date | Product Hunt published timestamp in UTC |
| `updatedAt` | ISO date | Feed update timestamp in UTC |
| `feedPosition` | integer | One-based position in the fetched feed |
| `sourceFeedUrl` | URL | Canonical feed URL used by the run |
| `scrapedAt` | ISO date | Time the Actor processed the feed |

Nullable fields reflect the public source: Product Hunt may omit optional values from an entry.

### Getting started

1. Open Product Hunt Launches Scraper in Apify Console.
2. Leave the prefilled `maxItems` and `includeContentHtml` settings for a first run.
3. Optionally add keywords or a rolling time window.
4. Click **Start**.
5. Open the **Dataset** tab when the run succeeds.
6. Export records as JSON, CSV, Excel, XML, or RSS, or consume the dataset API URL.
7. For recurring monitoring, create an Apify schedule and use `updatedWithinHours` to match the schedule interval.

A first run needs no proxy configuration, login, token, Product Hunt account, or custom feed URL.

### Input parameters

#### `maxItems`

Maximum matching records to save from the current feed.

- Default: `20`
- Minimum: `1`
- Maximum: `100`

The public feed currently has a bounded set of entries. Asking for 100 does not invent historical data; the Actor stops when the feed is exhausted.

#### `keywords`

Optional list of up to 20 case-insensitive terms. A launch matches when any term occurs in its title, content, or author name.

Use an empty list to export the feed without keyword filtering.

#### `updatedWithinHours`

Optional rolling window from 1 to 8760 hours. This tests the Atom entry's `updated` timestamp and is the recommended filter for scheduled change monitoring.

#### `publishedWithinHours`

Optional rolling window from 1 to 8760 hours. This tests the source `published` timestamp. Product Hunt may publish a product before the entry is updated in the current daily feed, so this filter can return fewer records than `updatedWithinHours`.

#### `includeContentHtml`

When `true`, `contentHtml` retains the original Atom HTML. When `false`, the Actor still emits normalized `content` but sets `contentHtml` to `null`.

### Input examples

Export the current feed:

```json
{
  "maxItems": 20,
  "includeContentHtml": true
}
```

Find AI-related launches:

```json
{
  "maxItems": 10,
  "keywords": ["AI", "artificial intelligence"],
  "includeContentHtml": false
}
```

Monitor entries updated during the last day:

```json
{
  "maxItems": 100,
  "updatedWithinHours": 24,
  "includeContentHtml": false
}
```

### Output example

A current feed record has this shape:

```json
{
  "entryId": "tag:www.producthunt.com,2005:Post/1227752",
  "productId": "1227752",
  "title": "Enter Pro",
  "url": "https://www.producthunt.com/products/enter-pro",
  "content": "The AI-native platform to build and scale your apps Discussion | Link",
  "contentHtml": null,
  "author": "Rohan Chaubey",
  "publishedAt": "2026-08-20T14:14:52.000Z",
  "updatedAt": "2026-08-27T14:41:02.000Z",
  "feedPosition": 1,
  "sourceFeedUrl": "https://www.producthunt.com/feed",
  "scrapedAt": "2026-08-27T14:41:45.481Z"
}
```

The default dataset is the primary integration output. Filtering happens before charging and saving, so rejected and duplicate-free nonmatching entries do not become dataset items.

### How much does it cost to export Product Hunt launches?

The Actor uses pay-per-event pricing:

- one `start` event per run;
- one `item` event for each saved launch record;
- no charge for feed entries rejected by your filters.

At the BRONZE rate, the start event is **$0.005** and each saved item is **$0.012936**. Tier prices decrease for higher Apify account tiers.

Approximate BRONZE examples:

| Saved launches | BRONZE calculation |
| ---: | --- |
| 1 | $0.005 start + 1 × $0.012936 per item |
| 10 | $0.005 start + 10 × $0.012936 per item |
| 50 | $0.005 start + 50 × $0.012936 per item |

The actual run charge is shown in Apify Console. The final number depends on saved items and the pricing tier assigned to your account, not on how many feed entries are inspected.

### Daily launch monitoring workflow

1. Create a Task with `updatedWithinHours` set to your schedule interval plus a small overlap.
2. Set `maxItems` high enough to accept all matching current-feed entries.
3. Run the Task daily or several times per day with an Apify schedule.
4. Send completed-run data to a webhook or integration.
5. Deduplicate downstream by stable `entryId` and compare `updatedAt` to detect changes.
6. Keep the newest record for an ID when monitoring across multiple datasets.

The Actor does not maintain a private historical database or send alerts itself. Apify schedules, dataset retention, webhooks, and your downstream workflow provide those capabilities.

### API usage

Replace `YOUR_APIFY_TOKEN` with an Apify API token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~product-hunt-launch-feed-scraper/runs?token=YOUR_APIFY_TOKEN&waitForFinish=120" \
  -H "Content-Type: application/json" \
  -d '{"maxItems":20,"updatedWithinHours":24,"includeContentHtml":false}'
```

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/product-hunt-launch-feed-scraper').call({
  maxItems: 20,
  updatedWithinHours: 24,
  includeContentHtml: false,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("automation-lab/product-hunt-launch-feed-scraper").call(
    run_input={
        "maxItems": 20,
        "updatedWithinHours": 24,
        "includeContentHtml": False,
    }
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with Apify MCP

Add this Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/product-hunt-launch-feed-scraper"
```

Claude Desktop, Cursor, and VS Code use this MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/product-hunt-launch-feed-scraper"
    }
  }
}
```

Example prompts:

- “Run Product Hunt Launches Scraper and return the first 20 current launches.”
- “Find launch feed records mentioning AI and summarize their source URLs.”
- “Export Product Hunt records updated during the last 24 hours.”

### Integrations

Use the default dataset with:

- Apify webhooks for completed-run delivery;
- Google Sheets for a lightweight daily launch log;
- Make or Zapier for no-code routing;
- Slack or email steps after downstream filtering;
- BigQuery, Snowflake, or a database for historical comparison;
- another Actor for enrichment using the emitted Product Hunt URLs.

Stable `entryId`, `productId`, `url`, and timestamps make dataset joins and deduplication straightforward.

### Limits and freshness

- The Actor exports only entries currently exposed by Product Hunt's public Atom feed.
- It does not provide full history or arbitrary date pagination.
- Feed order and contents are controlled by Product Hunt and can change.
- `publishedAt` and `updatedAt` have different meanings and can be far apart.
- Keyword matching is a case-insensitive substring match, not semantic classification.
- Content is source-provided and can contain links or markup.
- The Actor makes one bounded feed request per attempt and retries only transient network, 429, and 5xx failures.
- A successful no-result run is possible when filters match no current entry.

### Troubleshooting

**The dataset is empty**

Remove keyword and time filters, then run the prefilled input. A narrow `publishedWithinHours` filter often excludes entries that were published earlier but updated today.

**The run failed with an upstream HTTP or content-type error**

Product Hunt may be temporarily unavailable or may have changed the public feed. Retry later after checking the run log. Deterministic invalid responses are not silently treated as empty datasets.

**I requested 100 items but received fewer**

`maxItems` is a ceiling. The public feed may contain fewer records, and filters can reduce the result further.

**Where are votes, comments, topics, and maker profiles?**

Those fields are not in this focused public-feed contract. This Actor intentionally avoids claiming product-detail or authenticated API data.

### Responsible use and legality

This Actor accesses a public Product Hunt feed without bypassing login or access controls.

You are responsible for:

- following Product Hunt's applicable terms and policies;
- respecting copyright, database rights, and attribution requirements;
- using personal names lawfully and only for a legitimate purpose;
- avoiding spam, harassment, profiling, or automated republishing without review;
- securing exported datasets and complying with applicable privacy law;
- checking source content before making decisions or publishing summaries.

Public availability does not remove your legal or contractual responsibilities.

### Related Actors

This Actor is intentionally standalone within the Automation Lab portfolio: no currently active Automation Lab Actor provides a directly complementary Product Hunt feed workflow that can be recommended honestly.

For enrichment, pass emitted `url` values into your own approved downstream workflow or use Apify integrations rather than assuming this Actor includes product-page details.

### FAQ

**Does it require a Product Hunt API token?**

No. It reads the public Atom feed.

**Does it require an Apify proxy?**

No. The current implementation uses direct HTTP and has no user-triggerable proxy fallback.

**Can it scrape a specific historical date?**

No. It filters the records currently present in the feed; it does not paginate a historical archive.

**Can I monitor only one topic?**

Use `keywords` for terms found in the launch title, content, or author. This is text filtering, not Product Hunt topic metadata.

**Are unchanged entries charged?**

Every record saved by a run emits one `item` charge.

To limit repeated records, use a rolling update window and deduplicate across runs by `entryId` and `updatedAt`.

**Can I disable source HTML?**

Yes. Set `includeContentHtml` to `false`; normalized plain text remains available in `content`.

**Will an empty match be treated as a failure?**

No. Valid filters that match no current entries produce a successful run with an empty dataset. Invalid input or an invalid upstream response fails clearly.

# Actor input Schema

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

Maximum number of matching launch records to save from the current feed.

## `keywords` (type: `array`):

Optional case-insensitive keywords. A launch is included when any keyword appears in its title, content, or author name.

## `updatedWithinHours` (type: `integer`):

Optionally include only feed records updated within this many hours. Useful for scheduled monitoring runs.

## `publishedWithinHours` (type: `integer`):

Optionally include only products whose Product Hunt published timestamp falls within this many hours.

## `includeContentHtml` (type: `boolean`):

Include the original HTML summary alongside normalized plain text.

## Actor input object example

```json
{
  "maxItems": 20,
  "keywords": [],
  "includeContentHtml": true
}
```

# Actor output Schema

## `overview` (type: `string`):

Open all saved launch records in the overview dataset view.

# 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 = {
    "maxItems": 20,
    "keywords": [],
    "includeContentHtml": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/product-hunt-launch-feed-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 = {
    "maxItems": 20,
    "keywords": [],
    "includeContentHtml": True,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/product-hunt-launch-feed-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 '{
  "maxItems": 20,
  "keywords": [],
  "includeContentHtml": true
}' |
apify call automation-lab/product-hunt-launch-feed-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/product-hunt-launch-feed-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/JnZaZ5zFi6yrXVonk/builds/2MQ4w208pB82mmzDS/openapi.json
