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

# Track a competitor set

> From a list of storefront URLs to a daily brief on what changed.

You have a handful of competitors and you want to know when something about them changes. This
builds that, end to end, in four calls.

## 1. Resolve the URLs once

Start from whatever you have — a spreadsheet of storefront links.

```bash theme={null}
curl -X POST https://api.unif.dev/v1/resolve \
  -H "Authorization: Bearer $UNIF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": [
      { "type": "shop", "url": "https://www.tiktok.com/shop/glowlab",   "ref": "glowlab" },
      { "type": "shop", "url": "https://www.tiktok.com/shop/northpeak", "ref": "northpeak" },
      { "type": "shop", "url": "https://www.tiktok.com/shop/aurabeauty","ref": "aura" }
    ]
  }'
```

Store the returned IDs on your own rows. From here on you work with `shp_…` IDs, which survive the
competitor renaming their storefront — a URL does not.

```python theme={null}
ids = {r["ref"]: r["id"] for r in resolved["data"] if r["status"] == "resolved"}
unresolved = [r["ref"] for r in resolved["data"] if r["status"] != "resolved"]
```

## 2. Put them in a list

```bash theme={null}
curl -X POST https://api.unif.dev/v1/lists \
  -H "Authorization: Bearer $UNIF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Competitor shops — US skincare",
    "entity_type": "shop",
    "item_ids": ["shp_01k3…fa", "shp_01k3…fb", "shp_01k3…fc"]
  }'
```

The list is what makes every later step one call instead of a batch you rebuild.

## 3. Read the set over any window

```bash theme={null}
curl "https://api.unif.dev/v1/lists/lst_01k3…fa/items?period=last_7d&currency=USD" \
  -H "Authorization: Bearer $UNIF_API_KEY"
```

Change `period` for a different window against the same set — which is how you get
week-over-week without storing history yourself:

```python theme={null}
this_week = get_items(list_id, period="last_7d")
prior     = get_items(list_id, period="last_30d")

for shop in this_week["data"]:
    baseline = next(s for s in prior["data"] if s["id"] == shop["id"])
    weekly_run_rate = shop["metrics"]["revenue"]
    monthly_avg_week = baseline["metrics"]["revenue"] / 4.3
    shop["accelerating"] = weekly_run_rate > monthly_avg_week * 1.15
```

### The field that tells you the most

`revenue_by_source` is the one to read first on a competitor.

```json theme={null}
"revenue_by_source": { "video": 0.62, "live": 0.24, "mall": 0.09, "search": 0.05 }
```

A shop at 62% video is running an affiliate motion — its growth depends on recruiting creators,
and you can see that pipeline directly. A shop at 60% mall is winning on placement and price, and
creator outreach will not touch it. The same revenue number means two different competitors.

<Tip>
  Watch the **shift** in that split more than the level. A competitor moving from mall to video
  over six weeks has changed strategy, and the split shows it a month before revenue does.
</Tip>

## 4. Get told when something moves

```bash theme={null}
curl -X POST https://api.unif.dev/v1/trackers \
  -H "Authorization: Bearer $UNIF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Competitor revenue swings",
    "source": { "type": "list", "list_id": "lst_01k3…fa" },
    "schedule": "daily",
    "conditions": [
      { "metric": "revenue", "change": "pct", "over": "7d", "gte": 0.3 },
      { "metric": "revenue", "change": "pct", "over": "7d", "lte": -0.3 },
      { "metric": "creators_count", "change": "pct", "over": "7d", "gte": 0.5 }
    ],
    "webhook_id": "whk_01k3…fa"
  }'
```

The third condition is the useful one. A 50% jump in `creators_count` means a competitor started
recruiting affiliates hard — and it shows up a week or two before the revenue it produces.

## Going one level deeper

When a tracker fires, the follow-up is usually "what are they actually selling?"

```bash theme={null}
curl "https://api.unif.dev/v1/shops/shp_01k3…fa/products?period=last_7d&sort=-revenue&limit=20" \
  -H "Authorization: Bearer $UNIF_API_KEY"
```

Then the creators behind their top product:

```bash theme={null}
curl "https://api.unif.dev/v1/products/prd_01k3…fa/creators?period=last_30d&limit=50" \
  -H "Authorization: Bearer $UNIF_API_KEY"
```

That last call is the most directly actionable thing in this guide: it is a ranked list of the
creators who can already sell a product like yours, sorted by the revenue they generated doing it.

## Keeping the set honest

<Steps>
  <Step title="Re-resolve the misses">
    Route `not_found` rows to a person. A competitor's storefront URL changing is itself news.
  </Step>

  <Step title="Let a search tracker add members">
    A [search tracker](/docs/workflows/trackers#tracking-a-search) on your category above a revenue
    floor surfaces competitors you have not heard of. Add them to the list when they appear.
  </Step>

  <Step title="Set a floor on the conditions">
    Percentage swings on a small competitor are noise. Filter the list to shops above a revenue
    threshold, or you will be paged about nothing.
  </Step>
</Steps>
