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

# Size and monitor a category

> Using the category tree for market sizing and whitespace analysis.

Category is the one entity whose IDs are shared across channels. That is what makes it the right
place to start a market question — a sizing you do today stays comparable when you add a channel.

## Walk the tree

```bash theme={null}
curl "https://api.unif.dev/v1/categories?market=US&depth=2" \
  -H "Authorization: Bearer $UNIF_API_KEY"
```

Each node carries its own metrics, so one call gives you the shape of a market:

```json theme={null}
{
  "id": "cat_beauty_personal_care",
  "name": "Beauty & Personal Care",
  "level": 1,
  "metrics": {
    "revenue": 412800000.0,
    "units_sold": 18420000,
    "avg_unit_price": 22.41,
    "revenue_growth_rate": 0.18,
    "shops_count": 24180,
    "products_count": 486200,
    "creators_count": 92400
  },
  "children": [
    { "id": "cat_beauty_skincare", "name": "Skincare", "metrics": { "revenue": 164700000.0 } }
  ]
}
```

## Find where the room is

Revenue alone tells you where the money is, not where you can get any. Two derived ratios are more
useful than either raw number.

```python theme={null}
for cat in categories:
    m = cat["metrics"]
    cat["revenue_per_shop"]    = m["revenue"] / max(m["shops_count"], 1)
    cat["revenue_per_product"] = m["revenue"] / max(m["products_count"], 1)
```

<CardGroup cols={2}>
  <Card title="High revenue per shop" icon="trophy">
    Few sellers capturing a lot. Either a genuine moat, or a category nobody has attacked yet.
    Worth a closer look either way.
  </Card>

  <Card title="Low revenue per product" icon="boxes-stacked">
    A crowded catalogue where listings compete for the same demand. Entering means fighting on
    price.
  </Card>
</CardGroup>

Pair those with growth to get a real shortlist:

```python theme={null}
opportunities = [
    c for c in categories
    if c["metrics"]["revenue_growth_rate"] > 0.15
    and c["revenue_per_shop"] > median_revenue_per_shop
]
```

Growing faster than the market, with sellers earning more than average — the combination that says
demand is arriving faster than supply.

## Compare against the parent

A subcategory growing 18% inside a parent growing 25% is losing share while looking healthy.

```python theme={null}
parent = get_category("cat_beauty_personal_care", market="US", period="last_90d")
parent_growth = parent["metrics"]["revenue_growth_rate"]

for child in parent["children"]:
    delta = child["metrics"]["revenue_growth_rate"] - parent_growth
    child["share_shift"] = delta        # negative: losing share despite growing
```

<Warning>
  Child revenue does not necessarily sum to the parent. Products can sit on a parent node directly,
  and some listings are not categorized to leaf level. Use the parent's own `revenue` for sizing —
  never a sum of its children.
</Warning>

## Track the shape over time

```bash theme={null}
curl "https://api.unif.dev/v1/categories/cat_beauty_skincare/timeseries?market=US&metrics=revenue,avg_unit_price,shops_count&granularity=week&period=last_180d" \
  -H "Authorization: Bearer $UNIF_API_KEY"
```

Three series together tell a story none tells alone:

| Pattern                           | Reading                                                  |
| --------------------------------- | -------------------------------------------------------- |
| Revenue up, `avg_unit_price` down | Growth bought with discounting. Margin is compressing.   |
| Revenue up, `shops_count` flat    | Incumbents capturing it. Hard to enter.                  |
| Revenue flat, `shops_count` up    | Saturating. Latecomers are splitting the same demand.    |
| Revenue up, `avg_unit_price` up   | The healthy case. Demand is real and premium is working. |

## Automate the watch

```json theme={null}
{
  "name": "Category shifts — US beauty subcategories",
  "source": {
    "type": "search",
    "entity_type": "shop",
    "search": {
      "market": "US",
      "period": { "preset": "last_30d" },
      "filters": {
        "category_ids": ["cat_beauty_skincare"],
        "revenue": { "gte": 250000 }
      }
    }
  },
  "schedule": "weekly",
  "webhook_id": "whk_01k3…fa"
}
```

Membership change on a shop search inside a category is an early read on competitive structure: a
new shop crossing \$250k is a new entrant, and one dropping out has stalled.

<Tip>
  Run category sizing at `last_90d` and monitoring at `last_7d`. Sizing needs a window long enough
  to be stable; monitoring needs one short enough to be news.
</Tip>
