---
title: "Analysis Ecosystem"
method: POST
path: "/api/v1/analysis/ecosystem"
tags: ["analysis"]
---

# Analysis Ecosystem

`POST /api/v1/analysis/ecosystem`

## Request

- Base URL: `https://api.cohearence.app` (the document declares no server; this is the origin it was published from)
- URL: `https://api.cohearence.app/api/v1/analysis/ecosystem`
- Auth: HTTP bearer

All-vs-all correlation across the user's metrics — the Signal tab payload.

Unlike Build, each metric contributes only its *own* measurements (no
subtree aggregation): a parent aggregated over its children would be
trivially correlated with every one of them, which is definitional noise in
an all-vs-all view. Container metrics with no direct measurements drop out
via the empty-series filter.

Per-metric missing policy defaults to each metric's saved policy, else its
type default (:func:`_metric_default_missing`), and an explicit ``missing``
map overrides per metric. On top of the matrix
payload (r/p/n/ci_low/ci_high) this adds:

- ``q``: Benjamini–Hochberg FDR-adjusted p-values — edge visibility should
  key on these, not raw p (all-vs-all is a multiple-comparisons machine).
- ``order``: seriation permutation (indices) from hierarchical clustering,
  so a heatmap renders with similar metrics adjacent.
- ``groups``: cluster id per metric (aligned with ``metric_ids``).
- ``observed``: non-empty buckets per metric (node sizing).
- ``category_ids``: category per metric (node coloring / grouping).
- ``dismissed``: ``[metric_id_a, metric_id_b]`` pairs the user has marked
  unimportant (see ``/analysis/dismissed-correlations``) — the client hides
  these by default rather than the server dropping them, so a "show
  dismissed" toggle needs no extra round trip.

**Multi-scale mode** (``scales: ["D","W","M"]`` in the body): computes the
matrix on each requested calendar grid, pools every scale's p-values into
ONE Benjamini–Hochberg family (per-scale families would give each pair
several shots at significance), and combines them into best-scale top-level
matrices — each pair reported at the scale with the highest
confidence-adjusted strength (LCB), ties to the finer scale. The daily grid
reads a trailing ``DAILY_RECENCY_CAP_DAYS`` window unless
``custom_window: true``; coarse scales read the full window and are skipped
(never partially computed) when the data span can't reach ``MIN_CORR_N``
buckets. Adds ``best_scale`` (per-pair scale matrix), ``scales`` (computed
codes), ``scale_meta`` (window/buckets/needed/computed per requested
scale), and ``per_scale`` (full matrix set per computed scale, on the same
union id order — the edge sheet's scale profile). ``insights`` are
generated at each pair's chosen scale and carry a ``scale`` field. Without
``scales`` the endpoint behaves exactly as before (single ``resample``).

**Free plans get an outline, not the matrix.** Everything above describes the Pro
payload. A free caller receives the topology-only projection built by
:func:`_project_ecosystem` — opaque node indices, cluster ids, bucketed sizes and
index-pair edges — with no labels, statistics or insights. The endpoint itself stays
open (rather than returning 402) precisely so the locked Signal page can still draw
the user's real network shape as the thing they are being offered.

## Request body

- object

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/cohearence/apis/health-agent-api.md) · [All operations](https://skmtc.dev/cohearence/apis/health-agent-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cohearence/apis/health-agent-api/revisions/c7aee7d6ecf0?raw)
