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

# Validate Metadata

> Check app store metadata against Apple and Google character limits

```
POST /v1/aso/metadata/validate
```

Validate your app store metadata against Apple App Store or Google Play Store character limits before submitting. Checks each field for length compliance, detects keyword stuffing, and identifies duplicate keywords.

***

## Request Body

| Field            | Type   | Required | Description                                       |
| ---------------- | ------ | -------- | ------------------------------------------------- |
| platform         | string | Yes      | `"apple"` or `"google"`                           |
| title            | string | No       | App title to validate                             |
| subtitle         | string | No       | Apple subtitle (Apple only)                       |
| keywords         | string | No       | Apple keyword field, comma-separated (Apple only) |
| shortDescription | string | No       | Google short description (Google only)            |
| fullDescription  | string | No       | Google full description (Google only)             |

<Note>
  Include only the fields relevant to your platform. For Apple, send `title`, `subtitle`, and/or `keywords`. For Google, send `title`, `shortDescription`, and/or `fullDescription`.
</Note>

***

## Character Limits

| Platform | Field            | Max Characters |
| -------- | ---------------- | -------------- |
| Apple    | title            | 30             |
| Apple    | subtitle         | 30             |
| Apple    | keywords         | 100            |
| Google   | title            | 50             |
| Google   | shortDescription | 80             |
| Google   | fullDescription  | 4,000          |

***

## Code Examples

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST "https://api.appeeky.com/v1/aso/metadata/validate" \
    -H "X-API-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "platform": "apple",
      "title": "FitFlow: Fitness Tracker",
      "subtitle": "Easy Workout Planner & Log",
      "keywords": "activity,goals,routine,challenge,calories,home,progress,simple,exercise,fitness,beginner"
    }'
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const response = await fetch(
    "https://api.appeeky.com/v1/aso/metadata/validate",
    {
      method: "POST",
      headers: {
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        platform: "apple",
        title: "FitFlow: Fitness Tracker",
        subtitle: "Easy Workout Planner & Log",
        keywords: "activity,goals,routine,challenge,calories,home,progress,simple,exercise,fitness,beginner",
      }),
    }
  );

  const { data } = await response.json();
  console.log(`All valid: ${data.allValid}`);
  data.fields.forEach((f) => console.log(`  ${f.field}: ${f.message}`));
  ```

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

  response = requests.post(
      "https://api.appeeky.com/v1/aso/metadata/validate",
      headers={"X-API-Key": "YOUR_API_KEY"},
      json={
          "platform": "apple",
          "title": "FitFlow: Fitness Tracker",
          "subtitle": "Easy Workout Planner & Log",
          "keywords": "activity,goals,routine,challenge,calories,home,progress,simple,exercise,fitness,beginner",
      },
  )

  data = response.json()["data"]
  print(f"All valid: {data['allValid']}")
  print(f"Keyword stuffing: {data['keywordStuffingDetected']}")
  print(f"Duplicate keywords: {data['duplicateKeywords']}")
  ```
</CodeGroup>

***

## Response

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": {
    "platform": "apple",
    "fields": [
      {
        "field": "title",
        "value": "FitFlow: Fitness Tracker",
        "charCount": 24,
        "maxChars": 30,
        "isValid": true,
        "message": "24/30 characters (6 remaining)"
      },
      {
        "field": "subtitle",
        "value": "Easy Workout Planner & Log",
        "charCount": 26,
        "maxChars": 30,
        "isValid": true,
        "message": "26/30 characters (4 remaining)"
      },
      {
        "field": "keywords",
        "value": "activity,goals,routine,challenge,calories,home,progress,simple,exercise,fitness,beginner",
        "charCount": 89,
        "maxChars": 100,
        "isValid": true,
        "message": "89/100 characters (11 remaining)"
      }
    ],
    "allValid": true,
    "keywordStuffingDetected": false,
    "duplicateKeywords": []
  }
}
```

### Example: Invalid Metadata

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": {
    "platform": "apple",
    "fields": [
      {
        "field": "title",
        "value": "FitFlow: The Best Fitness Tracker App For Everyone",
        "charCount": 50,
        "maxChars": 30,
        "isValid": false,
        "message": "50/30 characters (20 over limit!)"
      }
    ],
    "allValid": false,
    "keywordStuffingDetected": true,
    "duplicateKeywords": []
  }
}
```

***

## Response Fields

| Field                   | Type      | Description                                                      |
| ----------------------- | --------- | ---------------------------------------------------------------- |
| platform                | string    | `"apple"` or `"google"`                                          |
| fields                  | array     | Validation result for each submitted field                       |
| allValid                | boolean   | `true` if all fields pass character limits                       |
| keywordStuffingDetected | boolean   | `true` if excessive keyword repetition is detected               |
| duplicateKeywords       | string\[] | List of keywords that appear more than once in the keyword field |

### Field Entry

| Field     | Type    | Description                                     |
| --------- | ------- | ----------------------------------------------- |
| field     | string  | Field name (e.g. `"title"`, `"keywords"`)       |
| value     | string  | The submitted value                             |
| charCount | number  | Actual character count                          |
| maxChars  | number  | Maximum allowed characters                      |
| isValid   | boolean | `true` if within character limit                |
| message   | string  | Human-readable status with remaining/over count |

***

<Tip>
  **Apple keyword field tips:**

  * Use commas without spaces between keywords (saves characters)
  * Don't repeat words already in your title or subtitle
  * Don't include your app name or brand
  * Singular vs plural: Apple matches both, so pick the shorter form
  * Use all 100 characters — every unused character is a wasted opportunity
</Tip>

<Warning>
  **Keyword stuffing** will get your app rejected or penalized. Apple and Google both have guidelines against unnatural keyword repetition. The `keywordStuffingDetected` flag warns you when a word appears too frequently (> 5% density in descriptions).
</Warning>

***

## Errors

| Status | Code              | When                                |
| ------ | ----------------- | ----------------------------------- |
| 400    | INVALID\_PLATFORM | platform is not "apple" or "google" |
| 401    | MISSING\_API\_KEY | No API key in the request           |
