Skip to main content

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.

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, 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:
EndpointPurpose
GET /v1/ai-visibility/:appId/intentsList with metrics — drives the dashboard table
GET /v1/ai-visibility/:appId/intents/:intentIdDrill-down: prompts + latest AI answers
POST /v1/ai-visibility/:appId/intentsManually add an intent
PATCH /v1/ai-visibility/:appId/intents/:intentIdRename / pause / archive
DELETE /v1/ai-visibility/:appId/intents/:intentIdArchive (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

NameTypeDefaultDescription
countrystringusISO country code
modelstringchatgptOne of chatgpt, claude, gemini, perplexity — metrics are scored per model

Response

{
  "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": [ /* ... */ ]
    }
  ]
}
FieldDescription
intentIdUUID — use this for drill-down or update calls.
labelDisplay text, sentence-case.
descriptionOne-sentence explanation of the user goal. May be null for legacy or manually-added intents.
statusactive (scanned daily), paused (kept around but not scanned), archived (hidden from list endpoints).
sourcellm (generated by the bootstrap), user (you added it manually).
visibilityPct% of this intent’s prompts where your app appeared, position-weighted.
sentimentPctAverage tone of the assistant when it mentioned your app, on a 0–100% scale. null if you weren’t mentioned at all.
positionAvgAverage rank in the assistant’s list when your app was mentioned. null if you weren’t mentioned.
promptsTotalNumber of active prompts under this intent (those used in the most recent scan).
topAppsUp 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

NameTypeDefaultDescription
countrystringusISO country code
modelstringchatgptFilters the latest answers to this model

Response (truncated)

{
  "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 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 — until at least one active prompt exists, the intent won’t be scanned.

Body

{
  "label": "Help me journal in Turkish",
  "description": "Turkish-speaking user wants an app to keep a daily journal."
}
FieldTypeRequiredDescription
labelstringYesSentence-case user goal, 8–80 chars
descriptionstringNoOne-sentence explanation, ≤ 200 chars

Response

{
  "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
{
  "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

# 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" }'

Credits

EndpointCost
GET /intents2 credits
GET /intents/:intentId2 credits
POST /intents1 credit
PATCH /intents/:intentIdFree
DELETE /intents/:intentIdFree

Errors

StatusCodeWhen
400INVALID_INPUTlabel shorter than 8 characters or status is not one of the allowed values
404NOT_FOUNDIntent doesn’t exist or doesn’t belong to this app
401Missing or invalid API key / JWT
429Insufficient monthly credits

See also

  • Prompts — manage the queries each intent sends to the assistants
  • Answers — drill into a single AI response
  • Bootstrap — initial intent generation