For developers
Everything BestAppify knows about your apps is available over HTTP, and over MCP so Claude and Cursor can query it for you. Same data, same numbers as the dashboard — it all reads from one layer.
Create a key in Dashboard → API & MCP and send it as a bearer token. Keys are shown once and stored only as a hash, so if you lose one, create another. X-API-Key works too, if a header called Authorization is awkward where you are.
curl -H "Authorization: Bearer ba_live_xxx" \
https://bestappify.app/api/v1/appsA key can read everything on your account, including revenue. Keep it server-side.
Every success is { data, meta } and every failure is { error: { code, message } }. Branch on code, not on the message — codes are stable, wording is not.
{
"data": {
"app": { "app": "fast-bundle", "name": "FBP | Fast Bundle Product", "app_id": 6174 },
"keywords": [
{
"keyword": "product bundles",
"keyword_id": 31,
"position": 12,
"last_known_position": 12,
"previous_position": 17,
"change": 5,
"as_of": "2026-07-28",
"is_current": true,
"difficulty": 68,
"competition": 41,
"demand": 73
}
]
},
"meta": { "generated_at": "2026-07-28T09:14:22.031Z", "count": 1 }
}Three habits worth knowing, because they run through the whole API. A position of null means the app was not in the search results we captured — not that it has no rank. is_current: false means the rank history matched to your app lags the newest crawl, usually by a day, when a crawl saw the listing before matching it to our catalog — position is still the live figure. And where a number is reconstructed rather than reported (MRR, churn, trials, keyword demand), the response says so rather than presenting it as Shopify's own.
120 requests per minute and 10,000 per day, per key. Every response carries X-RateLimit-Remaining; a 429 carries Retry-After in seconds. MCP tool calls draw on the same allowance.
One endpoint — https://bestappify.app/api/mcp — over streamable HTTP, authenticated with the same key. Fourteen read-only tools: your apps, keyword rankings and history, opportunities, competitors and overlap, review intelligence, listing analytics, revenue and churn, plus catalog search, app details, the leaderboard, movers and niches.
claude mcp add --transport http bestappify https://bestappify.app/api/mcp \
--header "Authorization: Bearer ba_live_xxx"{
"mcpServers": {
"bestappify": {
"url": "https://bestappify.app/api/mcp",
"headers": { "Authorization": "Bearer ba_live_xxx" }
}
}
}Claude Desktop's custom connectors expect OAuth, so a key-authenticated server goes through mcp-remote, which adds the header for you.
{
"mcpServers": {
"bestappify": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://bestappify.app/api/mcp",
"--header", "Authorization: Bearer ba_live_xxx"]
}
}
}Then ask things like
Base URL https://bestappify.app. Every {app} accepts the handle, the listing URL, or an id from /api/v1/apps.
/api/v1/meYour account, apps and rate limits
Confirms the key works and returns the app references every other endpoint accepts, plus how much of your rate limit you have used.
GET /api/v1/me
/api/v1/appsList your tracked apps
Every app on your account. The `app` field is the handle used in the paths below; `tracked_app_id` and `app_id` are returned for callers that prefer ids.
GET /api/v1/apps
/api/v1/apps/{app}/keywordsKeyword rankings
Your tracked keywords for one app with today's position, the week-over-week change, and the difficulty, competition and demand indices. `position` is the live standing and is null when the app did not appear in the latest crawl. `last_known_position` and `change` come from the rank history keyed to your app in our catalog; `is_current: false` means that history is a little behind the newest crawl, not that the app stopped ranking.
GET /api/v1/apps/fast-bundle/keywords
/api/v1/apps/{app}/keywords/{keyword}One keyword, with full rank history
Daily rank history for a single tracked keyword, oldest first, plus its current standing. `{keyword}` is the term (URL-encoded) or its keyword_id.
GET /api/v1/apps/fast-bundle/keywords/product%20bundles
/api/v1/apps/{app}/opportunitiesKeyword opportunities
Keywords one of your tracked competitors ranks for and this app does not, with the competitor's position.
GET /api/v1/apps/fast-bundle/opportunities
/api/v1/apps/{app}/competitorsCompetitors and keyword overlap
Your tracked competitor set with current rank and rank change, plus the keyword overlap matrix showing where each of you places.
GET /api/v1/apps/fast-bundle/competitors
/api/v1/apps/{app}/reviewsReview intelligence
Rating distribution, monthly review trend, countries, the AI theme analysis (what merchants love, complain about and ask for) and a comparison against your tracked competitors.
GET /api/v1/apps/fast-bundle/reviews?recent=25
/api/v1/apps/{app}/analyticsListing analytics
Listing views, install clicks, installs, click-through and conversion from the Google Analytics property linked to the app, daily and totalled. Returns `connected: false` when no property is linked.
GET /api/v1/apps/fast-bundle/analytics?days=30
/api/v1/apps/{app}/revenueRevenue and churn
Monthly MRR, churn rate, trials, installs, uninstalls and net revenue from the Shopify Partner API. MRR and churn are derived from the subscription charge lifecycle — the Partner API publishes neither directly. Returns `connected: false` when the app is not linked to a Partner app.
GET /api/v1/apps/fast-bundle/revenue?months=24
/api/v1/apps/{app}/intelligenceApp intelligence
Rank trajectory over time, position in each category, nearest competitors by category rank, and how the app's entry price compares with its peers.
GET /api/v1/apps/fast-bundle/intelligence
/api/v1/market/appsSearch the App Store catalog
Search every app we hold by name — not only your own. This is how you find a competitor's handle before looking it up.
GET /api/v1/market/apps?q=bundle
/api/v1/market/apps/{app}One catalog app
Any app in our catalog by handle, listing URL or id: rating, review count, description, categories, pricing plans and listing status.
GET /api/v1/market/apps/judge-me-reviews?include=intelligence
/api/v1/market/leaderboardTop apps by review volume
The App Store leaderboard, overall or for one category. Ranked by review count, because Shopify publishes no install numbers.
GET /api/v1/market/leaderboard?category=Product%20bundles
/api/v1/market/moversWeek-over-week rank movement
Which apps climbed and which fell over the last week, from our daily rank snapshots. `change` is positive for a climb; `rank_a_week_ago: null` marks an app new to the ranking.
GET /api/v1/market/movers
/api/v1/market/nichesCategory growth and concentration
Every category with its app count, growth and the leader's share of reviews — for judging whether a niche is crowded or open.
GET /api/v1/market/niches
/api/v1/market/categoriesList categories
The App Store categories we hold at least five apps for, with counts. These ids and titles are what `?category=` accepts.
GET /api/v1/market/categories
| Code | HTTP | Meaning |
|---|---|---|
| missing_api_key | 401 | No Authorization header or X-API-Key header was sent. |
| invalid_api_key | 401 | The key does not exist or has been revoked. |
| rate_limited | 429 | More than 120 requests in the last minute. Retry-After says when to try again. |
| daily_limit_reached | 429 | More than 10,000 requests in the last 24 hours. |
| app_not_found | 404 | The app reference is not one of your tracked apps. |
| keyword_not_tracked | 404 | That keyword is not tracked for the given app. |
| category_not_found | 404 | No category matched the id or title given. |
| missing_query | 400 | A required query parameter was absent. |
| app_not_in_catalog | 409 | The app is tracked but our crawler has not matched it to a listing yet. |
| service_unavailable | 503 | The API is misconfigured or the database is unreachable. Safe to retry. |
| internal_error | 500 | An unexpected failure on our side. |
Keys take a few seconds to create, and the same one drives the API and the MCP server.
Create an API key