Skip to main content
Product Hunt needs a developer token on the deployment — its GraphQL API has no anonymous mode. On Nephia’s hosted API it is configured; if you self-host, create an application at producthunt.com/v2/oauth/applications and set PRODUCTHUNT_DEVELOPER_TOKEN. GET /account reports which Sources a deployment offers in capabilities.liveSources.

The launch

A Product Hunt Watch emits a Launch — the product on the page, not a comment about it. Called a Launch and not a Post because that is what Product Hunt calls the thing a reader lands on, and because post belongs to Reddit throughout this API. url is the Product Hunt page, where the votes and the discussion are. website is the maker’s own site, through Product Hunt’s redirect, and stays its own field. featuredAt is a date (2026-09-01), not an instant: it names the day the launch was on the front page, which is how Product Hunt itself talks about it. null means it was never featured, which is true of plenty of posts. votesCount is the only audience number the API reports, and it is what a Feed row shows as reach.

Coverage

A Watch takes a topic and/or a query, and neither is required. “The newest launches” is a real thing to watch on a feed that publishes about a hundred items a day — unlike, say, “everything on Hacker News”, which is fifty an hour. The two work differently, and the difference is visible in what you get:
  • topic narrows what Product Hunt sends. It is the only narrowing the API offers, and it is applied server-side.
  • query is matched here, over the newest page. Product Hunt’s GraphQL v2 has no text search on launches. So a Watch fetches the newest launches — in the topic, if one is set — and keeps the ones whose name, tagline or description carry your term.
The consequence, stated plainly: a term that appears in nothing launched recently finds nothing, however often it appeared last month. This Source answers “did something about X launch today”, not “search Product Hunt’s archive”. A topic slug is developer-tools, never “Developer Tools” — the API 404s on the display name. The match is a case-insensitive substring rather than a whole word, because product names are compounds: Nephia, NephiaAI and nephia.cc are all the same brand appearing in a tagline. Interval: 300–86400 seconds. Cap: 20 active Watches per Account. Each tick costs 1 credit. The floor is five minutes because of what the Source is rather than because of a quota: a page of twenty launches covers hours on a feed this size, and polling faster would re-read the same page. The complexity budget agrees — a developer token allows roughly 6 250 points per 15 minutes and twenty Watches at this floor spend about 1 000.

What an event carries

The first tick asks for the last 24 hours, establishes a silent baseline and emits nothing. A wider first window would swallow a week of launches and leave the first real tick with nothing to report. Later ticks emit launch.created.
Watching for a term across every topic:
webhook_url is optional — without it the Watch still records every match, readable through GET /v1/producthunt/watches/{id}/events. See Webhooks. Not covered: comments on a launch. Deferred rather than silently missing.

Errors

A temporary Product Hunt failure is 503 and is not charged. Product Hunt’s GraphQL server answers 200 with an errors array rather than a status code when a query fails; Nephia reads that and treats it as a platform failure, so the tick is refunded rather than charged for a page it did not get. The Watch reports it in its activity, readable through GET /v1/producthunt/watches/{id}/activity. A deployment with no PRODUCTHUNT_DEVELOPER_TOKEN answers 503 on these routes and omits producthunt from capabilities.liveSources.