ProductHunt API endpoint
Retrieve Product Hunt leaderboard
Fetches Product Hunt leaderboard data for daily, weekly, monthly, or yearly scopes via Product Hunt GraphQL.
/producthunt/leaderboardParameters
| Name | In | Type | Required | Enum | Example | Description |
|---|---|---|---|---|---|---|
| scope | query | string | No | daily, weekly, monthly, yearly | Leaderboard scope: daily, weekly, monthly, yearly | |
| date | query | string | No | 2026-01-29 | Anchor date in YYYY-MM-DD format. Used to derive missing year/month/day/week values. | |
| year | query | integer | No | 2026 | Leaderboard year override | |
| month | query | integer | No | 1 | Daily/monthly month override | |
| day | query | integer | No | 29 | Daily day override | |
| week | query | integer | No | 5 | Weekly ISO week override | |
| featured | query | boolean | No | Featured products only | ||
| order | query | string | No | Ranking order override. Defaults to scope rank enum. | ||
| cursor | query | string | No | Pagination cursor |
Authentication
Send your scraping API key in the x-api-key header. Use the console API Keys page to rotate or select the active key.
Billing
Endpoint usage is metered in credits. The plan prices, included credits, limits, and overage rates below match the active backend billing configuration.
- Credit cost
- 2 credits/request
- Charged response
- Successful 2xx responses
| Plan | Price | Included credits | Daily cap | Rate limit | Overage |
|---|---|---|---|---|---|
| Free | $0/mo | 2,000 | 500 daily credits | 5/min | No overage |
| Starter | $9/mo | 20,000 | 5,000 daily credits | 15/min | $0.75/1,000 overage credits when enabled |
| Growth | $29/mo | 100,000 | 25,000 daily credits | 45/min | $0.45/1,000 overage credits when enabled |
| Pro | $79/mo | 400,000 | No daily cap | 120/min | $0.30/1,000 overage credits |
| Business | $199/mo | 1,200,000 | No daily cap | 300/min | $0.20/1,000 overage credits |
| Enterprise | $499/mo | 5,000,000 | No daily cap | 1,000/min | $0.12/1,000 overage credits |
Response behavior
- Pass the returned `cursor` value from a previous response to continue pagination. Example response: ```json { "code": 200, "msg": "OK", "data": { "scope": "daily", "featured": true, "order": "DAILY_RANK", "year": 2026, "month": 4, "day": 27, "week": 18, "connection": "homefeedItems", "has_next_page": false, "items": [ { "type": "post", "post": { "id": "1101061", "name": "Kitty Points Leaderboard", "slug": "kitty-points-leaderboard", "tagline": "Find interesting community members and see how you stack up", "latest_score": 140, "daily_rank": 3, "weekly_rank": 9, "comments_count": 18, "product": { "id": "112572", "slug": "producthunt", "name": "Product Hunt" } } } ] } } ```
Failure responses
| Status | Description | Schema |
|---|---|---|
| 400 | Missing or invalid parameters | #/definitions/app.Response |
| 404 | Product not found | #/definitions/app.Response |
| 429 | Rate limit exceeded | #/definitions/app.Response |
| 500 | Internal server error | #/definitions/app.Response |
Example response
{
"code": 200,
"msg": "OK",
"data": {
"scope": "daily",
"featured": true,
"order": "DAILY_RANK",
"year": 2026,
"month": 4,
"day": 27,
"week": 18,
"connection": "homefeedItems",
"has_next_page": false,
"items": [
{
"type": "post",
"post": {
"id": "1101061",
"name": "Kitty Points Leaderboard",
"slug": "kitty-points-leaderboard",
"tagline": "Find interesting community members and see how you stack up",
"latest_score": 140,
"daily_rank": 3,
"weekly_rank": 9,
"comments_count": 18,
"product": {
"id": "112572",
"slug": "producthunt",
"name": "Product Hunt"
}
}
}
]
}
}Request schema
No body schema
Response schema
#/definitions/producthunt.leaderboardResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | producthunt.LeaderboardPage | No | ||||
| data.connection | string | No | ||||
| data.day | integer | No | 29 | |||
| data.end_cursor | string | No | ||||
| data.featured | boolean | No | ||||
| data.golden_kitty_years | array | No | ||||
| data.has_next_page | boolean | No | ||||
| data.items | array | No | ||||
| data.items[].ad | producthunt.LeaderboardAdItem | No | ||||
| data.items[].ad.channel_kind | string | No | ||||
| data.items[].ad.id | string | No | ||||
| data.items[].ad.large_asset_uuid | string | No | ||||
| data.items[].ad.name | string | No | ||||
| data.items[].ad.post | producthunt.LeaderboardAdPost | No | ||||
| data.items[].ad.post.comments_count | integer | No | ||||
| data.items[].ad.post.created_at | string | No | ||||
| data.items[].ad.post.disabled_when_scheduled | boolean | No | ||||
| data.items[].ad.post.embargo_preview_at | string | No | ||||
| data.items[].ad.post.featured_at | string | No | ||||
| data.items[].ad.post.featured_comment | producthunt.ProductCategoryAdComment | No | ||||
| data.items[].ad.post.featured_comment.body_text | string | No | ||||
| data.items[].ad.post.featured_comment.id | string | No | ||||
| data.items[].ad.post.featured_comment.is_pinned | boolean | No | ||||
| data.items[].ad.post.featured_comment.path | string | No | ||||
| data.items[].ad.post.featured_comment.subject_id | string | No | ||||
| data.items[].ad.post.featured_comment.user | producthunt.ProductCategoryUser | No | ||||
| data.items[].ad.post.featured_comment.user.avatar_url | string | No | ||||
| data.items[].ad.post.featured_comment.user.id | string | No | ||||
| data.items[].ad.post.featured_comment.user.name | string | No | ||||
| data.items[].ad.post.featured_comment.user.username | string | No | ||||
| data.items[].ad.post.has_voted | boolean | No | ||||
| data.items[].ad.post.hide_votes_count | boolean | No | ||||
| data.items[].ad.post.id | string | No | ||||
| data.items[].ad.post.latest_score | integer | No | ||||
| data.items[].ad.post.launch_day_score | integer | No | ||||
| data.items[].ad.post.name | string | No | ||||
| data.items[].ad.post.product | producthunt.LeaderboardProductRef | No | ||||
| data.items[].ad.post.product.id | string | No | ||||
| data.items[].ad.post.product.is_no_longer_online | boolean | No | ||||
| data.items[].ad.post.product.is_subscribed | boolean | No | ||||
| data.items[].ad.post.product.is_top_product | boolean | No | ||||
| data.items[].ad.post.product.logo_uuid | string | No | ||||
| data.items[].ad.post.product.name | string | No | ||||
| data.items[].ad.post.product.slug | string | No | ||||
| data.items[].ad.post.randomization_status | producthunt.LeaderboardRandomizationStatus | No | ||||
| data.items[].ad.post.randomization_status.active | boolean | No | ||||
| data.items[].ad.post.randomization_status.next_transition_at | string | No | ||||
| data.items[].ad.post.randomization_status.random_day | boolean | No | ||||
| data.items[].ad.post.randomization_status.randomize_order | boolean | No | ||||
| data.items[].ad.post.slug | string | No | ||||
| data.items[].ad.post.topics | array | No | ||||
| data.items[].ad.post.topics[].id | string | No | ||||
| data.items[].ad.post.topics[].name | string | No | ||||
| data.items[].ad.post.topics[].slug | string | No | ||||
| data.items[].ad.post.updated_at | string | No | ||||
| data.items[].ad.small_asset_uuid | string | No | ||||
| data.items[].ad.subject | string | No | ||||
| data.items[].ad.tagline | string | No | ||||
| data.items[].ad.thumbnail_uuid | string | No | ||||
| data.items[].ad.url | string | No | ||||
| data.items[].ad.variation_id | string | No | ||||
| data.items[].ghost_ad | producthunt.LeaderboardGhostItem | No | ||||
| data.items[].ghost_ad.id | string | No | ||||
| data.items[].ghost_ad.subject | string | No | ||||
| data.items[].post | producthunt.LeaderboardPostItem | No | ||||
| data.items[].post.comments_count | integer | No | ||||
| data.items[].post.created_at | string | No | ||||
| data.items[].post.daily_rank | integer | No | ||||
| data.items[].post.disabled_when_scheduled | boolean | No | ||||
| data.items[].post.embargo_preview_at | string | No | ||||
| data.items[].post.featured_at | string | No | ||||
| data.items[].post.friend_voters_count | integer | No | ||||
| data.items[].post.has_voted | boolean | No | ||||
| data.items[].post.hide_votes_count | boolean | No | ||||
| data.items[].post.id | string | No | ||||
| data.items[].post.is_subscribed | boolean | No | ||||
| data.items[].post.latest_score | integer | No | ||||
| data.items[].post.launch_day_score | integer | No | ||||
| data.items[].post.monthly_rank | integer | No | ||||
| data.items[].post.name | string | No | ||||
| data.items[].post.product | producthunt.LeaderboardProductRef | No | ||||
| data.items[].post.product.id | string | No | ||||
| data.items[].post.product.is_no_longer_online | boolean | No | ||||
| data.items[].post.product.is_subscribed | boolean | No | ||||
| data.items[].post.product.is_top_product | boolean | No | ||||
| data.items[].post.product.logo_uuid | string | No | ||||
| data.items[].post.product.name | string | No | ||||
| data.items[].post.product.slug | string | No | ||||
| data.items[].post.product_state | string | No | ||||
| data.items[].post.randomization_status | producthunt.LeaderboardRandomizationStatus | No | ||||
| data.items[].post.randomization_status.active | boolean | No | ||||
| data.items[].post.randomization_status.next_transition_at | string | No | ||||
| data.items[].post.randomization_status.random_day | boolean | No | ||||
| data.items[].post.randomization_status.randomize_order | boolean | No | ||||
| data.items[].post.scheduled_at | string | No | ||||
| data.items[].post.shortened_url | string | No | ||||
| data.items[].post.slug | string | No | ||||
| data.items[].post.tagline | string | No | ||||
| data.items[].post.thumbnail_image_uuid | string | No | ||||
| data.items[].post.topics | array | No | ||||
| data.items[].post.topics[].id | string | No | ||||
| data.items[].post.topics[].name | string | No | ||||
| data.items[].post.topics[].slug | string | No | ||||
| data.items[].post.updated_at | string | No | ||||
| data.items[].post.weekly_rank | integer | No | ||||
| data.items[].type | string | No | ||||
| data.month | integer | No | 1 | |||
| data.order | string | No | DAILY_RANK | |||
| data.raw_page_info | object | No | ||||
| data.scope | string | No | daily | |||
| data.total_count | integer | No | ||||
| data.week | integer | No | 5 | |||
| data.year | integer | No | 2026 | |||
| msg | string | No | Request successful |
Example request
curl -X GET "https://api.crawlora.net/api/v1/producthunt/leaderboard?date=2026-01-29&year=2026&month=1&day=29&week=5" -H "x-api-key: <api-key>"
TypeScript fetch
const url = new URL("https://api.crawlora.net/api/v1/producthunt/leaderboard");
url.searchParams.set("date", "2026-01-29");
url.searchParams.set("year", "2026");
url.searchParams.set("month", "1");
url.searchParams.set("day", "29");
url.searchParams.set("week", "5");
const headers = new Headers();
headers.set("x-api-key", "<api-key>");
const response = await fetch(url, {
method: "GET",
headers,
});
const payload = await response.json();