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

# Keyword Compare Cluster

> Multi-competitor keyword overlap and lifecycle buckets for your app plus up to five rivals

```
GET /v1/keywords/compare-cluster
```

Builds a **keyword lifecycle view** for your app and **1–5 competitor** Apple app IDs: which terms appear everywhere in the cluster, which are partial overlaps, which are only yours, which appear only on the competitor side (including strict per-competitor exclusives). Uses the same latest keyword snapshot per app as [`GET /v1/keywords/compare`](/docs/keyword-compare) (two-way compare is unchanged).

***

## Query parameters

| Name        | Type   | Required | Default | Description                                                          |
| ----------- | ------ | -------- | ------- | -------------------------------------------------------------------- |
| appId       | string | Yes      | —       | Your app’s Apple App ID                                              |
| competitors | string | Yes      | —       | Comma-separated competitor app IDs (1–5), e.g. `544007664,284882215` |
| country     | string | No       | `us`    | ISO country code (e.g. `us`, `gb`, `de`, `jp`)                       |

Duplicate IDs and `appId` itself in the list are ignored. Competitors are sorted numerically in the response.

***

## Code examples

<CodeGroup>
  ```bash curl theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl "https://api.appeeky.com/v1/keywords/compare-cluster?appId=1617391485&competitors=544007664,284882215&country=us" \
    -H "X-API-Key: YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const params = new URLSearchParams({
    appId: "1617391485",
    competitors: "544007664,284882215",
    country: "us",
  });
  const res = await fetch(`https://api.appeeky.com/v1/keywords/compare-cluster?${params}`, {
    headers: { "X-API-Key": "YOUR_API_KEY" },
  });
  const { data } = await res.json();
  console.log(data.summary.withoutPrimaryCount, data.summary.inAllApps.count);
  ```
</CodeGroup>

***

## Response shape

Top-level fields:

| Field                  | Description                                                                |
| ---------------------- | -------------------------------------------------------------------------- |
| appId                  | Your app ID                                                                |
| competitorIds          | Sorted competitor IDs                                                      |
| country                | Storefront used                                                            |
| appIds                 | Cluster order: your app first, then competitors                            |
| summary                | Counts and volume/difficulty averages per bucket                           |
| inAllApps              | Sample rows (up to 80): keyword in **every** app in the cluster            |
| partialOverlap         | Sample rows: keyword in **2..n−1** apps (not universal)                    |
| primaryOnly            | Sample rows: only **your** app ranks                                       |
| competitorExclusive    | Sample rows: exactly **one** competitor ranks; you do not                  |
| withoutPrimary         | Sample rows: you have **no** rank; at least one competitor does (gap view) |
| perCompetitorExclusive | Same as competitor-exclusive terms, split by competitor app ID             |

Each row includes `keyword`, `ranks` (map of app ID → rank or `null`), `appsWithKeyword`, `volumeScore`, and `difficulty`.

### Summary buckets

| Field               | Meaning                                                                             |
| ------------------- | ----------------------------------------------------------------------------------- |
| totalUniqueKeywords | Distinct keywords across the union of all apps’ tracked lists                       |
| withoutPrimaryCount | Number of keywords where your app does not rank (subset view; see `withoutPrimary`) |
| inAllApps           | `count`, `avgVolumeScore`, `avgDifficulty` for universal keywords                   |
| partialOverlap      | Same for **partial** overlap (2..n−1 apps)                                          |
| primaryOnly         | Same for **only-you** singletons                                                    |
| competitorExclusive | Same for **single-competitor** terms (you absent)                                   |

Buckets are **disjoint**: every keyword falls into exactly one of `inAllApps`, `partialOverlap`, `primaryOnly`, or `competitorExclusive`. The `withoutPrimary` list is a separate convenience slice (all keywords where you do not rank).

***

## Credits

This endpoint costs **4 credits** per successful call (see [Rate limits](/docs/rate-limits)).

***

## Errors

| Status | Code                                  | When                                                                                           |
| ------ | ------------------------------------- | ---------------------------------------------------------------------------------------------- |
| 400    | INVALID\_APP\_ID                      | Missing or non-numeric `appId`                                                                 |
| 400    | INVALID\_COMPETITORS                  | Missing `competitors`, no valid IDs, only duplicates of `appId`, or more than five competitors |
| 401    | MISSING\_API\_KEY / INVALID\_API\_KEY | Auth                                                                                           |
| 429    | RATE\_LIMIT\_EXCEEDED                 | Insufficient monthly credits                                                                   |

***
