{
  "openapi": "3.0.1",
  "info": {
    "title": "Product Hunt Reviews Scraper - Ratings & Pros Cons",
    "description": "Product Hunt reviews scraper that returns full review text, five separate rating dimensions, and the AI pro/con tags Product Hunt generates itself. Includes why each reviewer chose the product over alternatives. No login, no API token, no browser.",
    "version": "1.0",
    "x-build-id": "yeQK8ImINHgdNryhe"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/eiv~producthunt-reviews-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-eiv-producthunt-reviews-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/eiv~producthunt-reviews-scraper/runs": {
      "post": {
        "operationId": "runs-sync-eiv-producthunt-reviews-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/eiv~producthunt-reviews-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-eiv-producthunt-reviews-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "products": {
            "title": "Product Hunt products",
            "type": "array",
            "description": "Product URLs (`producthunt.com/products/<slug>`) or bare slugs. A LAUNCH url (`/posts/<slug>`) is rejected with a message rather than guessed at: launches and products are separate namespaces on Product Hunt and their slugs do not line up, so coercing one into the other would scrape the wrong thing or nothing at all.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Start URLs",
            "type": "array",
            "description": "The same products in the shape other Actors and the Apify UI hand over. Merged with the list above and deduplicated by slug.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "sourceDatasetId": {
            "title": "Source dataset id",
            "type": "string",
            "description": "Read product URLs out of another run's dataset, for chaining after a discovery Actor."
          },
          "sourceDatasetField": {
            "title": "Source dataset field",
            "type": "string",
            "description": "Which field in that dataset holds the product URL or slug. Defaults to `url`."
          },
          "maxReviewsPerProduct": {
            "title": "Max reviews per product",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Bounds the **output**. Product Hunt repeats a fixed block of top reviews on every page, so this Actor deduplicates by review id and counts only genuinely new ones — measured, page 2 returned 18 review objects of which only 8 were new.",
            "default": 200
          },
          "maxPagesPerProduct": {
            "title": "Max pages per product",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Bounds the **work**, where the cap above bounds the output. Needed because the repeated top-review block means pages keep returning rows long after the new ones run out; the run also stops on its own when a page yields no new review ids.",
            "default": 40
          },
          "reviewDetail": {
            "title": "Review detail level",
            "enum": [
              "any",
              "withText",
              "structured"
            ],
            "type": "string",
            "description": "Product Hunt has two review formats. A QUICK review carries an overall rating and one written paragraph — measured at 62% of reviews. A STRUCTURED review adds four more ratings (ease of use, reliability, value for money, customization) and splits the prose into what the reviewer liked, what they didn't, and why they chose the product over alternatives — measured at 22%. Every review carries an overall rating and, measured over 260 rows, 100% carry some written text. Choose `structured` when you need the rating breakdown; filtered rows are never written and never charged, and the coverage row reports how many were examined and dropped.",
            "default": "any"
          },
          "reviewTypes": {
            "title": "Review types",
            "type": "array",
            "description": "Limit to `personal` (from users) or `founder` (from the product's own founders). Leave empty for both. Founder reviews are a large share of some products — on one measured product they were 567 of 983 — and they carry written feedback far less often, so excluding them raises the density of useful rows.",
            "items": {
              "type": "string"
            }
          },
          "maxTotalReviews": {
            "title": "Max reviews for the whole run",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "A ceiling across every product. Reached mid-product, the run stops cleanly and the summary rows say so.",
            "default": 5000
          },
          "requestDelayMs": {
            "title": "Delay between requests (ms)",
            "minimum": 0,
            "maximum": 60000,
            "type": "integer",
            "description": "Applied across the whole run rather than per worker, so this is the real interval between requests whatever the concurrency.",
            "default": 1000
          },
          "maxConcurrency": {
            "title": "Concurrent products",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many products are scraped at once. Pages within a product are sequential because each page's new-review check depends on the ones before it.",
            "default": 3
          },
          "proxyConfig": {
            "title": "Proxy",
            "type": "object",
            "description": "Leave this at the default. Product Hunt is behind Cloudflare and challenges every plain datacenter IP — measured 0 usable responses out of 15 — so this Actor uses the Apify UNBLOCKER group, which clears the challenge and is billed per request rather than per gigabyte.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "UNBLOCKER"
              ]
            }
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}