# @kentcdodds/producthunt — agent notes Human setup and intent live in [`README.md`](./README.md). This file is for agents: imports, smoke execute snippets, and edge cases. Auth is the saved OAuth integration named **`producthunt`** — never paste tokens. Do not disable live webhooks or jobs. ## Auth / integration | Item | Value | | --- | --- | | Integration name | `producthunt` | | Reconnect | `https://kody.codes/connect/oauth?provider=producthunt` (or `./guide`) | | GraphQL | `https://api.producthunt.com/v2/api/graphql` | | Approved host | `api.producthunt.com` | OAuth-managed secret names (do not paste values): `producthuntAccessToken`, `producthuntClientSecret`. Pass `integration` on helpers only when the saved connection is not named `producthunt`. ## Import paths | Export | Import | | --- | --- | | overview | `kody:@kentcdodds/producthunt` | | types | `kody:@kentcdodds/producthunt/types` | | request | `kody:@kentcdodds/producthunt/request` | | smoke-test | `kody:@kentcdodds/producthunt/smoke-test` | | guide | `kody:@kentcdodds/producthunt/guide` | | get-viewer | `kody:@kentcdodds/producthunt/get-viewer` | | get-user | `kody:@kentcdodds/producthunt/get-user` | | get-post | `kody:@kentcdodds/producthunt/get-post` | | list-posts | `kody:@kentcdodds/producthunt/list-posts` | | list-comments | `kody:@kentcdodds/producthunt/list-comments` | | get-collection | `kody:@kentcdodds/producthunt/get-collection` | | list-collections | `kody:@kentcdodds/producthunt/list-collections` | | get-topic | `kody:@kentcdodds/producthunt/get-topic` | | list-topics | `kody:@kentcdodds/producthunt/list-topics` | Prefer static `kody:@kentcdodds/producthunt/...` imports from `execute`. Do not lead with `packages.invoke`. ## Smoke test (read-only) ```js import smokeTest from 'kody:@kentcdodds/producthunt/smoke-test' export default async function main() { return await smokeTest() // => { ok: true, viewer: { username }, featuredPost: { slug } } } ``` Connect URL / setup metadata (no Product Hunt call beyond local guide): ```js import guide from 'kody:@kentcdodds/producthunt/guide' export default async function main() { return await guide() } ``` ## Common read snippets ```js import listPosts from 'kody:@kentcdodds/producthunt/list-posts' import getPost from 'kody:@kentcdodds/producthunt/get-post' import getViewer from 'kody:@kentcdodds/producthunt/get-viewer' export default async function main() { const featured = await listPosts({ featured: true, first: 5, order: 'RANKING' }) const post = await getPost({ slug: 'clara-ai-sdr' }) const me = await getViewer() return { featured, post, me } } ``` Generic GraphQL escape hatch: ```js import request from 'kody:@kentcdodds/producthunt/request' export default async function main() { return await request({ query: `query TopicBySlug($slug: String!) { topic(slug: $slug) { id name slug } }`, variables: { slug: 'developer-tools' }, }) } ``` ## Edge cases - Page sizes are clamped to **1–20**. - `get-viewer` needs `private` scope; featured lists work with `public`. - There is no Product Hunt OpenAPI surface — transport is `createAuthenticatedFetch('producthunt')` against the GraphQL endpoint. - Prefer dedicated helpers over hand-written GraphQL when one exists. - Write mutations via `request` need Product Hunt app approval + `write` scope. - Never paste Product Hunt OAuth tokens or client secrets into chat or logs.