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

# Analyze and compare strategies

> View holdings, find outliers, compare two strategies, export data, and pull a factsheet for existing Noonum thematic strategies through the REST API and MCP server.

A Noonum thematic strategy is a thematic investment definition: a basket of ranked companies assembled around an objective, with evidence-backed metadata for every holding. Each company's inclusion is grounded in textual evidence, so you can analyze and report on a strategy from the evidence rather than by guessing.

The workflows below run against existing strategies through the [REST API](https://api.noonum.ai/v2) or the [MCP server](/base/agentic/mcp-server): viewing holdings, finding outliers, analyzing composition, comparing two strategies, exporting CSV, pulling a factsheet, and archiving.

<Note>
  To create or submit a strategy, see [Build a strategy](/v2/guides/build-strategy). To run the full refinement loop, see [Iterate on a strategy](/v2/guides/iterate-strategy).
</Note>

Every request needs an `Authorization: Bearer <token>` header. See [Authentication](/v2/getting-started/authentication) for tokens and API keys.

## The three signals

Each holding carries three scores: conviction, linguistic beta, and market buzz. [Signals and scores](/base/concepts/signals-and-scores) defines each one, its range, and how to read it. This guide assumes that and focuses on which one to lead with for a given question:

* **Conviction** for ranking holdings, summarizing a company, or comparing strategies. It is the default ranking metric and headline number.
* **Linguistic beta** when you need to defend why a company belongs in the theme, judge how tightly a cluster ties to the thesis, or flag outliers.
* **Market buzz** to see which holdings are currently active in the theme versus historically connected but quiet.

Holdings tables include both conviction and linguistic beta as columns, sorted by conviction by default.

## Resolve a strategy

Most operations take a strategy ID. To find one:

* List your strategies with `GET /strategies` (MCP: `list_strategies`).
* Fetch a specific strategy with `GET /strategies/{strategyId}` (MCP: `get_strategy`).

To browse the public catalog of completed, non-archived strategies, pass `scope=public` to `GET /strategies`. Use `scope=all` to return your own strategies plus the catalog, deduplicated.

## Endpoint quick reference

All REST paths are relative to `https://api.noonum.ai/v2`. The MCP server exposes the same endpoints as named tools.

| Intent                       | REST endpoint                                        | MCP tool                      |
| ---------------------------- | ---------------------------------------------------- | ----------------------------- |
| List strategies              | `GET /strategies`                                    | `list_strategies`             |
| Get one strategy             | `GET /strategies/{strategyId}`                       | `get_strategy`                |
| Get holdings                 | `GET /strategies/{strategyId}/companies`             | `get_strategy_companies`      |
| Look up one company          | `GET /strategies/{strategyId}/companies/{companyId}` | `get_strategy_company`        |
| Search companies             | `POST /helper/companies/search`                      | `search_companies`            |
| Get evidence                 | `GET /strategies/{strategyId}/evidences`             | `get_strategy_evidences`      |
| Get factsheet (PDF)          | `GET /strategies/{strategyId}/factsheet`             | `get_strategy_factsheet`      |
| Update metadata / exclusions | `PATCH /strategies/{strategyId}`                     | `update_strategy`             |
| Reprocess after changes      | `POST /strategies/{strategyId}/submit`               | `submit_strategy`             |
| Export holdings as CSV       | `GET /strategies/{strategyId}/companies` (CSV)       | `download_strategy_companies` |
| Archive a strategy           | `DELETE /strategies/{strategyId}`                    | `delete_strategy`             |
| List archived strategies     | `GET /strategies/archived`                           | `list_archived_strategies`    |
| Revive an archived strategy  | `POST /strategies/{strategyId}/revive`               | `revive_strategy`             |

## View holdings

Fetch a strategy's companies with `GET /strategies/{strategyId}/companies`. The endpoint reads the active version's latest completed run by default; pass `asOfDate` and/or `versionId` to select a different run. Set `includeReasoning=true` to add a per-company justification column. Use `scoringMinMarketCap` to set the minimum market cap (USD) for conviction scoring; companies below the threshold receive a `convictionScore` of 0.

```bash theme={null}
curl -X GET "https://api.noonum.ai/v2/strategies/{strategyId}/companies?includeReasoning=true" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Table columns

The companies endpoint returns these columns:

| # | Symbol | Name | Sector | Industry | Market Cap | Conviction | Ling. Beta | Mkt Buzz |
| - | ------ | ---- | ------ | -------- | ---------- | ---------- | ---------- | -------- |

With `includeReasoning=true`, a **Reasoning** column is appended. An internal **ID** column is used for per-company queries such as `GET /strategies/{strategyId}/companies/{companyId}`. You typically won't surface that ID to end users.

### Sparse data

Some companies have incomplete metadata. When a field is missing:

* Show an em dash (`—`) in the cell rather than leaving it blank.
* Keep the company in the table; don't drop it.
* Note the count at the bottom (e.g. "N companies with incomplete data").

## Understand why a company is included

Use `GET /strategies/{strategyId}/companies/{companyId}` for a single company's scores, and `GET /strategies/{strategyId}/evidences` for the underlying evidence. Lead with the linguistic beta score, then read the evidence the API returns. If you only have a name, resolve the company first with `POST /helper/companies/search`.

## Find outliers

Fetch holdings with `includeReasoning=true` and flag companies that show:

* Low conviction or low linguistic beta, signaling a tangential connection to the theme.
* A sector that's unexpected relative to the thesis.
* Thin or indirect reasoning.

These are candidates for exclusion. See [Iterate on a strategy](/v2/guides/iterate-strategy) for how to act on them.

## Analyze composition

Profile a strategy from its holdings data:

* **Sector / industry breakdown**: a frequency table with average linguistic beta per sector shows which sectors are core to the theme versus peripheral. Watch for any single sector dominating the basket, which can mean the strategy is really a sector bet, and for notable absences.
* **Market-cap distribution**: the large-cap, mid-cap, and small-cap mix.
* **Geographic exposure**: country distribution.
* **Thematic coherence**: the spread of linguistic beta scores tells you whether the strategy is tightly focused or broad.

[Signals and scores](/base/concepts/signals-and-scores) explains how to interpret each value.

## Compare two strategies

Fetch holdings for both strategies, then compute the overlap and differences. A clear layout:

### Overlap (N companies, X%)

| Company | Ticker | Conviction (Strategy A) | Conviction (Strategy B) | Sector |
| ------- | ------ | ----------------------- | ----------------------- | ------ |

### Unique to Strategy A (N companies)

| Company | Ticker | Conviction | Sector |
| ------- | ------ | ---------- | ------ |

### Unique to Strategy B (N companies)

| Company | Ticker | Conviction | Sector |
| ------- | ------ | ---------- | ------ |

### Summary

* Overlap: N companies (X% of A, Y% of B).
* Sector distribution comparison: call out the largest differences.
* Average conviction comparison. Also note any linguistic beta divergence when thematic coherence is in question.

## Export holdings

Request the companies endpoint in CSV form (MCP: `download_strategy_companies`) to get all holdings as a CSV string you can save to disk or load into a spreadsheet.

## Get a factsheet

The factsheet is generated on demand. Request (re)generation with `POST /strategies/{strategyId}/factsheet`, then read it with `GET /strategies/{strategyId}/factsheet`:

* When the PDF is ready, the `GET` returns `302 Found` with a short-lived presigned URL in the `Location` header.
* While generation is in flight or none has been requested, the `GET` returns `200 OK` with a `FactsheetStatus` body whose `status` is `generating` or `not_requested`.

Both endpoints accept `asOfDate` and `versionId` to target a specific run. Default to the active version's latest completed run. Request a factsheet after refinement to capture the updated state.

<Tip>
  When polling, disable redirect following so you can tell a `302` (ready) from a `200` (still generating).
</Tip>

## Archive a strategy

`DELETE /strategies/{strategyId}` archives the strategy rather than destroying it: it returns `204`, is hidden from reads, and is scheduled for permanent deletion after a 30-day grace window.

* List archived strategies still inside the window with `GET /strategies/archived`. Each carries `archived_at` and `permanent_delete_at`.
* Restore one with `POST /strategies/{strategyId}/revive`. This returns the revived strategy with `archived_at` and `permanent_delete_at` reset to `null`.

<Warning>
  Once the grace window has elapsed, a background job permanently purges the strategy and `POST /strategies/{strategyId}/revive` returns `410 Gone`. Revive before then if you need it back.
</Warning>

## Status codes

The strategy's top-level `status` is a discrete code for the active version's latest live run, not a raw percentage:

| Status   | Meaning                         |
| -------- | ------------------------------- |
| `0`      | Not started, or never submitted |
| `1`–`95` | In progress                     |
| `100`    | Done                            |
| `-1`     | Error                           |
| `-2`     | Permanently failed              |

`status` is run-scoped: by default it reflects the active version's latest live run. For per-version or per-date detail, read `GET /strategies/{strategyId}/versions/{versionId}`.

## Error handling

* **Strategy not found**: list your strategies to confirm the ID. An archived strategy is reachable only via `GET /strategies/archived` and `POST /strategies/{strategyId}/revive`.
* **Empty holdings**: the strategy may still be processing. Check `GET /strategies/{strategyId}`; if its `status` is not `100`, wait for the run to finish.
* **Update / submit fails**: the error message usually means the exclusions need adjustment. Revise and resubmit.
