> ## Documentation Index
> Fetch the complete documentation index at: https://docs.preuve.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Deep Modules

> Opt-in analysis modules on paid deep runs: Proof of Demand, Founder Fit, Playbook, Trends, and Community.

Deep (paid) analyses can generate five optional modules through the enrich endpoint. Pass `modules` in the body of `POST /api/agent/analyses/:id/enrich`:

```json theme={null}
{
  "modules": ["playbook", "proofOfDemand", "trends", "community"]
}
```

| Module | What it generates | Execution |
| - | - | - |
| `proofOfDemand` | **Beta.** Verified real-demand prospects: real people publicly expressing the pain or asking for the solution, with verbatim quotes. Results can be uneven; every quote links to its source thread | Async |
| `founderFit` | Founder-vs-plan underwriting from your `founderProfile`: fit score, top risks, pivot fit | Inline (up to \~90s) |
| `playbook` | A concrete launch playbook for the idea | Async |
| `trends` | Google Trends data for the idea's keywords, generated on demand (the analysis itself never fetches it) | Async |
| `community` | Community signals: real discussions from forums, Reddit, review sites, and X about the idea's market, with links back to each source | Async |

## Rules

* **Deep only.** Requesting modules on a free run returns `403 MODULES_REQUIRE_DEEP`. The analysis must be `COMPLETED` (`409 ANALYSIS_NOT_COMPLETE` otherwise).
* **One successful generation per module per report.** A module already generated returns `409 MODULE_ALREADY_GENERATED`. A failed generation never consumes the cap - retry freely.
* **Async modules** return `202` with `state: "generating"`. Poll `GET /api/agent/analyses/:id`: its `modules` map reports `not_generated | generating | failed | completed` per module. A generation already started elsewhere (for example by the report owner in the web app) returns `202` with `alreadyStarted: true` - the API and the web app can never double-generate.
* Generated payloads land in the export as `details.founderFit`, `details.playbook`, and `details.proofOfDemand`, and in the report's web view.

## Founder Fit

`founderFit` requires a `founderProfile` in the same request:

```json theme={null}
{
  "modules": ["founderFit"],
  "founderProfile": {
    "hoursPerWeek": 20,
    "runwayMonths": 6,
    "domainYears": 3,
    "shippedBefore": "side_project",
    "audienceSize": "under_1k",
    "teamStatus": "solo",
    "twelveMonthGoal": "replace_income",
    "sabotagePattern": "I rebuild the landing page instead of talking to users"
  }
}
```

| Field | Type | Values |
| - | - | - |
| `hoursPerWeek` | number | 1-168 |
| `runwayMonths` | number | 0-120 |
| `domainYears` | number | 0-60 |
| `shippedBefore` | enum | `never`, `side_project`, `launched` |
| `audienceSize` | enum | `none`, `under_1k`, `1k_10k`, `over_10k` |
| `teamStatus` | enum | `solo`, `cofounded_friends`, `cofounded_colleagues`, `team_with_hires` |
| `twelveMonthGoal` | enum, optional | `replace_income`, `side_income`, `vc_scale` |
| `sabotagePattern` | string, optional | Max 280 chars |

A missing or invalid profile returns `400 INVALID_FOUNDER_PROFILE` with per-field `details`. Founder Fit runs inline and returns `state: "completed"` in the same response on success. Two extra guards:

* `503 INSUFFICIENT_TIME_BUDGET` (retryable): the request spent too much time on core enrichment first. Call enrich again - core is now done, so the retry has the full time budget.
* `429 REGEN_LIMIT_REACHED`: the report's lifetime Founder Fit generation cap (shared with the web app) is exhausted.

## Trends

`trends` is on-demand by design: the analysis pipeline never fetches Google Trends itself. Startable when the data is absent or a previous fetch `failed`; successful data is final (`409 MODULE_ALREADY_GENERATED`) - it is never re-fetched for freshness.

Once generated, the data lands in the export as `details.googleTrends`: `fetchedAt`, `timeRange`, and per-keyword `{ keyword, averageVolume, growthPercent, peakMonth, dataPoints }`.

Values are Google's 0-100 search interest. Google scales each request of up to 5 terms to its own 100, and terms 1-5 and 6-10 come from two requests. Compare `averageVolume` and `dataPoints` only inside one term, never between terms. `growthPercent` compares the last 6 months with the 6 before. It is `null` when the earlier half averages under 10, because there is too little data to measure a change. `peakMonth` is the week label of the highest value, or `null` when every week is 0.

## Community

`community` is on-demand by design too: the deep analysis pipeline never generates community signals itself. This module - or the "Analyze Community Signals" button in the web report - is the only way to get them. It takes about 90 seconds and shares its in-flight lock with that button: if a refresh is already running, calling the module returns `202` with `alreadyStarted: true` instead of starting a second one.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.