> ## 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 Metrics

> Search volume and ranking difficulty scores for any keyword

```
GET /v1/keywords/metrics
```

Returns detailed search volume and ranking difficulty scores for a keyword. The scoring algorithms analyse the store's search results, top app review volumes, autocomplete position, rating distributions, and developer diversity to produce actionable scores. Works for both the App Store and Google Play (`platform=google`) using store-native signals.

***

## Query Parameters

| Name      | Type   | Required | Default | Description                                                                                                                       |
| --------- | ------ | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| keyword   | string | Yes      | —       | Search keyword (min 2 characters)                                                                                                 |
| platform  | string | No       | `apple` | `apple` (default) or `google` for Google Play — see [Platforms](/docs/platforms)                                                  |
| country   | string | No       | `us`    | ISO country code — when **`countries` is omitted** (single storefront)                                                            |
| countries | string | No       | —       | Comma-separated ISO codes (e.g. `us,gb,de`) for multiple storefronts in one request (max 25). When set, **`country` is ignored**. |
| lang      | string | No       | `en`    | Google Play language code (used when `platform=google`)                                                                           |

***

## Code Examples

<CodeGroup>
  ```bash curl theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl "https://api.appeeky.com/v1/keywords/metrics?keyword=puzzle+game&country=us" \
    -H "X-API-Key: YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const res = await fetch(
    "https://api.appeeky.com/v1/keywords/metrics?keyword=puzzle+game&country=us",
    { headers: { "X-API-Key": "YOUR_API_KEY" } }
  );
  const { data } = await res.json();
  console.log(`Volume: ${data.volumeScore}/100`);
  console.log(`Difficulty: ${data.difficulty}/100`);
  console.log(`Results: ${data.resultCount}`);
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import requests

  res = requests.get(
      "https://api.appeeky.com/v1/keywords/metrics",
      params={"keyword": "puzzle game", "country": "us"},
      headers={"X-API-Key": "YOUR_API_KEY"},
  )
  data = res.json()["data"]
  print(f"Volume: {data['volumeScore']}/100")
  print(f"Difficulty: {data['difficulty']}/100")
  print(f"Results: {data['resultCount']}")
  ```

  ```bash Google Play theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl "https://api.appeeky.com/v1/keywords/metrics?platform=google&keyword=puzzle+game&country=us" \
    -H "X-API-Key: YOUR_API_KEY"
  ```
</CodeGroup>

<Note>
  On **Google Play**, `volumeScore` and `difficulty` are computed from store-native signals (search results, ratings, review counts, autocomplete). The enrichment fields `rankVolatility`, `marketDominance`, and `historicalDays` are currently Apple-only — on Google they return `null` and `interpretation.trustworthy` is `false`.
</Note>

***

## Response

Single storefront (default — same as before):

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": {
    "keyword": "puzzle game",
    "country": "us",
    "volumeScore": 72,
    "difficulty": 85,
    "resultCount": 3450,
    "topAppsAvgRating": 4.6,
    "topAppsAvgReviews": 284500,
    "developerDiversity": 0.82,
    "rankVolatility": 12.4,
    "marketDominance": 0.31,
    "historicalDays": 90,
    "updatedAt": "2026-04-21T03:14:00Z",
    "interpretation": {
      "stability": "volatile",
      "competition": "competitive",
      "trustworthy": true
    }
  },
  "meta": {
    "lastScrapedAt": "2026-04-21T03:14:00Z",
    "dataAgeHours": 7,
    "source": "stored",
    "freshness": "fresh"
  }
}
```

Multi-country (`?countries=us,gb`):

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": {
    "keyword": "puzzle game",
    "countries": ["us", "gb"],
    "results": {
      "us": {
        "keyword": "puzzle game",
        "country": "us",
        "volumeScore": 72,
        "difficulty": 85,
        "resultCount": 3450,
        "topAppsAvgRating": 4.6,
        "topAppsAvgReviews": 284500,
        "developerDiversity": 0.82
      },
      "gb": {
        "keyword": "puzzle game",
        "country": "gb",
        "volumeScore": 68,
        "difficulty": 80,
        "resultCount": 3100,
        "topAppsAvgRating": 4.5,
        "topAppsAvgReviews": 200000,
        "developerDiversity": 0.78
      }
    }
  }
}
```

***

## Response Fields

| Field              | Type           | Description                                                                                                                                             |
| ------------------ | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| keyword            | string         | The queried keyword                                                                                                                                     |
| country            | string         | ISO country code (single-storefront response only)                                                                                                      |
| countries          | array          | List of ISO codes (multi-storefront response only)                                                                                                      |
| results            | object         | Per-country metric objects keyed by ISO code (multi-storefront only)                                                                                    |
| volumeScore        | number         | Estimated search volume score (0–100)                                                                                                                   |
| difficulty         | number         | Ranking difficulty score (0–100)                                                                                                                        |
| resultCount        | number         | Total apps in the App Store search results for this keyword                                                                                             |
| topAppsAvgRating   | number         | Average star rating of the top-ranking apps (1.0–5.0)                                                                                                   |
| topAppsAvgReviews  | number         | Average review count of the top-ranking apps                                                                                                            |
| developerDiversity | number         | Ratio of unique developers in the top results (0.0–1.0). Higher = more diverse.                                                                         |
| rankVolatility     | number \| null | Average daily rank change observed across the top results — higher = more chaotic SERP, lower = stable incumbents. `null` if no historical data yet.    |
| marketDominance    | number \| null | Share of total review weight held by the #1 app on this keyword (0.0–1.0). High dominance = one app owns the keyword. `null` if no historical data yet. |
| historicalDays     | number \| null | Number of days of historical observations the enriched signals are based on. `null` if not yet enriched.                                                |
| updatedAt          | string \| null | ISO timestamp of the last enrichment refresh. `null` if not yet enriched.                                                                               |
| interpretation     | object         | Plain-English bucketing of the volatility / dominance / history signals — see "Interpretation" below.                                                   |

### `interpretation`

| Field       | Type    | Values                                                                                   | Meaning                                                                                                |
| ----------- | ------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| stability   | string  | `stable` (volatility \< 3), `moderate` (3–10), `volatile` (> 10), `unknown`              | How shaky the SERP has been over the trailing window.                                                  |
| competition | string  | `fragmented` (dominance \< 0.3), `competitive` (0.3–0.6), `dominated` (> 0.6), `unknown` | How concentrated review-share is at the top of the SERP.                                               |
| trustworthy | boolean | `true` when `historicalDays >= 7`                                                        | False means the volatility/dominance numbers exist but the trend they describe is too short to act on. |

Use `interpretation` for at-a-glance UI labels and LLM summaries — the underlying numerical fields stay the source of truth for filtering / sorting.

### `meta` envelope (response-level)

Every keyword response includes a `meta` block describing data freshness:

| Field         | Type           | Description                                                                                                                                                             |
| ------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| lastScrapedAt | string \| null | ISO timestamp of the most recent data point that backs this response.                                                                                                   |
| dataAgeHours  | number \| null | Whole-hour age relative to `lastScrapedAt`.                                                                                                                             |
| source        | string         | `stored` (served from a precomputed snapshot), `live` (fetched from the App Store in real-time for this request), or `hybrid` (a snapshot enriched with a live lookup). |
| freshness     | string         | `fresh` (\< 24h), `stale` (24h–7d), `very-stale` (> 7d), or `unknown`.                                                                                                  |

***

## Scoring Algorithms

### Volume Score (0–100)

The volume score estimates relative search popularity using three weighted signals:

| Signal             | Weight | Description                                                             |
| ------------------ | ------ | ----------------------------------------------------------------------- |
| iTunes resultCount | 40%    | Number of apps in search results, normalized to a max of 200            |
| Top app reviews    | 40%    | Average review count of top apps, normalized to a max of 500K           |
| Autocomplete bonus | 20%    | Bonus points if the keyword appears in Apple's autocomplete suggestions |

### Difficulty Score (0–100)

The difficulty score measures how hard it is to rank in the top results:

| Signal               | Weight | Description                                                        |
| -------------------- | ------ | ------------------------------------------------------------------ |
| Average rating       | 20%    | Higher avg rating of top apps = harder to compete                  |
| Average review count | 35%    | More reviews on top apps = stronger incumbents                     |
| Developer diversity  | 25%    | Low diversity = dominated by a few publishers = harder to break in |
| Dominance ratio      | 20%    | How much of the market the #1 app captures relative to others      |

***

## Score Ranges

| Range  | Label     | Volume Meaning                       | Difficulty Meaning                           |
| ------ | --------- | ------------------------------------ | -------------------------------------------- |
| 0–20   | Very Low  | Minimal search traffic               | Very easy to rank — few strong competitors   |
| 21–40  | Low       | Some searches, niche keyword         | Relatively easy — moderate competition       |
| 41–60  | Medium    | Moderate search volume               | Competitive — established apps present       |
| 61–80  | High      | Popular keyword, significant traffic | Hard — strong incumbents dominate            |
| 81–100 | Very High | Top-tier keyword, massive volume     | Extremely hard — dominated by top publishers |

***

<Note>
  The scoring algorithms analyze the **top search results** from iTunes at query time. Scores may fluctuate slightly over time as the App Store rankings change.
</Note>

<Tip>
  **Combine with opportunity score**: Use this endpoint to evaluate individual keywords, then cross-reference with the `opportunity` score from `GET /v1/apps/:id/keywords` for a complete prioritization framework. High volume + low difficulty + high opportunity = your best ASO targets.
</Tip>

***

## Errors

| Status | Code             | When                              |
| ------ | ---------------- | --------------------------------- |
| 400    | INVALID\_KEYWORD | Keyword shorter than 2 characters |
| 401    | UNAUTHORIZED     | Missing or invalid API key        |
| 429    | RATE\_LIMITED    | Too many requests — slow down     |
| 500    | INTERNAL\_ERROR  | Error calculating metrics         |
