{
  "openapi": "3.0.1",
  "info": {
    "title": "Product Hunt Launch Monitor - Upvote Velocity & AI",
    "description": "Monitor Product Hunt launches, upvote velocity, makers, topics, comments, and breakout alerts. Built for VC deal flow, competitor tracking, startup trend research, Slack/webhook alerts, optional AI briefs, and x402-ready PPE pricing.",
    "version": "1.9",
    "x-build-id": "JMwdPyvaExiyfI9OS"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/harvestlab~producthunt-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-harvestlab-producthunt-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/harvestlab~producthunt-scraper/runs": {
      "post": {
        "operationId": "runs-sync-harvestlab-producthunt-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/harvestlab~producthunt-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-harvestlab-producthunt-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": {
          "productHuntApiToken": {
            "title": "Product Hunt API Token (recommended)",
            "type": "string",
            "description": "Recommended for full GraphQL API access. Get one FREE in 2 minutes: (1) Go to producthunt.com/v2/oauth/applications, (2) Create an application (any name), (3) Copy the Developer Token and paste it here. Without this token the actor uses the public Atom feed fallback, which returns recent products with limited fields."
          },
          "mode": {
            "title": "Scraping Mode",
            "enum": [
              "today",
              "weekly",
              "monthly",
              "topic",
              "search"
            ],
            "type": "string",
            "description": "What to scrape from Product Hunt. 'Today's Launches' = today's homepage feed (best for daily breakout monitoring + Watch Mode velocity). 'Weekly / Monthly Leaderboard' = trending top products over a longer window (best for trend reports). 'Browse by Topic' = launches filtered by a topic slug (e.g. artificial-intelligence) - supply the slug in the Topic field below. 'Search Products' = keyword search across all PH history - supply the keyword in the Search Query field. Watch Mode and breakout detection work on every mode but require running the same (mode, topic, search) tuple on a schedule to build velocity history.",
            "default": "today"
          },
          "searchQuery": {
            "title": "Search Query",
            "type": "string",
            "description": "Search query to find products (e.g. 'AI tools', 'developer productivity', 'no-code'). Only used when mode is 'search' - leave empty for other modes."
          },
          "query": {
            "title": "Search Query (CLI alias)",
            "type": "string",
            "description": "CLI alias for searchQuery. Hidden from Console form."
          },
          "q": {
            "title": "Search Query (CLI alias)",
            "type": "string",
            "description": "CLI alias for searchQuery. Hidden from Console form."
          },
          "search": {
            "title": "Search Query (CLI alias)",
            "type": "string",
            "description": "CLI alias for searchQuery. Hidden from Console form."
          },
          "keyword": {
            "title": "Search Query (CLI alias)",
            "type": "string",
            "description": "CLI alias for searchQuery. Hidden from Console form."
          },
          "searchTerm": {
            "title": "Search Query (CLI alias)",
            "type": "string",
            "description": "CLI alias for searchQuery. Hidden from Console form."
          },
          "topic": {
            "title": "Topic Slug",
            "type": "string",
            "description": "Topic slug for topic mode (e.g. 'artificial-intelligence', 'developer-tools', 'saas', 'marketing', 'fintech', 'web3')."
          },
          "category": {
            "title": "Topic Slug (CLI alias)",
            "type": "string",
            "description": "CLI alias for topic. Hidden from Console form."
          },
          "maxProducts": {
            "title": "Max Products",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Maximum number of products to scrape. Product Hunt shows ~30 launches per day, so requesting more than 30 in 'today' mode pulls from prior days. Start small (5-10) when first testing - bumping to 100 is fine once you've validated the API token works.",
            "default": 30
          },
          "maxItems": {
            "title": "Max Items (CLI alias)",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "CLI alias for maxProducts. Hidden from Console form."
          },
          "includeComments": {
            "title": "Include Comments",
            "type": "boolean",
            "description": "Fetch the top community comments on each launch via a second GraphQL call per product. Adds ~0.5-1s per product to runtime and surfaces 'why this is hot' qualitative signal alongside upvotes. Recommended for breakout-narrator runs (extra context in the AI prompt) and for sentiment / theme research. Leave off for fast leaderboard snapshots.",
            "default": false
          },
          "maxCommentsPerProduct": {
            "title": "Max Comments Per Product",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many top comments to pull per product when 'Include Comments' is on. 5 is a good default - the loudest reactions are almost always in the top 3-5. Cap at 20.",
            "default": 5
          },
          "enableWatchMode": {
            "title": "Track Upvote Velocity & Rank Momentum Across Runs",
            "type": "boolean",
            "description": "Persist each run's upvote counts + rank in a named key-value store and emit upvote_velocity (upvotes gained since last run), upvotes_per_hour, rank_change (positive = climbed leaderboard), and a momentum label (new / accelerating / steady / fading) on every product. A 'breakout_summary' item is pushed once per run with the top-5 climbers. Free (no extra charge, no extra HTTP calls). Requires a valid Product Hunt API token and scheduling runs on the same (mode, topic, search) filter to build history.",
            "default": true
          },
          "watchMode": {
            "title": "Watch Mode (CLI alias)",
            "type": "boolean",
            "description": "CLI alias for enableWatchMode. Hidden from Console form."
          },
          "enableAiAnalysis": {
            "title": "Enable AI Trend Analysis",
            "type": "boolean",
            "description": "Generate an AI-powered trend analysis report (trending categories, market themes, top picks, investment signals). Billed at $0.05 per report. Requires an API key for the selected LLM provider.",
            "default": false
          },
          "enableBreakoutNarrator": {
            "title": "Generate AI Breakout Narrative (2-3 paragraphs)",
            "type": "boolean",
            "description": "When AI is enabled AND Watch Mode emits a breakout_summary this run, feed the top-5 climbers to the LLM with a 'PH trend analyst' prompt. Result is attached to the breakout_summary item as a 'breakout_narrative' field (plain prose, 120-240 words) explaining the breakout + a concrete action for founders/PMs/VCs. Billed separately at $0.01 per narrative generated, only charged on successful generation.",
            "default": true
          },
          "breakoutNarrator": {
            "title": "Breakout Narrator (CLI alias)",
            "type": "boolean",
            "description": "CLI alias for enableBreakoutNarrator. Hidden from Console form."
          },
          "llmProvider": {
            "title": "LLM Provider",
            "enum": [
              "openrouter",
              "anthropic",
              "google",
              "openai",
              "ollama"
            ],
            "type": "string",
            "description": "AI backend for trend analysis + breakout narratives. 'OpenRouter' (default) is cheapest - Gemini Flash via OpenRouter runs ~$0.001 per analysis, ~$0.0005 per narrative. 'Anthropic' uses Claude direct (best prose for narratives), 'Google AI' uses Gemini direct, 'OpenAI' uses GPT-4o mini, 'Ollama' runs on your own server (no API cost). Only the chosen provider's API key is required.",
            "default": "openrouter"
          },
          "llmModel": {
            "title": "LLM Model (optional override)",
            "type": "string",
            "description": "Specific model to use. Leave empty for the provider default (google/gemini-2.0-flash-001 for OpenRouter, claude-sonnet-4-20250514 for Anthropic, gemini-2.0-flash for Google AI, gpt-4o-mini for OpenAI, llama3.1 for Ollama)."
          },
          "openrouterApiKey": {
            "title": "OpenRouter API Key",
            "type": "string",
            "description": "OpenRouter API key - set OPENROUTER_API_KEY env var OR openrouterApiKey input. Get one at https://openrouter.ai/keys."
          },
          "anthropicApiKey": {
            "title": "Anthropic API Key",
            "type": "string",
            "description": "Anthropic API key - set ANTHROPIC_API_KEY env var OR anthropicApiKey input. Get one at https://console.anthropic.com/settings/keys."
          },
          "googleApiKey": {
            "title": "Google AI API Key",
            "type": "string",
            "description": "Google AI (Gemini) API key - set GOOGLE_API_KEY env var OR googleApiKey input. Get one at https://aistudio.google.com/app/apikey."
          },
          "openaiApiKey": {
            "title": "OpenAI API Key",
            "type": "string",
            "description": "OpenAI API key - set OPENAI_API_KEY env var OR openaiApiKey input. Get one at https://platform.openai.com/api-keys."
          },
          "ollamaBaseUrl": {
            "title": "Ollama Base URL",
            "type": "string",
            "description": "Base URL for self-hosted Ollama API. Set ollamaBaseUrl input (no env var - Ollama is local). Install at https://ollama.com/download."
          },
          "alertWebhookUrl": {
            "title": "Breakout Alert Webhook URL",
            "type": "string",
            "description": "Optional https:// endpoint (Slack / Discord / Zapier / n8n / Make / your own receiver). When set and a breakout_summary is emitted this run, the actor POSTs the summary JSON (including the AI narrative if generated) with header X-Actor-Run-Id. Fire-and-forget with 1 retry - a failed webhook never fails the run. Billed at $0.002 per successful dispatch. Leave empty to disable."
          },
          "webhookUrl": {
            "title": "Webhook URL (CLI alias)",
            "type": "string",
            "description": "CLI alias for alertWebhookUrl. Hidden from Console form."
          },
          "slackWebhookUrl": {
            "title": "Slack Webhook URL (CLI alias)",
            "type": "string",
            "description": "CLI alias for alertWebhookUrl. Hidden from Console form."
          },
          "proxyConfiguration": {
            "title": "Proxy Configuration",
            "type": "object",
            "description": "Optional proxy settings. Default datacenter proxy is fine for the public GraphQL API."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}