POST /scan— kick off an immediate re-scan (useful right after a metadata change or when you want fresh data without waiting for the daily run).GET / PUT /settings— choose which AI models to scan, how often the scheduled scans run, and whether AI Visibility is enabled at all for the app.
Trigger an on-demand scan
GET /overview within roughly 3–6 minutes.
Scheduled scans run automatically — you should only need this endpoint when you want fresh data now (after a launch, a new feature, a metadata change, or right after adding new intents/prompts).
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| appId | string | Yes | Apple App ID (numeric) |
Body
No body is required. The scan uses the app’s saved settings (country, models, language).Response
| Field | Description |
|---|---|
taskRunId | Trigger.dev run id for the orchestrator. Useful for support requests but not normally needed. |
promptsTotal | Number of active prompts that will be sent. |
models | The models that will receive each prompt — derived from your settings, capped at your plan’s maxModels and filtered to providers Appeeky has API keys for. |
estimatedCost | AI Visibility credits this scan will consume. Same value as the X-Credit-Cost header. |
400 NO_PROMPTS. Run bootstrap first or add intents + prompts manually.
Same-day idempotency
Each(prompt × model × day) is fingerprinted before the model call. Re-running /scan later the same day won’t charge you for a second round of model calls — the existing answers are reused. So you can hit “Refresh” in the UI without worrying about double-billing.
If you really want a re-query on the same day (e.g. you suspect a flaky earlier answer), pause the prompt, scan, then re-activate it; or wait until tomorrow’s automatic scan.
Get or update settings
GET /v1/ai-visibility/:appId/settings
Returns the current scanning configuration for the app, plus the list of AI providers Appeeky currently has credentials for (so you can render a UI that only offers configurable options).
settings is null until you’ve called bootstrap at least once.
tier reflects the caller’s current plan and the per-plan AI Visibility caps (see pricing overview). Use it in your dashboard to grey out model toggles the user can’t actually enable: e.g. on the small plan above, only the first 2 entries in availableModels are selectable.
aiVisibilityCredits is the dedicated credit bucket for AI Visibility (separate from your general API quota). estimatedMonthlyCost is a forecast based on the current cadence and enabled models — (prompts × Σ(model_cost)) × (30 / scanCadenceDays). Use it to surface “you’ll spend ~5,760 / 8,000 this month” before the user commits to a setting change.
PUT /v1/ai-visibility/:appId/settings
| Field | Type | Description |
|---|---|---|
enabled | bool | Master switch. false stops scheduled scans (existing data and intents stay). |
models | string[] | Which AI models to scan. Subset of availableModels. The chatgpt model is the most commonly enabled — most users start with one or two and expand later. |
scanCadenceDays | int | 0 disables scheduled scans, 1 = daily, 3 = every 3 days (default), 7 = weekly, max 30. The next scan after a settings change is scheduled scanCadenceDays from now. AI recommendations change slowly, so 3-day cadence captures most movement at a third of daily’s credit cost. |
language | string | ISO 639-1, biases newly-generated prompts. Doesn’t affect existing prompts. |
Cost controls
Both manual and scheduled scans bill against the dedicated AI Visibility credit bucket (api_plans.ai_visibility_monthly_credits) — not your general API quota. Each call costs per (prompt × model), summed across every model you’ve enabled.
| Model | Credits per call |
|---|---|
chatgpt | 9 |
claude | 15 |
gemini | 5 |
perplexity | 3 |
| Models enabled | Credits per scan | Monthly (3-day cadence) | Monthly (daily cadence) |
|---|---|---|---|
chatgpt only | 48 × 9 = 432 | ~4,300 | ~13,000 |
chatgpt + perplexity | 48 × 12 = 576 | ~5,800 | ~17,300 |
| All four | 48 × 32 = 1,536 | ~15,400 | ~46,100 |
GET /settings → aiVisibilityCredits.estimatedMonthlyCost. Manual /scan calls return the per-call charge in X-Credit-Cost (and the response body’s estimatedCost).
What happens when the bucket runs low
| Trigger | Behavior |
|---|---|
Manual /scan | Hard fail — the API returns 429 AI_VISIBILITY_QUOTA_EXCEEDED with the requested cost and your remaining balance. No scan runs, no credits deducted. |
| Scheduled cron scan | Graceful degrade — the orchestrator drops models in cost-descending order (claude → gemini → perplexity), keeping chatgpt as the most user-valuable fallback, until the scan fits remaining budget. The dropped models are recorded on the run row (models_dropped, degraded_reason). When even chatgpt-only doesn’t fit, the scan is skipped entirely and next_scan_at is pushed out 24h. |
ai_visibility_runs.models_dropped — it’s empty when the full requested set ran, otherwise it lists the silently-removed models so you can prompt the user to upgrade.
Tier limits on models[]
The PUT endpoint enforces a per-plan cap on how many models you can enable simultaneously:
| Plan | Monthly AI Visibility credits | Allowed models |
|---|---|---|
| Free | 0 | — (AI Visibility unavailable) |
| Indie | 3,000 | 1 |
| Starter | 8,000 | 2 |
| Growth | 20,000 | 4 (all) |
| Pro | 50,000 | 4 (all) |
| Enterprise | 150,000 | 4 (all) |
models: ["chatgpt", "claude"] on the Indie plan, the API returns 403 TIER_LIMIT_EXCEEDED and your settings stay unchanged.
A practical recommendation:
- Start with
["chatgpt"]. It’s the dominant assistant by usage and gives you the most signal per credit. - Add
perplexitywhen you want web-grounded comparisons (Perplexity returns citations alongside the answer — useful for understanding why the assistant picked an app). - Add
claudeandgeminiwhen you have evidence your audience uses them. Note thatclaudeis the most expensive at 15 credits/call — the scheduler will drop it first when budget gets tight.
Code examples
Credits
| Endpoint | Cost | Bucket |
|---|---|---|
POST /scan | Dynamic — Σ(model credit cost) × prompts_count. Returned in X-Credit-Cost. | AI Visibility |
GET /settings | 1 credit | AI Visibility |
PUT /settings | Free | — |
api_plans.ai_visibility_monthly_credits. The middleware sets X-AiVisibility-Limit and X-AiVisibility-Remaining headers on the response so dashboards can render the current bucket state.
Errors
| Status | Code | When |
|---|---|---|
| 400 | NO_PROMPTS | App has no active prompts — run bootstrap first |
| 400 | INVALID_APP_ID | Missing or non-numeric app ID |
| 403 | TIER_LIMIT_EXCEEDED | models[] exceeds your plan’s max, or AI Visibility is unavailable on your plan |
| 401 | — | Missing or invalid API key / JWT |
| 429 | AI_VISIBILITY_QUOTA_EXCEEDED | Insufficient AI Visibility credits — top up, downgrade your model selection, or wait for the quota to reset |
See also
- Bootstrap — required before the first scan
- Overview endpoint — read fresh data after the scan completes
- Intents — change what’s scanned
- Prompts — change which queries are sent

