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

# Market sizing

> Count and break down a sector across geographies, exact, reproducible numbers for TAM and territory planning.

**Inputs:** a sector (`nace_code`) + scope (`country`) · a breakdown dimension (`group_by`). **Returns:** exact counts per bucket.

`POST /v2/stats` answers "how many" and "distribution of" with **exact, deterministic** counts, unlike search, which scores and ranks. Use it for market sizing, territory planning, and coverage checks.

## The recipe

Set `ISTARI_API_KEY`, then swap in your filters and `group_by` dimension. The request maps to `POST /v2/stats`.

```python theme={null}
import os
import requests

API_KEY = os.environ["ISTARI_API_KEY"]


def aggregate_market(
    country: str,
    nace_code: str,
    group_by: str = "state",
    limit: int = 20,
) -> list[dict]:
    body = {
        "filters": {
            "country": [country],
            "nace_code": [nace_code],
        },
        "group_by": group_by,  # or: country, region, organization_size, nace_code, ...
        "limit": limit,
    }
    resp = requests.post(
        "https://api.istari.ai/v2/stats",
        headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
        json=body,
    )
    return resp.json()["data"]


for bucket in aggregate_market("Germany", "NACE C: Manufacturing"):
    print(bucket["state"], bucket["count"])
```

## What each lever does

| Lever                                                                                     | Role                                                                   |
| ----------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| `filters` (`nace_code`, `country`, `region`, `organization_size`, `organization_type`, …) | Structured filters that define the slice you're sizing.                |
| `group_by`                                                                                | The breakdown dimension. Omit for a single total `COUNT(*)`.           |
| `group_by_secondary`                                                                      | Optional 2nd dimension for a cross-tab (e.g. `country` × `nace_code`). |

## Validated examples

The same tool, three different breakdowns — all exact:

**German manufacturers (`NACE C`) by `state`:** Nordrhein-Westfalen 37,627 · Bayern 31,543 · Baden-Württemberg 29,705 · Niedersachsen 13,190 · Hessen 11,675

**German manufacturers by `organization_size`:** Small (10–49) 81,270 · Micro (0–9) 62,792 · Medium (50–249) 17,598 · Large (250+) 9,473

**Switzerland by `nace_code` (sector mix):** Professional/scientific (N) 53,397 · Wholesale/retail (G) 27,872 · Manufacturing (C) 21,985 · Health (R) 19,996 · Construction (F) 19,874

## Notes

<Warning>
  **Aggregate ignores keyword filters.** `POST /v2/stats` honors structured `filters` (country, NACE, size, type, region, dates, `summary_keywords`) but **silently ignores** `keywords`. So an aggregate is a *sector + geography* denominator: never a product-specific count. Label it honestly ("manufacturers + traders in DE"), not "suppliers of product X".
</Warning>

* For a **product-specific** count, there's no exact tool: deliver the [supplier shortlist](/cookbooks/supplier-discovery) instead, and quote the aggregate only as a labeled sector denominator.
* Discover valid `summary_keywords` tags by running `POST /v2/stats` with `group_by: "summary_keywords"` on a narrow slice rather than guessing.
