{
  "openapi": "3.1.0",
  "info": {
    "title": "Product Hunt API",
    "version": "1.0.0",
    "description": "Product Hunt products, launches, comment threads, leaderboards, topics, collections and maker profiles exposed through FetchLayer."
  },
  "servers": [
    {
      "url": "https://api.fetchlayer.dev/producthunt"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key",
        "description": "Send your FetchLayer key as Authorization: Bearer ss-your-key."
      }
    }
  },
  "paths": {
    "/search-products": {
      "post": {
        "operationId": "search-products",
        "tags": [
          "Products"
        ],
        "summary": "Search products by keyword",
        "description": "Search Product Hunt for products matching a keyword or phrase. Each match comes back with its slug, tagline, logo, review count and average rating, plus a cursor to page deeper. Use it to find the slug that product-detail and product-comments take.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string",
                    "description": "Keyword or phrase to search Product Hunt for."
                  },
                  "limit": {
                    "type": "number",
                    "description": "Maximum products returned (max 500), or -1 for everything available.",
                    "example": "30"
                  },
                  "pages": {
                    "type": "number",
                    "description": "Pages of results to collect in one request (max 100), or -1 for the maximum allowed. Each page walked counts as one request.",
                    "example": "1"
                  },
                  "cursor": {
                    "type": "string",
                    "description": "Resume from a previous response's nextCursor."
                  },
                  "delayMs": {
                    "type": "number",
                    "description": "Milliseconds to wait between pages (max 30000)."
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown. Markdown returns the same result rendered as text.",
                    "example": "json"
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "query"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "query": "ai note taking",
                    "limit": 30
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string",
                      "description": "The keyword the search ran with."
                    },
                    "products": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "slug": {
                            "type": "string",
                            "description": "Product slug — the handle for product-detail and product-comments."
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Product name."
                          },
                          "tagline": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The one-line pitch shown under the name."
                          },
                          "url": {
                            "type": "string",
                            "description": "Public Product Hunt page for the product."
                          },
                          "logoUrl": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Logo image URL. Pass it to GET /media to download the file."
                          },
                          "reviewsCount": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "How many reviews the product has."
                          },
                          "reviewsRating": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Average review rating."
                          },
                          "followersCount": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Followers on Product Hunt."
                          },
                          "launchesCount": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "How many times the product has launched."
                          },
                          "isNoLongerOnline": {
                            "type": "boolean",
                            "description": "Whether Product Hunt has marked the product as dead."
                          }
                        }
                      },
                      "description": "The matching products."
                    },
                    "productCount": {
                      "type": "number",
                      "description": "Number of products in this response."
                    },
                    "pagesAvailable": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "Total pages Product Hunt reports for this query, where it reports one."
                    },
                    "pagesScraped": {
                      "type": "number",
                      "description": "Pages actually collected. Each page counts as one request against your plan."
                    },
                    "pagesRequested": {
                      "type": "number",
                      "description": "Pages the request asked for."
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass back as cursor to continue, or null when the listing is exhausted."
                    },
                    "hasNextPage": {
                      "type": "boolean",
                      "description": "Whether more results are available beyond this response."
                    },
                    "requestedUrl": {
                      "type": "string",
                      "description": "The Product Hunt page this result corresponds to."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO timestamp the result was collected at."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Read this. Caveats about this specific result — a walk that stopped early, an upstream ceiling, or promoted entries that were dropped. An empty array means nothing was held back."
                    },
                    "blocked": {
                      "type": "boolean",
                      "description": "Always false on a successful response."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "query": "ai note taking",
                      "productCount": 30,
                      "pagesScraped": 1,
                      "hasNextPage": true,
                      "notes": [],
                      "products": [
                        {
                          "slug": "granola",
                          "name": "Granola",
                          "tagline": "The AI notepad for people in back-to-back meetings",
                          "reviewsCount": 214,
                          "reviewsRating": 4.9,
                          "launchesCount": 3
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/product-detail": {
      "post": {
        "operationId": "product-detail",
        "tags": [
          "Products"
        ],
        "summary": "Read a product and its launch",
        "description": "Read one product in full — description, website, categories, follower and review counts, screenshots and gallery media — together with a launch: its tagline, upvotes, comment count, launch date, daily, weekly and monthly rank, topics, makers, hunter and ranking badges. Defaults to the product's most recent launch; pass a launch slug for an older one, or includeLaunches to list every launch it has had.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "product": {
                    "type": "string",
                    "description": "Product slug (for example \"notion\"), or any Product Hunt product or launch URL."
                  },
                  "launch": {
                    "type": "string",
                    "description": "A specific launch slug or launch URL, instead of the product's most recent launch."
                  },
                  "includeLaunches": {
                    "type": "boolean",
                    "description": "Also list every launch the product has had, newest first.",
                    "example": "false"
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown.",
                    "example": "json"
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "product"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "product": "notion",
                    "includeLaunches": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "product": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The product record.",
                      "properties": {
                        "slug": {
                          "type": "string",
                          "description": "Product slug."
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The full product description."
                        },
                        "websiteUrl": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The maker's own site, with websiteDomain alongside it."
                        },
                        "categories": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Categories the product sits under."
                        },
                        "socialLinks": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Public social profiles listed on the product."
                        },
                        "media": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Gallery items: images carry url, videos carry the platform and id."
                        },
                        "reviewsRating": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Average review rating, with reviewsCount alongside it."
                        }
                      }
                    },
                    "launch": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "additionalProperties": true,
                      "description": "The requested launch, or the most recent one. Null if the product has never launched.",
                      "properties": {
                        "upvotes": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Upvotes on the launch."
                        },
                        "launchDayUpvotes": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Upvotes as of the end of launch day, where that differs from the current total."
                        },
                        "launchedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "When it launched. Null while a launch is still scheduled."
                        },
                        "dailyRank": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Rank on its launch day, with weeklyRank and monthlyRank alongside it."
                        },
                        "launchNumber": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "1 for a product's first launch."
                        },
                        "topics": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Topics the launch was filed under."
                        },
                        "makers": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "The people credited as makers."
                        },
                        "hunter": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "additionalProperties": true,
                          "description": "Whoever posted the launch, who is not always one of the makers."
                        },
                        "badges": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Ranking ribbons the launch earned, such as #1 Product of the Day."
                        }
                      }
                    },
                    "launches": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Every launch of the product, newest first, when includeLaunches was set."
                    },
                    "launchCount": {
                      "type": "number",
                      "description": "How many launches the product has had."
                    },
                    "requestedUrl": {
                      "type": "string",
                      "description": "The Product Hunt page this result corresponds to."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO timestamp the result was collected at."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Read this. Caveats about this specific result — a walk that stopped early, an upstream ceiling, or promoted entries that were dropped. An empty array means nothing was held back."
                    },
                    "blocked": {
                      "type": "boolean",
                      "description": "Always false on a successful response."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "product": {
                        "slug": "notion",
                        "name": "Notion",
                        "tagline": "The all-in-one workspace",
                        "reviewsRating": 4.8,
                        "launchesCount": 12
                      },
                      "launch": {
                        "name": "Notion 3.0",
                        "upvotes": 2841,
                        "commentsCount": 312,
                        "launchedAt": "2026-08-19",
                        "dailyRank": 1,
                        "launchNumber": 12
                      },
                      "launchCount": 12,
                      "notes": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/product-comments": {
      "post": {
        "operationId": "product-comments",
        "tags": [
          "Launches"
        ],
        "summary": "Get a launch's comment threads",
        "description": "Pull the comment threads on a launch — the maker's own notes, the questions, and the feedback launch day produces. Replies come back nested underneath their parent comment rather than flattened into one list, so walk comments[].replies recursively. Sort by score, date or votes, and page through with a cursor.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "product": {
                    "type": "string",
                    "description": "Product slug, launch slug, or any Product Hunt product or launch URL."
                  },
                  "launch": {
                    "type": "string",
                    "description": "A specific launch, instead of the product's most recent one."
                  },
                  "limit": {
                    "type": "number",
                    "description": "Maximum comments returned (max 300), or -1 for everything available. Counts replies too.",
                    "example": "30"
                  },
                  "pageSize": {
                    "type": "number",
                    "description": "Comment threads fetched per page (max 50).",
                    "example": "10"
                  },
                  "sortBy": {
                    "type": "string",
                    "description": "SCORE, DATE, DATE_DESC, VOTES, or DEFAULT.",
                    "example": "SCORE"
                  },
                  "pages": {
                    "type": "number",
                    "description": "Pages of results to collect in one request (max 100), or -1 for the maximum allowed. Each page walked counts as one request.",
                    "example": "1"
                  },
                  "cursor": {
                    "type": "string",
                    "description": "Resume from a previous response's nextCursor."
                  },
                  "delayMs": {
                    "type": "number",
                    "description": "Milliseconds to wait between pages (max 30000)."
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown. Markdown returns the same result rendered as text.",
                    "example": "json"
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "product"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "product": "notion",
                    "sortBy": "SCORE",
                    "limit": 50,
                    "pageSize": 20
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "launchSlug": {
                      "type": "string",
                      "description": "The launch the comments belong to."
                    },
                    "launchName": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Name of that launch."
                    },
                    "commentsCount": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "Every comment on the launch, as Product Hunt counts them."
                    },
                    "threadCount": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "Top-level threads on the launch."
                    },
                    "comments": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "body": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The comment text with the markup removed. bodyHtml carries it as posted."
                          },
                          "author": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "additionalProperties": true,
                            "description": "Who wrote it: username, name and avatar."
                          },
                          "badges": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Labels shown beside the author, such as \"maker\"."
                          },
                          "votes": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Upvotes on the comment."
                          },
                          "isPinned": {
                            "type": "boolean",
                            "description": "Whether the comment is pinned to the top of the thread."
                          },
                          "repliesCount": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "How many replies the comment has, which can exceed the number nested in replies when a walk stopped early."
                          },
                          "replies": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "description": "Replies, in the same shape, nested to whatever depth the thread reaches."
                          }
                        }
                      },
                      "description": "Top-level threads. Each one carries its replies nested underneath in comments[].replies — the tree is not flattened."
                    },
                    "returnedCount": {
                      "type": "number",
                      "description": "Comments in this response, replies included."
                    },
                    "pagesScraped": {
                      "type": "number",
                      "description": "Pages actually collected. Each page counts as one request against your plan."
                    },
                    "pagesRequested": {
                      "type": "number",
                      "description": "Pages the request asked for."
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass back as cursor to continue, or null when the listing is exhausted."
                    },
                    "hasNextPage": {
                      "type": "boolean",
                      "description": "Whether more results are available beyond this response."
                    },
                    "requestedUrl": {
                      "type": "string",
                      "description": "The Product Hunt page this result corresponds to."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO timestamp the result was collected at."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Read this. Caveats about this specific result — a walk that stopped early, an upstream ceiling, or promoted entries that were dropped. An empty array means nothing was held back."
                    },
                    "blocked": {
                      "type": "boolean",
                      "description": "Always false on a successful response."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "launchSlug": "notion-3-0",
                      "commentsCount": 312,
                      "threadCount": 128,
                      "returnedCount": 50,
                      "hasNextPage": true,
                      "notes": [
                        "Reply walk stopped at depth 3 on 2 threads."
                      ],
                      "comments": [
                        {
                          "body": "Congrats on the launch! How does this handle offline edits?",
                          "author": {
                            "username": "jane"
                          },
                          "badges": [],
                          "votes": 24,
                          "repliesCount": 2,
                          "replies": [
                            {
                              "body": "Offline edits sync on reconnect.",
                              "author": {
                                "username": "ivan"
                              },
                              "badges": [
                                "maker"
                              ],
                              "replies": []
                            }
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/leaderboard": {
      "post": {
        "operationId": "leaderboard",
        "tags": [
          "Launches"
        ],
        "summary": "Ranked launches for a period",
        "description": "Get the ranked Product Hunt launches for any day, week, month or year, back to 2013. Address the period with a date, or with year plus month, day or week. Promoted entries — Product Hunt places three per twenty in the feed — are dropped from the results, and the number dropped is reported in notes, so a count that differs from the website has an explanation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "period": {
                    "type": "string",
                    "description": "daily, weekly, monthly, or yearly.",
                    "example": "daily"
                  },
                  "date": {
                    "type": "string",
                    "description": "YYYY-MM-DD — the day, or any day inside the week, month or year wanted.",
                    "example": "today"
                  },
                  "year": {
                    "type": "number",
                    "description": "Year (2013-2100), instead of date."
                  },
                  "month": {
                    "type": "number",
                    "description": "Month 1-12, with year."
                  },
                  "day": {
                    "type": "number",
                    "description": "Day of month, with year and month."
                  },
                  "week": {
                    "type": "number",
                    "description": "ISO week 1-53, with year."
                  },
                  "sortBy": {
                    "type": "string",
                    "description": "DAILY_RANK, WEEKLY_RANK, MONTHLY_RANK, YEARLY_RANK, VOTES, or SCORE."
                  },
                  "limit": {
                    "type": "number",
                    "description": "Maximum entries returned (max 500), or -1 for everything available.",
                    "example": "30"
                  },
                  "pages": {
                    "type": "number",
                    "description": "Pages of results to collect in one request (max 100), or -1 for the maximum allowed. Each page walked counts as one request.",
                    "example": "1"
                  },
                  "cursor": {
                    "type": "string",
                    "description": "Resume from a previous response's nextCursor."
                  },
                  "delayMs": {
                    "type": "number",
                    "description": "Milliseconds to wait between pages (max 30000)."
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown. Markdown returns the same result rendered as text.",
                    "example": "json"
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000)."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "value": {
                    "period": "daily",
                    "date": "2026-09-01",
                    "limit": 20
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "period": {
                      "type": "string",
                      "description": "The period the board covers."
                    },
                    "year": {
                      "type": "number",
                      "description": "Year of the board, with month, day and week filled in where they apply."
                    },
                    "date": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "YYYY-MM-DD for a daily board, null otherwise."
                    },
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "rank": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "The launch's rank for this period."
                          },
                          "launch": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "The launch: slug, name, tagline, thumbnail, upvotes, comment count, launch date, ranks, product slug and topics."
                          }
                        }
                      },
                      "description": "The ranked launches, promoted placements removed."
                    },
                    "entryCount": {
                      "type": "number",
                      "description": "Number of entries in this response."
                    },
                    "pagesScraped": {
                      "type": "number",
                      "description": "Pages actually collected. Each page counts as one request against your plan."
                    },
                    "pagesRequested": {
                      "type": "number",
                      "description": "Pages the request asked for."
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass back as cursor to continue, or null when the listing is exhausted."
                    },
                    "hasNextPage": {
                      "type": "boolean",
                      "description": "Whether more results are available beyond this response."
                    },
                    "requestedUrl": {
                      "type": "string",
                      "description": "The Product Hunt page this result corresponds to."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO timestamp the result was collected at."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Read this. Caveats about this specific result — a walk that stopped early, an upstream ceiling, or promoted entries that were dropped. An empty array means nothing was held back."
                    },
                    "blocked": {
                      "type": "boolean",
                      "description": "Always false on a successful response."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "period": "daily",
                      "date": "2026-09-01",
                      "entryCount": 20,
                      "notes": [
                        "Dropped 3 promoted entries from the feed."
                      ],
                      "entries": [
                        {
                          "rank": 1,
                          "launch": {
                            "slug": "granola-2-0",
                            "name": "Granola 2.0",
                            "upvotes": 1842,
                            "commentsCount": 214,
                            "productSlug": "granola"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/topic-products": {
      "post": {
        "operationId": "topic-products",
        "tags": [
          "Discovery"
        ],
        "summary": "Products in a topic",
        "description": "List the products filed under a Product Hunt topic — developer-tools, artificial-intelligence, productivity and the rest — ordered by most recent launch, rating, followers, post count or shoutouts. Narrow it with tags, or drop featuredOnly to include products that never launched. Poll one topic on a schedule and it becomes a category watchlist.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "topic": {
                    "type": "string",
                    "description": "Topic slug (for example \"developer-tools\"), or a Product Hunt topic URL."
                  },
                  "sortBy": {
                    "type": "string",
                    "description": "most_recent_launch, most_recent, oldest, posts_count, most_followed, best_rated, highest_rated, most_shoutouts, or no_order.",
                    "example": "most_recent_launch"
                  },
                  "featuredOnly": {
                    "type": "boolean",
                    "description": "Only products that have launched on Product Hunt.",
                    "example": "true"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Narrow the topic to these tags (max 10)."
                  },
                  "limit": {
                    "type": "number",
                    "description": "Maximum products returned (max 500), or -1 for everything available.",
                    "example": "30"
                  },
                  "pages": {
                    "type": "number",
                    "description": "Pages of results to collect in one request (max 100), or -1 for the maximum allowed. Each page walked counts as one request.",
                    "example": "1"
                  },
                  "cursor": {
                    "type": "string",
                    "description": "Resume from a previous response's nextCursor."
                  },
                  "delayMs": {
                    "type": "number",
                    "description": "Milliseconds to wait between pages (max 30000)."
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown. Markdown returns the same result rendered as text.",
                    "example": "json"
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "topic"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "topic": "developer-tools",
                    "sortBy": "most_recent_launch",
                    "limit": 50
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "topic": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The resolved topic: id, slug, name, description, url, parent topic and sub-topic slugs."
                    },
                    "products": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "slug": {
                            "type": "string",
                            "description": "Product slug — the handle for product-detail and product-comments."
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Product name."
                          },
                          "tagline": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The one-line pitch shown under the name."
                          },
                          "url": {
                            "type": "string",
                            "description": "Public Product Hunt page for the product."
                          },
                          "logoUrl": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Logo image URL. Pass it to GET /media to download the file."
                          },
                          "reviewsCount": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "How many reviews the product has."
                          },
                          "reviewsRating": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Average review rating."
                          },
                          "followersCount": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Followers on Product Hunt."
                          },
                          "launchesCount": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "How many times the product has launched."
                          },
                          "isNoLongerOnline": {
                            "type": "boolean",
                            "description": "Whether Product Hunt has marked the product as dead."
                          },
                          "latestLaunch": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "additionalProperties": true,
                            "description": "The product's most recent launch. Present on a topic listing, absent on a keyword search."
                          }
                        }
                      },
                      "description": "Products in the topic."
                    },
                    "productCount": {
                      "type": "number",
                      "description": "Number of products in this response."
                    },
                    "totalCount": {
                      "type": [
                        "number",
                        "null"
                      ],
                      "description": "Products in the topic overall, not just on this page."
                    },
                    "pagesScraped": {
                      "type": "number",
                      "description": "Pages actually collected. Each page counts as one request against your plan."
                    },
                    "pagesRequested": {
                      "type": "number",
                      "description": "Pages the request asked for."
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass back as cursor to continue, or null when the listing is exhausted."
                    },
                    "hasNextPage": {
                      "type": "boolean",
                      "description": "Whether more results are available beyond this response."
                    },
                    "requestedUrl": {
                      "type": "string",
                      "description": "The Product Hunt page this result corresponds to."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO timestamp the result was collected at."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Read this. Caveats about this specific result — a walk that stopped early, an upstream ceiling, or promoted entries that were dropped. An empty array means nothing was held back."
                    },
                    "blocked": {
                      "type": "boolean",
                      "description": "Always false on a successful response."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "topic": {
                        "slug": "developer-tools",
                        "name": "Developer Tools"
                      },
                      "productCount": 50,
                      "totalCount": 8421,
                      "hasNextPage": true,
                      "notes": [],
                      "products": [
                        {
                          "slug": "warp",
                          "name": "Warp",
                          "tagline": "The terminal reimagined",
                          "latestLaunch": {
                            "slug": "warp-3",
                            "launchedAt": "2026-09-08"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/collections": {
      "post": {
        "operationId": "collections",
        "tags": [
          "Discovery"
        ],
        "summary": "Search or browse collections",
        "description": "Search Product Hunt collections by name, or omit the query to browse the newest ones. Each collection carries its curator, how many products it holds, and a short preview of what is inside — a ready-made, human-curated shortlist of products in one theme.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string",
                    "description": "Search collections by name. Omit to browse the newest ones."
                  },
                  "limit": {
                    "type": "number",
                    "description": "Maximum collections returned (max 200), or -1 for everything available.",
                    "example": "20"
                  },
                  "pages": {
                    "type": "number",
                    "description": "Pages of results to collect in one request (max 100), or -1 for the maximum allowed. Each page walked counts as one request.",
                    "example": "1"
                  },
                  "cursor": {
                    "type": "string",
                    "description": "Resume from a previous response's nextCursor."
                  },
                  "delayMs": {
                    "type": "number",
                    "description": "Milliseconds to wait between pages (max 30000)."
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown. Markdown returns the same result rendered as text.",
                    "example": "json"
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000)."
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "default": {
                  "value": {
                    "query": "design tools",
                    "limit": 20
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The search term, or null when browsing."
                    },
                    "collections": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Collection name, with title alongside it."
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "What the curator says the collection is for."
                          },
                          "url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Public Product Hunt page for the collection."
                          },
                          "productsCount": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "How many products the collection holds."
                          },
                          "curator": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "additionalProperties": true,
                            "description": "Who maintains it."
                          },
                          "products": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "description": "A short preview of what the collection holds — names and logos."
                          }
                        }
                      },
                      "description": "The matching collections."
                    },
                    "collectionCount": {
                      "type": "number",
                      "description": "Number of collections in this response."
                    },
                    "pagesScraped": {
                      "type": "number",
                      "description": "Pages actually collected. Each page counts as one request against your plan."
                    },
                    "pagesRequested": {
                      "type": "number",
                      "description": "Pages the request asked for."
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass back as cursor to continue, or null when the listing is exhausted."
                    },
                    "hasNextPage": {
                      "type": "boolean",
                      "description": "Whether more results are available beyond this response."
                    },
                    "requestedUrl": {
                      "type": "string",
                      "description": "The Product Hunt page this result corresponds to."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO timestamp the result was collected at."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Read this. Caveats about this specific result — a walk that stopped early, an upstream ceiling, or promoted entries that were dropped. An empty array means nothing was held back."
                    },
                    "blocked": {
                      "type": "boolean",
                      "description": "Always false on a successful response."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "query": "design tools",
                      "collectionCount": 20,
                      "hasNextPage": true,
                      "notes": [],
                      "collections": [
                        {
                          "name": "Design tools I actually use",
                          "productsCount": 34,
                          "curator": {
                            "username": "maya"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/user-profile": {
      "post": {
        "operationId": "user-profile",
        "tags": [
          "People"
        ],
        "summary": "Get a maker or hunter profile",
        "description": "Read a Product Hunt member's public profile: name, headline, about text, links, join date, follower and following counts, upvotes given, launches submitted, collections and badges — plus the first page of products they created and every product they are credited on. The way to go from a launch's maker list to who these people are.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "user": {
                    "type": "string",
                    "description": "Username, \"@username\", or a Product Hunt profile URL."
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown.",
                    "example": "json"
                  },
                  "timeoutMs": {
                    "type": "number",
                    "description": "Per-request time limit in milliseconds (max 600000)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "user"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "user": "rrhoover"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "profile": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The public profile record.",
                      "properties": {
                        "username": {
                          "type": "string",
                          "description": "Product Hunt username."
                        },
                        "headline": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The one-line bio, with about carrying the longer text."
                        },
                        "links": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "External links listed on the profile."
                        },
                        "joinedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "When the account was created."
                        },
                        "followersCount": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Followers, with followingCount alongside it."
                        },
                        "upvotesGiven": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Upvotes this person has given."
                        },
                        "launchesSubmittedCount": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "How many launches they have submitted — the hunter signal."
                        },
                        "isMaker": {
                          "type": "boolean",
                          "description": "Whether Product Hunt marks them as a maker, with isVerified alongside it."
                        },
                        "products": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "The first page of products this person created, newest first."
                        },
                        "creditedProducts": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Every product this person is credited on. Names and logos only."
                        }
                      }
                    },
                    "requestedUrl": {
                      "type": "string",
                      "description": "The Product Hunt page this result corresponds to."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO timestamp the result was collected at."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Read this. Caveats about this specific result — a walk that stopped early, an upstream ceiling, or promoted entries that were dropped. An empty array means nothing was held back."
                    },
                    "blocked": {
                      "type": "boolean",
                      "description": "Always false on a successful response."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "profile": {
                        "username": "rrhoover",
                        "name": "Ryan Hoover",
                        "headline": "Founder",
                        "followersCount": 128400,
                        "launchesSubmittedCount": 1204,
                        "isMaker": true
                      },
                      "notes": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/media": {
      "get": {
        "operationId": "media",
        "tags": [
          "Media"
        ],
        "summary": "Download a product or launch image",
        "description": "Stream a product logo, launch thumbnail or gallery image, using a url taken from a product or launch returned by the other endpoints. Only Product Hunt image hosts are accepted. HTTP Range requests are supported. This is a GET with query parameters, not a JSON POST, and it bills as one request.",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Product Hunt image URL, as returned on a product or launch. Passed as a query parameter.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "filename",
            "in": "query",
            "required": false,
            "description": "Content-Disposition filename to serve the file as (max 200 characters).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Range",
            "in": "header",
            "required": false,
            "description": "Standard HTTP Range request header, for example bytes=0-65535. Sent as a header, not a query parameter.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/resolve-url": {
      "post": {
        "operationId": "resolve-url",
        "tags": [
          "Utility"
        ],
        "summary": "Parse a Product Hunt URL",
        "description": "Turn any Product Hunt URL into the structured input it encodes — whether it points at a product, a launch, a user, a topic, a category, a collection, a leaderboard or a search, plus the slug, comment id, query or period carried with it. Parsing a URL does not consume a credit.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Any Product Hunt URL, to be parsed into structured input."
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown.",
                    "example": "json"
                  }
                },
                "additionalProperties": false,
                "required": [
                  "url"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "url": "https://www.producthunt.com/posts/granola-2-0"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "kind": {
                      "type": "string",
                      "description": "What the URL points at: product, launch, user, topic, category, collection, leaderboard, search, home, or unknown. Only the fields matching the kind are filled in."
                    },
                    "productSlug": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Present when the URL names a product."
                    },
                    "launchSlug": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Present when the URL names a launch."
                    },
                    "username": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Present when the URL names a profile."
                    },
                    "topicSlug": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Present when the URL names a topic, with categorySlug and collectionSlug for those kinds."
                    },
                    "commentId": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Present when the URL deep-links to a comment."
                    },
                    "query": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Present when kind is search."
                    },
                    "leaderboardPeriod": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "daily, weekly, monthly or yearly, with leaderboardYear, leaderboardMonth, leaderboardDay and leaderboardWeek alongside it."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "kind": "launch",
                      "launchSlug": "granola-2-0",
                      "productSlug": null,
                      "username": null,
                      "commentId": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    }
  }
}