Unified iOS + Android app store data with LLM pain-point mining — for ANY app. Reviews, metadata, version history, cross-store search. Built for competitive research and agent workflows.
export API_KEY="pa_..." # get one on the landing page (free tier)
# What do users hate about TikTok?
curl -s -H "x-api-key: $API_KEY" \
"https://app-pain-api.quiet-delta.workers.dev/v1/apps/android/com.zhiliaoapp.musically/painpoints?country=us" | jq
All endpoints: GET, JSON responses, gzip-friendly. Interactive docs: this page. Machine spec: /openapi.json.
| Get a key | Self-service, no credit card:
|
|---|---|
| Auth | x-api-key: pa_... header (preferred) or ?api_key= query param (quick browser tests — it ends up in logs, so prefer the header for real usage). |
| Rate limit | 60 requests/min per key → 429 with Retry-After: 60. Registration limited to 5/min per IP. |
| Free tier | 10 cold painpoint analyses per month (cache hits are unlimited and free). |
| Caching | Server-side KV cache — metadata 24h, reviews 6h, versions/search 6h, painpoints 7d. Every response carries X-Cache: HIT|MISS and a cache.hit field. Cache hits are effectively free and instant. Pro keys can add ?refresh=1 (reviews/painpoints/search) to bypass the cache read and force a fresh fetch. Degraded results (empty fetches, half-store searches during Apple rate windows) are cached briefly (15-30 min), never long-term. |
| Errors | 400 bad params · 401 missing/invalid/revoked key · 403 admin-only · 429 rate limited · 502 upstream store error (Apple/Google rate-limit windows — retry) · 503 daily LLM budget fuse blown. |
:store = ios|android; :appId = iOS numeric id (e.g. 835599320) or Android package (com.zhiliaoapp.musically). Query: country (default us).
curl -s -H "x-api-key: $API_KEY" "https://app-pain-api.quiet-delta.workers.dev/v1/apps/ios/835599320?country=us"
# {"app":{"store":"ios","id":"835599320","name":"TikTok","developer":"TikTok Ltd.",
# "category":"Entertainment","ratingHistogram":{"1":2400000,"2":600000,...},
# "price":"Free","hasIap":null},"cache":{"hit":false}}
Unified schema across stores. Query: country, page (1–10, 50/page), sort=recent|helpful (Android both; iOS best-effort store order).
curl -s -H "x-api-key: $API_KEY" \
"https://app-pain-api.quiet-delta.workers.dev/v1/apps/android/com.zhiliaoapp.musically/reviews?page=1&sort=recent"
# {"reviews":[
# {
# "id": "0f37b2fc-ee59-4581-9252-7d32bb13228f",
# "rating": 2,
# "title": null,
# "body": "my views keep dropping and I'm shadow banned",
# "version": "37.9.2",
# "country": "us",
# "date": "2026-10-14T03:39:50-07:00",
# "devReply": null,
# "thumbsUp": 14
# }
# ],"cache":{"hit":true}}
The core endpoint: fetches up to 500 recent reviews, keeps negative ones (rating <= maxRating, default 3), then LLM clusters complaints into ranked pain points with evidence quotes. Cached 7 days. Query: country, maxRating (1–5), reviews (rounded up to 100 / 300 / 500, default 300).
curl -s -H "x-api-key: $API_KEY" \
"https://app-pain-api.quiet-delta.workers.dev/v1/apps/ios/835599320/painpoints?reviews=300"
# {
# "painPoints": [
# {
# "title": "Intrusive Ads and Ad Frequency",
# "summary": "Users are frustrated by the high frequency of ads, especially mid-video and unskippable formats.",
# "sharePercent": 16,
# "severity": 4,
# "evidence": ["ads every two videos", "so many ads in every single video I watch it's so annoying"],
# "nReviews": 16
# },
# {
# "title": "Shadowbanning and Algorithm Suppression",
# "summary": "Users report their videos receive no views or engagement, suspecting shadowbanning.",
# "sharePercent": 12,
# "severity": 4,
# "evidence": ["my views keep dropping and I'm shadow banned"],
# "nReviews": 12
# }
# ],
# "overview": "Monetization pressure (ads) and opaque algorithm changes dominate complaints.",
# "analyzedReviews": 300,
# "negativeReviews": 187,
# "model": "glm-4.5-flash",
# "generatedAt": "2026-10-16T12:00:00.000Z"
# }
Compares two archived analyses of the same app: every theme is labelled new, resolved, rising, falling or stable with its share change in percentage points. Defaults to the latest snapshot vs ~30 days earlier; pin dates with from / to (YYYY-MM-DD). Reads the archive only — no LLM quota. Snapshots accumulate ~weekly per app, so the timeline only gets deeper.
curl -s -H "x-api-key: $API_KEY" "https://app-pain-api.quiet-delta.workers.dev/v1/apps/android/com.spotify.music/painpoints/trend"
# {"to":{"date":"2026-11-20",...},"from":{"date":"2026-10-23",...},
# "items":[{"title":"Shuffle repeats the same songs","status":"rising","shareFrom":12,"shareTo":21,"deltaPp":9,...}, ...]}
Per-version review stats — catch a rating crash right after a bad release (competitive iteration monitoring). Android: aggregated from up to 900 recent reviews. iOS: current version + release notes; distribution best-effort. Query: country.
curl -s -H "x-api-key: $API_KEY" "https://app-pain-api.quiet-delta.workers.dev/v1/apps/android/com.spotify.music/versions"
# {
# "store": "android",
# "id": "com.spotify.music",
# "current": { "version": "9.1.94.525", "releasedAt": "2026-10-14T18:11:03.344Z", "releaseNotes": null },
# "versions": [
# { "version": "9.1.94.525", "reviews": 437, "avgRating": 3.41, "firstSeen": "2026-10-14T18:11:03.344Z", "lastSeen": "2026-10-14T18:11:03.344Z" },
# { "version": "9.1.90.486", "reviews": 70, "avgRating": 4.05, "firstSeen": "2026-10-09T07:19:06.672Z", "lastSeen": "2026-10-13T20:39:06.672Z" }
# ],
# "sampledReviews": 900
# }
Both stores merged (or one via store=ios|android). Query: q (required), limit (≤30, default 10), country.
curl -s -H "x-api-key: $API_KEY" "https://app-pain-api.quiet-delta.workers.dev/v1/search?q=notion&limit=6"
# {
# "query": "notion",
# "results": [
# { "store": "ios", "id": "1232780281", "name": "Notion: Notes, Tasks, AI", "developer": "Notion Labs, Incorporated", "rating": 4.78, "ratingsCount": 162133, "price": "Free" },
# { "store": "android", "id": "notion.id", "name": "Notion: Notes, Tasks, AI", "developer": null }
# ]
# }
# 1. find competitors → /v1/search?q=habit%20tracker
# 2. compare their pain → /v1/apps/ios/<id>/painpoints (loop over ids)
# 3. track what got worse → /v1/apps/<store>/<id>/painpoints/trend
# 4. watch version damage → /v1/apps/android/<pkg>/versions (avgRating per release)
# 5. drill into raw complaints → /v1/apps/<store>/<id>/reviews?page=2
No API key needed — paste the URL and go. Keyless use gets unlimited cached results (~100 popular apps are always pre-analyzed) plus a few new analyses per day; add an x-api-key header for your own quota. Server URL:
https://app-pain-api.quiet-delta.workers.dev/mcp
Mainland China: *.workers.dev is not reachable on a direct connection — enable your proxy (system proxy or TUN mode) before connecting, otherwise the client times out after ~30s. Everywhere else works as-is.
| Claude Code | claude mcp add --transport http app-pain-api https://app-pain-api.quiet-delta.workers.dev/mcp |
|---|---|
| Claude Desktop / claude.ai | Settings → Connectors → Add custom connector → paste the URL above. |
| ChatGPT | Settings → Apps & Connectors → Developer mode → Create → paste the URL, authentication: No authentication. |
| Cursor | Button above, or ~/.cursor/mcp.json: {"mcpServers":{"app-pain-api":{"url":"https://app-pain-api.quiet-delta.workers.dev/mcp"}}} |
| VS Code | Button above, or code --add-mcp '{"name":"app-pain-api","type":"http","url":"https://app-pain-api.quiet-delta.workers.dev/mcp"}' |
| Windsurf | ~/.codeium/windsurf/mcp_config.json: {"mcpServers":{"app-pain-api":{"serverUrl":"https://app-pain-api.quiet-delta.workers.dev/mcp"}}} |
| Codex CLI | ~/.codex/config.toml: [mcp_servers.app-pain-api] url = "https://app-pain-api.quiet-delta.workers.dev/mcp" |
| Gemini CLI | ~/.gemini/settings.json: {"mcpServers":{"app-pain-api":{"httpUrl":"https://app-pain-api.quiet-delta.workers.dev/mcp"}}} |
| stdio-only clients | npx -y mcp-remote https://app-pain-api.quiet-delta.workers.dev/mcp as the command |
| With an API key | Add header x-api-key: pa_... (e.g. claude mcp add ... --header "x-api-key: pa_..."); clients that can't set headers can use https://app-pain-api.quiet-delta.workers.dev/mcp?api_key=pa_... |
Tools: search_apps · mine_app_pain_points ★ · get_pain_trend · get_app_details · get_version_history · get_app_reviews · watch_competitors (paid: alerts to Slack/Discord). Prompts: competitor_pain_report · app_pain_deep_dive. appId also accepts App Store / Google Play links. Cold analyses take 30–120s and stream progress notifications; repeat calls are instant (7-day cache). When the server-side allowance runs out, the tool hands your agent the prepared negative reviews to cluster with its own model — no extra keys, and your model credentials never touch our servers.
Try asking: "What do users hate most about Duolingo, and is it getting better?" · "Compare the top 4 habit tracker apps' pain points and find a product gap." · "Watch my 3 biggest competitors and alert our Slack when their users start complaining about something new."
Already running an LLM (Claude, Cursor, your own agent)? Add ?mode=agent to /painpoints: we still fetch and filter the reviews, but instead of clustering them on our side we return up to 120 prepared negative reviews plus clustering instructions — your model does the analysis. No analysis quota is used (a daily cap of 30 / 100 / 300 pulls by plan applies), and no model credentials are ever sent to us. If a server-side result is already cached, you get that instead. Plan features (countries, depth) apply as usual. Over MCP this happens automatically when the server-side allowance runs out (analyze: "auto"), or on demand with analyze: "agent".
curl -s -H "x-api-key: $API_KEY" "https://app-pain-api.quiet-delta.workers.dev/v1/apps/android/com.todoist/painpoints?mode=agent"
# {"mode":"agent","analyzedReviews":300,"negativeReviews":74,"included":74,
# "instructions":"These are 74 negative reviews ... Cluster them into the top 6-10 distinct pain points ...",
# "outputShape":{"painPoints":[...],"overview":""},"reviews":[{"rating":1,"text":"...","version":"12.3","date":"2026-10-20"}, ...]}
Put competitors on a watchlist and get a digest of their new 1–2★ reviews and new or rising pain points — weekly on Starter (2 apps), daily on Pro (15 apps). Slack and Discord webhooks are formatted natively; any other https URL receives JSON (type: "app_pain.digest"). Quiet periods send nothing. Agents can do all of this through the watch_competitors MCP tool.
curl -s -X POST -H "x-api-key: $API_KEY" -H 'Content-Type: application/json' "https://app-pain-api.quiet-delta.workers.dev/v1/watchlist" -d '{"appId":"https://play.google.com/store/apps/details?id=com.spotify.music","webhookUrl":"https://hooks.slack.com/services/..."}'
curl -s -X POST -H "x-api-key: $API_KEY" "https://app-pain-api.quiet-delta.workers.dev/v1/watchlist/test" # sample digest right now
# Slack: *App Pain monitor* — 2026-11-03
# *Spotify: Music and Podcasts* (android)
# • 14 new 1-2★ reviews
# ★ "Ads after literally every song now…"
# • rising 18% → 27% (+9pp): Excessive and repetitive ads
Paid plans are bought through Creem (merchant of record). Your license key is your API key — it is shown right after checkout, included in the receipt email, and always retrievable from the Creem customer portal (link in the receipt). Use it as x-api-key; it works for REST and MCP within seconds of payment. Cancel anytime: the key keeps working until the end of the paid period; renewing reactivates the same key. Check your plan, usage and limits with GET /v1/usage. Monthly quotas reset on the 1st (UTC); cached results never count against analysis quotas.
curl -s -H "x-api-key: $API_KEY" "https://app-pain-api.quiet-delta.workers.dev/v1/usage"
# {"tier":"starter","month":"2026-11","usage":{"calls":212,"painAnalyses":4,"deepDives":1},
# "limits":{"calls":1500,"painAnalyses":30,"deepDives":3},"resetsAt":"2026-12-01T00:00:00.000Z"}
| iOS reviews | Sourced from Apple's public channels; ordering is the store's default (helpfulness-leaning). Depth is currently ~50 recent reviews per app (Apple tightened edge access to deeper pages) — painpoint analyses on iOS run on that window and say so via analyzedReviews. Version field often null. |
| Android reviews | Unlimited depth via pagination; version and developer replies included. |
| Fair use | Cached responses are cheap; cold fetches hit Apple/Google — don't hammer page 1–10 for the same app in a loop. 502 means an upstream rate-limit window, retry after a minute. |
Privacy Policy · Terms of Service · Acceptable Use Policy · Refund Policy · AI analyses are machine-generated summaries of public reviews — verify before acting. Contact: apppainapi@proton.me