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

# Intents

> List, drill into, and manage the user intents AI Visibility tracks for your app

An **intent** is a user goal that an AI assistant might be asked to recommend an app for. Each intent powers one row in the dashboard table — visibility %, sentiment, average position, top apps shown for it.

Intents are generated for you when you call [bootstrap](/docs/ai-visibility-bootstrap), but you can also add, rename, pause, or archive them at any time. Adding your own intents (e.g. *"Help me journal in Turkish"*) is the way to expand AI Visibility coverage beyond what the LLM proposed.

This page covers all intent endpoints:

| Endpoint                                            | Purpose                                        |
| --------------------------------------------------- | ---------------------------------------------- |
| `GET /v1/ai-visibility/:appId/intents`              | List with metrics — drives the dashboard table |
| `GET /v1/ai-visibility/:appId/intents/:intentId`    | Drill-down: prompts + latest AI answers        |
| `POST /v1/ai-visibility/:appId/intents`             | Manually add an intent                         |
| `PATCH /v1/ai-visibility/:appId/intents/:intentId`  | Rename / pause / archive                       |
| `DELETE /v1/ai-visibility/:appId/intents/:intentId` | Archive (soft delete)                          |

***

## List intents with metrics

```
GET /v1/ai-visibility/:appId/intents
```

The data shown in the **Intent Performance** table on the dashboard.

### Query parameters

| Name    | Type   | Default   | Description                                                                       |
| ------- | ------ | --------- | --------------------------------------------------------------------------------- |
| country | string | `us`      | ISO country code                                                                  |
| model   | string | `chatgpt` | One of `chatgpt`, `claude`, `gemini`, `perplexity` — metrics are scored per model |

### Response

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": [
    {
      "intentId": "9c1f...",
      "label": "Build a regular meditation practice",
      "description": "User wants an app that helps them meditate consistently every day.",
      "status": "active",
      "source": "llm",
      "visibilityPct": 78,
      "sentimentPct": 71,
      "positionAvg": 2,
      "promptsTotal": 6,
      "topApps": [
        { "trackId": "571800810", "name": "Calm",      "isOwnerApp": false },
        { "trackId": "493145008", "name": "Headspace", "isOwnerApp": false },
        { "trackId": "1234567890","name": "Sleepwell", "isOwnerApp": true  }
      ]
    },
    {
      "intentId": "a7b2...",
      "label": "Fall asleep faster and unwind",
      "description": "...",
      "status": "active",
      "source": "user",
      "visibilityPct": 75,
      "sentimentPct": 84,
      "positionAvg": 2,
      "promptsTotal": 6,
      "topApps": [ /* ... */ ]
    }
  ]
}
```

| Field           | Description                                                                                                          |
| --------------- | -------------------------------------------------------------------------------------------------------------------- |
| `intentId`      | UUID — use this for drill-down or update calls.                                                                      |
| `label`         | Display text, sentence-case.                                                                                         |
| `description`   | One-sentence explanation of the user goal. May be `null` for legacy or manually-added intents.                       |
| `status`        | `active` (scanned daily), `paused` (kept around but not scanned), `archived` (hidden from list endpoints).           |
| `source`        | `llm` (generated by the bootstrap), `user` (you added it manually).                                                  |
| `visibilityPct` | % of this intent's prompts where your app appeared, position-weighted.                                               |
| `sentimentPct`  | Average tone of the assistant when it mentioned your app, on a 0–100% scale. `null` if you weren't mentioned at all. |
| `positionAvg`   | Average rank in the assistant's list when your app was mentioned. `null` if you weren't mentioned.                   |
| `promptsTotal`  | Number of active prompts under this intent (those used in the most recent scan).                                     |
| `topApps`       | Up to 3 apps most frequently surfaced for this intent in the latest scan. `isOwnerApp: true` marks your own app.     |

***

## Drill into one intent

```
GET /v1/ai-visibility/:appId/intents/:intentId
```

Returns the same fields as the row above **plus** the prompts under that intent and the most recent AI answers for each prompt.

### Query parameters

| Name    | Type   | Default   | Description                              |
| ------- | ------ | --------- | ---------------------------------------- |
| country | string | `us`      | ISO country code                         |
| model   | string | `chatgpt` | Filters the latest answers to this model |

### Response (truncated)

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": {
    "intentId": "9c1f...",
    "label": "Reduce stress and anxiety to feel calm",
    "description": "...",
    "status": "active",
    "source": "llm",
    "visibilityPct": 73,
    "sentimentPct": 71,
    "positionAvg": 1,
    "promptsTotal": 6,
    "topApps": [ /* ... */ ],
    "prompts": [
      {
        "promptId": "p123...",
        "text": "Which app offers quick calming exercises for panic or high stress?",
        "style": "problem",
        "status": "active",
        "source": "llm",
        "latestAnswers": [
          {
            "answerId": "a789...",
            "modelSlug": "chatgpt",
            "fetchedAt": "2026-05-12T08:14:02.000Z",
            "apps": [
              { "position": 1, "name": "Calm",      "trackId": "571800810",  "isOwnerApp": false },
              { "position": 2, "name": "Headspace", "trackId": "493145008",  "isOwnerApp": false },
              { "position": 3, "name": "Sleepwell", "trackId": "1234567890", "isOwnerApp": true  }
            ]
          }
        ]
      }
    ]
  }
}
```

The `prompts[].latestAnswers[].apps` list is ordered by position. `apps[].trackId` is `null` when the assistant mentioned an app we couldn't confidently match against the App Store (very rare brands or a misspelling).

For the **raw model output and parsed sentiment per app**, use [GET /answers/:answerId](/docs/ai-visibility-answers) with the `answerId` returned here.

***

## Add an intent manually

```
POST /v1/ai-visibility/:appId/intents
```

Useful when:

* The LLM bootstrap missed something (e.g. a niche use case).
* You're launching a new feature and want to start tracking visibility for it before the first scan.
* You want to track a specific competitor angle (*"Apps similar to Calm"*).

After insertion, generate prompts for it via [POST /intents/:intentId/prompts](/docs/ai-visibility-prompts) — until at least one active prompt exists, the intent won't be scanned.

### Body

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "label": "Help me journal in Turkish",
  "description": "Turkish-speaking user wants an app to keep a daily journal."
}
```

| Field         | Type   | Required | Description                           |
| ------------- | ------ | -------- | ------------------------------------- |
| `label`       | string | Yes      | Sentence-case user goal, 8–80 chars   |
| `description` | string | No       | One-sentence explanation, ≤ 200 chars |

### Response

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": {
    "id": "f8a7...",
    "label": "Help me journal in Turkish",
    "description": "Turkish-speaking user wants an app to keep a daily journal.",
    "status": "active",
    "source": "user",
    "fingerprint": "ab12cd34..."
  }
}
```

`fingerprint` is a content hash. Re-posting the same label is safe — it returns the existing intent rather than creating a duplicate.

***

## Update / pause / archive

```
PATCH /v1/ai-visibility/:appId/intents/:intentId
```

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "label": "Build a daily meditation habit",
  "description": "Optional new description.",
  "status": "active"
}
```

All three fields are optional. Use `status: "paused"` to keep the intent and its prompts visible but stop sending them to the AI models in the next scan. Use `status: "archived"` (or DELETE) to hide it everywhere.

***

## Delete (archive)

```
DELETE /v1/ai-visibility/:appId/intents/:intentId
```

Soft-archive — the intent and its prompts/answers remain in the database but won't show up in list endpoints or be sent in future scans. Equivalent to `PATCH { status: "archived" }`.

***

## Code examples

<CodeGroup>
  ```bash curl theme={"theme":{"light":"github-light","dark":"github-dark"}}
  # Dashboard table
  curl "https://api.appeeky.com/v1/ai-visibility/1234567890/intents?model=chatgpt" \
    -H "X-API-Key: YOUR_API_KEY"

  # Drill into one intent
  curl "https://api.appeeky.com/v1/ai-visibility/1234567890/intents/9c1f...?model=chatgpt" \
    -H "X-API-Key: YOUR_API_KEY"

  # Manually add an intent
  curl -X POST "https://api.appeeky.com/v1/ai-visibility/1234567890/intents" \
    -H "X-API-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "label": "Help me journal in Turkish" }'

  # Pause an intent
  curl -X PATCH "https://api.appeeky.com/v1/ai-visibility/1234567890/intents/9c1f..." \
    -H "X-API-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "status": "paused" }'
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const HEADERS = { "X-API-Key": "YOUR_API_KEY" };

  // Render the intent table
  const intents = await fetch(
    "https://api.appeeky.com/v1/ai-visibility/1234567890/intents?model=chatgpt",
    { headers: HEADERS }
  ).then((r) => r.json());

  intents.data.forEach((row) => {
    console.log(`${row.label}  visibility=${row.visibilityPct}%  sentiment=${row.sentimentPct}%`);
  });

  // Add a custom intent
  const created = await fetch(
    "https://api.appeeky.com/v1/ai-visibility/1234567890/intents",
    {
      method: "POST",
      headers: { ...HEADERS, "Content-Type": "application/json" },
      body: JSON.stringify({
        label: "Help me journal in Turkish",
        description: "Turkish-speaking user wants an app to keep a daily journal.",
      }),
    }
  ).then((r) => r.json());

  console.log("New intent:", created.data.id);
  ```
</CodeGroup>

***

## Credits

| Endpoint                    | Cost      |
| --------------------------- | --------- |
| `GET /intents`              | 2 credits |
| `GET /intents/:intentId`    | 2 credits |
| `POST /intents`             | 1 credit  |
| `PATCH /intents/:intentId`  | Free      |
| `DELETE /intents/:intentId` | Free      |

***

## Errors

| Status | Code           | When                                                                           |
| ------ | -------------- | ------------------------------------------------------------------------------ |
| 400    | INVALID\_INPUT | `label` shorter than 8 characters or `status` is not one of the allowed values |
| 404    | NOT\_FOUND     | Intent doesn't exist or doesn't belong to this app                             |
| 401    | —              | Missing or invalid API key / JWT                                               |
| 429    | —              | Insufficient monthly credits                                                   |

***

## See also

* [Prompts](/docs/ai-visibility-prompts) — manage the queries each intent sends to the assistants
* [Answers](/docs/ai-visibility-answers) — drill into a single AI response
* [Bootstrap](/docs/ai-visibility-bootstrap) — initial intent generation
