# Apify Opportunity Scout (`shelvick/apify-opportunity-scout`) Actor

Decide whether to build a new Apify Actor for a niche. Pulls demand from Apify Ideas + HN/Reddit/GitHub/Stack Exchange and supply from the Apify Store + ProductHunt/G2/Capterra, then returns a PURSUE/CONSIDER/SKIP verdict with rationale, top-5 competitor table, and pricing recommendation.

- **URL**: https://apify.com/shelvick/apify-opportunity-scout.md
- **Developed by:** [Scott Helvick](https://apify.com/shelvick) (community)
- **Categories:** Developer tools, MCP servers
- **Stats:** 1 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.085 / niche analyzed (quick)

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Apify Opportunity Scout

Decide whether to build a new Apify Actor for a niche. Pulls demand from Apify Ideas + HN, Reddit, GitHub, Stack Exchange and supply from the Apify Store + ProductHunt, G2, Capterra, then returns a **PURSUE** / **CONSIDER** / **SKIP** verdict with rationale, top-5 competitor table, and pricing recommendation.

### What this does

Submit one niche description. The Actor runs a 4-layer demand framework and a 2-axis supply framework, then asks the main LLM for the synthesis: how strong is the demand signal, how crowded is the existing supply, and what's the routability of the likely buyer audience.

What you get back, per run:

- **Verdict** — `PURSUE` / `CONSIDER` / `SKIP`, with a one-paragraph rationale tied to what the data actually showed
- **Top 5 Apify Store competitors**, ranked by relevance to the niche, with MAU, pricing model, 30-day run-success rate, and agentic-payment whitelist status. Fewer than 5 entries appear when fewer than 5 of the matched Actors actually solve the same problem class — better than padding with keyword-noise.
- **Off-platform competition summary** — an LLM narrative across the SaaS/OSS landscape this niche overlaps, sourced from ProductHunt in standard and G2 / Capterra / Crunchbase in deep mode
- **Pricing recommendation** — model + price range, anchored to the existing competitor distribution rather than a wishful number
- **Demand quotes** — recent forum posts / issues / questions matching the niche's keywords, so you can read the actual evidence rather than trusting the counts
- **Ethical-filter flags** — ToS conflict, KYC ambiguity, scalping or scam risk — surfaced as a separate list so you spot them before building

Two outputs per successful run:

- One **dataset record** with the full structured shape (machine-readable; the schema is on the Console's Dataset tab)
- A **Markdown report** written to `OUTPUT.md` in the run's Key-Value Store (human-readable; same data, prose form)

Common workflows this enables:

- Triage a backlog of "actor ideas" before committing build time to any of them
- Decide between two similar niches by comparing demand/supply ratios
- Sanity-check that a niche you're already working on hasn't quietly become saturated
- Generate a pricing recommendation by anchoring to existing competitor prices in the same niche

### Why this matters

Most Apify builders pick niches the way you pick a new project on a Friday afternoon: "this sounds cool." The Store has 10000+ Actors and 559 open Ideas Board entries; most of the obvious niches are already built, half-built, or have been tried and abandoned. Picking by gut wastes the week.

Opportunity Scout turns "should I build this?" from a hunch into a 30-second data pull. It can't tell you whether *you specifically* should build something — but it can tell you whether a market exists, what shape the existing supply has, and what to charge if you do go ahead.

### How it compares to picking the niche yourself

| Approach | Apify supply data | Off-platform demand | Off-platform supply | Pricing rec | Time to verdict |
|---|---|---|---|---|---|
| Picking by gut on a Friday afternoon | ✗ | ✗ | ✗ | ✗ | seconds (often wrong) |
| Skimming Reddit / HN threads manually | ✗ | partial | ✗ | ✗ | hours |
| Browsing the Apify Store, counting Actors | partial | ✗ | ✗ | ✗ | tens of minutes |
| **Opportunity Scout** | ✓ | ✓ (standard+) | ✓ (deep) | ✓ | 5s–3min |

You don't get hidden data — the Actor reads the same public APIs and pages you would. It's the synthesis that's hard to do manually: pulling demand and supply signals from eight or nine sources, weighting them against each other, and producing one verdict in seconds.

### Depth modes

| Depth | Sources queried | Wall-clock | Best for |
|---|---|---|---|
| `quick` (default) | Apify Store + Ideas Board only | 5-15s | Cheapest triage. Surfaces obvious first-party dominance fast. |
| `standard` | quick + off-platform community demand (HN, GitHub Issues, Stack Exchange, ProductHunt) | 30-60s | The everyday "should I look closer?" pass. |
| `deep` | standard + Reddit discussion + off-platform commercial competition (G2, Capterra, Crunchbase) + more thorough analytical reasoning | 1-3min | Niches that survived `standard` and deserve a full read. Highest cost. |

Run `quick` first to triage. Promote to `deep` only for niches that justify the cost.

### Input

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `niche` | string | ✓ | — | Plain-language description of the Actor idea you're evaluating. E.g. `"BringATrailer auction monitoring"`, `"international Amazon marketplaces"`, `"GitHub repo health scoring"`. Untrusted input — wrapped in injection-protection tags before reaching the main LLM. |
| `depth` | enum: `quick` / `standard` / `deep` | | `quick` | Controls how many sources are queried and which model scores the verdict. |
| `keywords` | array of strings | | (LLM generates) | Override the LLM's keyword expansion. Useful when you already know the high-signal search terms and want to short-circuit the expansion call. |
| `categories` | array of strings | | (none) | Restrict the Apify Store + Ideas Board searches to specific Apify category enums (e.g. `["AUTOMATION", "ECOMMERCE"]`). |
| `includeCommercial` | boolean | | `true` | Whether to pull off-platform commercial competition (G2 / Capterra / Crunchbase) in deep mode. Set `false` to skip those catalogs and keep deep-mode cost on the community sources + the more thorough analytical pass only. No effect on `quick` or `standard`. |

### Output

One dataset record per run, plus a Markdown report at `OUTPUT.md` in the run's Key-Value Store.

Abbreviated success record:

```json
{
  "niche": "BringATrailer auction monitoring",
  "verdict": "CONSIDER",
  "scores": {
    "opportunity": 0.38,
    "demand_score": 0.42,
    "supply_on_platform_score": 0.5,
    "supply_off_platform_score": 0.3
  },
  "supply": {
    "on_platform": {
      "total_actors": 34,
      "total_mau": 183,
      "first_party_dominance_pct": 0,
      "top_5": [
        { "name": "...", "username": "...", "mau": 64, "pricing_summary": "...", "url": "..." }
      ]
    },
    "off_platform": { "saas_dominance_summary": "..." }
  },
  "demand": {
    "intent": { "apify_ideas": {...}, "hackernews": {...}, "github_issues": {...} },
    "revealed": { "reddit": {...}, "stackexchange": {...} }
  },
  "routability": {
    "buyer_persona": "developer",
    "factor": 0.55,
    "rationale": "..."
  },
  "pricing_recommendation": { "model_suggested": "PAY_PER_EVENT", "main_event_usd_range": [0.05, 0.20], "rationale": "..." },
  "ethical_filter_flags": []
}
````

The full schema is documented on the Console's Dataset tab. The `OUTPUT.md` report renders the same data as a prose report with sections for Verdict, Demand signals, Supply, and Pricing recommendation.

### Example

```json
{
  "niche": "GitHub repo health scoring",
  "depth": "standard"
}
```

Via the API:

```bash
curl -X POST "https://api.apify.com/v2/acts/shelvick~apify-opportunity-scout/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"niche": "GitHub repo health scoring", "depth": "standard"}'
```

A standard-depth run typically returns in 30-60 seconds. Deep runs can push past the 5-minute sync API cap — use the async `/runs` endpoint for deep mode.

### Calling from an AI agent

The Actor is designed for agent discovery and invocation.

**MCP** (`mcp.apify.com`): surfaces as a callable tool. The input schema is self-documenting — one required field (`niche`), structured output, no follow-up questions. An LLM can construct correct calls from the tool description without external context. Pay per call via the Actor's pay-per-event model — works with x402 and Skyfire agentic-payment rails.

**Apify SDK** (Python):

```python
from apify_client import ApifyClient

client = ApifyClient(token=API_TOKEN)
run = client.actor("shelvick/apify-opportunity-scout").call(
    run_input={"niche": "international Amazon marketplaces", "depth": "standard"}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["verdict"], item["scores"]["opportunity"], item["supply"]["on_platform"]["total_mau"])
```

**REST**: `/run-sync-get-dataset-items` for `quick` / `standard` runs (under 5 minutes), the async `/runs` endpoint for `deep`.

### Pricing

Pay-per-event. Each successful run fires one depth-tier charge:

- **Quick depth** — covers the Apify Store + Ideas Board queries and the LLM scoring call.
- **Standard depth** — adds off-platform community demand sources (HN, GitHub Issues, Stack Exchange, ProductHunt).
- **Deep depth** — adds Reddit discussion + off-platform commercial catalogs (G2, Capterra, Crunchbase) and more thorough analytical reasoning.

The minimum platform-startup charge fires once at run start regardless of outcome but is effectively zero. The depth-tier charge fires only on success — failed runs skip it entirely.

See the **Pricing** tab on this Store page for current per-event rates and any active subscriber discounts.

### Behavior

#### Failure modes

The run itself is marked **FAILED** only on input validation:

- `niche` empty or missing
- `depth` not one of `quick` / `standard` / `deep`
- `keywords` contains non-strings

Per-source data-collection failures never fail the run — they degrade gracefully. A source that's temporarily unreachable is simply omitted from that run's analysis (the field is absent / not-assessed rather than reported as a zero), and the verdict is computed from whatever sources did return. The on-platform analysis (Apify Store + Ideas Board) always completes. Per-source diagnostics are recorded in the run log for operators; they are not added to the dataset output.

#### Performance expectations

Wall-clock latency depends on depth mode:

- **Quick**: 5-15 seconds. Reads Apify Store + Ideas Board only — fast HTTP calls, no off-platform scraping.
- **Standard**: 30-60 seconds. Adds community-source demand scraping (HN, GitHub Issues, Stack Exchange, ProductHunt).
- **Deep**: 1-3 minutes. Adds Reddit discussion + commercial-catalog scraping (G2, Capterra, Crunchbase) and more thorough analytical reasoning.

The default `run-sync-get-dataset-items` endpoint times out at 180 seconds. Quick and standard fit comfortably. Deep runs can push past it on the slow end — use the async `/runs` endpoint with polling for deep mode, or pass `?timeout=300` to bump the sync cap to 5 minutes.

### FAQ

**What's the difference between `standard` and `deep` in practice?**
Standard pulls demand signal from community sources where developers ask questions and complain (HN, GitHub Issues, Stack Exchange, ProductHunt). Deep adds Reddit discussion plus commercial-catalog scraping for the SaaS competition landscape (G2, Capterra, Crunchbase) and runs a more thorough analytical synthesis. If the buyer audience is developers, standard usually suffices. If the buyer is a non-developer (SMB, enterprise procurement, marketing ops), deep helps because the SaaS-catalog supply matters more.

**Should I trust the routability score?**
Treat it as one input, not a verdict. Routability is the model's read on whether the buyer audience is reachable by the channels you have. Directionally useful but not formulaic. If the score conflicts with your own market knowledge, your knowledge wins.

**What if my niche is split across multiple Apify categories?**
Pass them all in the `categories` field — the Apify Store + Ideas Board queries restrict to that set. Leaving `categories` empty searches across all categories, which is usually fine for a first triage pass.

**Can I batch multiple niches in one run?**
No. One niche per run. Run several and diff the dataset records offline.

**Why doesn't this Actor build the thing for me?**
Different problem class. Scoring an opportunity and scaffolding an Actor are different skills; bundling them would muddy both. Once you've decided to PURSUE, the Actor's job is done.

**Do failed runs cost anything?**
The minimum platform-startup charge is effectively zero. The depth-tier charge (the only meaningful per-run cost) fires only on a successful verdict — failed runs skip it entirely.

**What signals push CONSIDER toward PURSUE?**
Higher demand-score with first-party dominance below ~20%, plus a routable buyer persona (typically developers or technical SMB). The verdict text includes an explanation, but those are the patterns that usually flip CONSIDER → PURSUE.

### What this doesn't do

- **No multi-niche comparisons in one run.** One niche per run. Run several and diff offline.
- **No build help.** Once you've decided to PURSUE, you're on your own — this Actor scores, it doesn't scaffold.
- **No marketing.** No SEO content generation, no domain availability check, no launch checklist. Pure go/no-go.
- **No private data sources.** Reads only public APIs (Apify Store, Ideas Board, HN, GitHub, Stack Exchange) plus scraped public pages (Reddit, ProductHunt, G2, Capterra, Crunchbase). Doesn't read your private Console workspace, your CRM, your own Actors' run logs.
- **No persistent memory across runs.** Every run is independent. If you want a "did I already analyze this niche?" record, store dataset items in your own KVS.

For competitor-by-competitor deep-dive research after a PURSUE verdict, use a dedicated competitive-analysis workflow. For technical scaffolding and implementation planning, escalate to architecture / SPEC docs or pair with your engineering team. For ongoing tracking of an already-built Actor's market position, use a portfolio-monitoring tool.

***

Design notes: [scotthelvick.com/tools/apify-opportunity-scout](https://www.scotthelvick.com/tools/apify-opportunity-scout/)

# Actor input Schema

## `niche` (type: `string`):

Plain-language description of the Actor idea you're evaluating. Examples: 'BringATrailer auction monitoring', 'international Amazon marketplaces', 'GitHub repo health scoring'. The system auto-expands this into 3-12 search variants based on depth. Override with the `keywords` field only if auto-expansion would miss critical domain terms -- specific platform names, brand abbreviations, or niche-specific vocabulary the system wouldn't produce. 3-500 characters.

## `depth` (type: `string`):

Which depth of analysis to run. Quick (5-15s) analyzes the Apify Store + Ideas Board only. Standard (30-60s) adds off-platform community demand (HN, GitHub, Stack Exchange, ProductHunt). Deep (1-3 min) adds Reddit discussion + commercial catalogs (G2, Capterra, Crunchbase) and more thorough analytical reasoning. Pick quick for fast triage, standard for most evaluations, deep for niches needing full competitive landscape review.

## `keywords` (type: `array`):

Optional override for keyword expansion (e.g. \['BringATrailer', 'bat-auctions', 'classic-car-auction']). Leave empty for first-pass triage -- the system auto-expands the niche into 3-12 search variants based on depth. Provide explicit keywords only if you know auto-expansion misses critical domain terms (platform names, brand abbreviations, niche-specific vocabulary the system wouldn't produce). Up to 20 strings, each 1-100 characters.

## `categories` (type: `array`):

Constrain the Apify Store supply search to specific categories (e.g. \['AI', 'AUTOMATION', 'DEVELOPER\_TOOLS']). Leave empty to search all categories -- recommended for first pass. Valid values: AI, AGENTS, AUTOMATION, BUSINESS, COVID\_19, DEVELOPER\_EXAMPLES, DEVELOPER\_TOOLS, ECOMMERCE, EDUCATION, FOR\_CREATORS, GAMES, INTEGRATIONS, JOBS, LEAD\_GENERATION, MARKETING, MCP\_SERVERS, NEWS, OPEN\_SOURCE, OTHER, REAL\_ESTATE, SEO\_TOOLS, SOCIAL\_MEDIA, SPORTS, TRAVEL, VIDEOS.

## `includeCommercial` (type: `boolean`):

Whether to scrape paid SaaS catalogs (G2, Capterra, Crunchbase) in deep mode. These signal buyer-routing risk: if competitors are already reviewed/funded there, the buyer may have routed away from Apify. Turn off if you already know there's no SaaS competition in this niche. No effect when depth is quick or standard.

## Actor input object example

```json
{
  "niche": "BringATrailer auction monitoring",
  "depth": "quick",
  "includeCommercial": true
}
```

# Actor output Schema

## `report` (type: `string`):

Human- and agent-readable Markdown report covering the verdict, competitive landscape, demand-by-source, routability, pricing recommendation, and ethical-filter flags.

## `structured` (type: `string`):

One dataset record per run with the full structured analysis (supply, demand, routability, scores, pricing recommendation, ethical-filter flags, verdict, warnings).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "niche": "BringATrailer auction monitoring",
    "depth": "quick",
    "includeCommercial": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("shelvick/apify-opportunity-scout").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "niche": "BringATrailer auction monitoring",
    "depth": "quick",
    "includeCommercial": True,
}

# Run the Actor and wait for it to finish
run = client.actor("shelvick/apify-opportunity-scout").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "niche": "BringATrailer auction monitoring",
  "depth": "quick",
  "includeCommercial": true
}' |
apify call shelvick/apify-opportunity-scout --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=shelvick/apify-opportunity-scout",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Apify Opportunity Scout",
        "description": "Decide whether to build a new Apify Actor for a niche. Pulls demand from Apify Ideas + HN/Reddit/GitHub/Stack Exchange and supply from the Apify Store + ProductHunt/G2/Capterra, then returns a PURSUE/CONSIDER/SKIP verdict with rationale, top-5 competitor table, and pricing recommendation.",
        "version": "0.0",
        "x-build-id": "iCak5PjS2TR7UHgaZ"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/shelvick~apify-opportunity-scout/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-shelvick-apify-opportunity-scout",
                "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/shelvick~apify-opportunity-scout/runs": {
            "post": {
                "operationId": "runs-sync-shelvick-apify-opportunity-scout",
                "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/shelvick~apify-opportunity-scout/run-sync": {
            "post": {
                "operationId": "run-sync-shelvick-apify-opportunity-scout",
                "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",
                "required": [
                    "niche"
                ],
                "properties": {
                    "niche": {
                        "title": "Niche",
                        "minLength": 3,
                        "maxLength": 500,
                        "type": "string",
                        "description": "Plain-language description of the Actor idea you're evaluating. Examples: 'BringATrailer auction monitoring', 'international Amazon marketplaces', 'GitHub repo health scoring'. The system auto-expands this into 3-12 search variants based on depth. Override with the `keywords` field only if auto-expansion would miss critical domain terms -- specific platform names, brand abbreviations, or niche-specific vocabulary the system wouldn't produce. 3-500 characters."
                    },
                    "depth": {
                        "title": "Depth",
                        "enum": [
                            "quick",
                            "standard",
                            "deep"
                        ],
                        "type": "string",
                        "description": "Which depth of analysis to run. Quick (5-15s) analyzes the Apify Store + Ideas Board only. Standard (30-60s) adds off-platform community demand (HN, GitHub, Stack Exchange, ProductHunt). Deep (1-3 min) adds Reddit discussion + commercial catalogs (G2, Capterra, Crunchbase) and more thorough analytical reasoning. Pick quick for fast triage, standard for most evaluations, deep for niches needing full competitive landscape review.",
                        "default": "quick"
                    },
                    "keywords": {
                        "title": "Keyword overrides (optional)",
                        "maxItems": 20,
                        "type": "array",
                        "description": "Optional override for keyword expansion (e.g. ['BringATrailer', 'bat-auctions', 'classic-car-auction']). Leave empty for first-pass triage -- the system auto-expands the niche into 3-12 search variants based on depth. Provide explicit keywords only if you know auto-expansion misses critical domain terms (platform names, brand abbreviations, niche-specific vocabulary the system wouldn't produce). Up to 20 strings, each 1-100 characters.",
                        "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                        }
                    },
                    "categories": {
                        "title": "Apify Store category constraint (optional)",
                        "type": "array",
                        "description": "Constrain the Apify Store supply search to specific categories (e.g. ['AI', 'AUTOMATION', 'DEVELOPER_TOOLS']). Leave empty to search all categories -- recommended for first pass. Valid values: AI, AGENTS, AUTOMATION, BUSINESS, COVID_19, DEVELOPER_EXAMPLES, DEVELOPER_TOOLS, ECOMMERCE, EDUCATION, FOR_CREATORS, GAMES, INTEGRATIONS, JOBS, LEAD_GENERATION, MARKETING, MCP_SERVERS, NEWS, OPEN_SOURCE, OTHER, REAL_ESTATE, SEO_TOOLS, SOCIAL_MEDIA, SPORTS, TRAVEL, VIDEOS.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "includeCommercial": {
                        "title": "Include paid SaaS catalogs (deep mode)",
                        "type": "boolean",
                        "description": "Whether to scrape paid SaaS catalogs (G2, Capterra, Crunchbase) in deep mode. These signal buyer-routing risk: if competitors are already reviewed/funded there, the buyer may have routed away from Apify. Turn off if you already know there's no SaaS competition in this niche. No effect when depth is quick or standard.",
                        "default": true
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
