API
Base URL https://appreviews.vibeserved.com. Every response is JSON. Times are ISO 8601 in UTC. Two stores, three endpoints, one schema.
# 1. sign up, copy the key from the dashboard
export KEY=ar_...
# 2. look up an app
curl https://appreviews.vibeserved.com/v1/apps/apple/310633997 \
-H "Authorization: Bearer $KEY"
# 3. page through its reviews
curl "https://appreviews.vibeserved.com/v1/apps/google/com.whatsapp/reviews?sort=recent" \
-H "Authorization: Bearer $KEY"
Authentication
Send your key in either header. Keys start with ar_, are created on the dashboard, and are shown exactly once.
Authorization: Bearer ar_...
X-Api-Key: ar_...
A missing, unknown or revoked key is a 401. Keys are stored as SHA-256 hashes; if you lose one, create another and revoke the old one.
Credits and limits
- One successful request costs one credit: one app lookup, or one page of up to 50 reviews.
- Errors cost nothing.
4xx,429and503responses never charge. - Upstream responses are cached for 10 minutes. A cache hit is still one request and still one credit.
- Every metered
200carriesX-Credits-Remaining./v1/meis free. - 60 requests per minute per key. Over that you get
429withRetry-Afterin seconds. - At zero credits you get
402until you buy a pack. Signup grants 300.
/v1/apps/{store}/{app_id}App metadata for one storefront.
| store | apple or google |
|---|---|
| app_id | Apple numeric track id (310633997) or Play package name (com.whatsapp) |
| country | Two-letter storefront, default us |
$ curl "https://appreviews.vibeserved.com/v1/apps/apple/310633997?country=us" \
-H "Authorization: Bearer $KEY"
{
"store": "apple",
"app_id": "310633997",
"country": "us",
"title": "WhatsApp Messenger",
"developer": "WhatsApp Inc.",
"rating": 4.68,
"rating_count": 18523223,
"version": "26.34.72",
"released_at": "2009-05-04T02:43:49Z",
"updated_at": "2026-08-31T13:21:38Z",
"genre": "Social Networking",
"icon_url": "https://is1-ssl.mzstatic.com/image/thumb/Purple221/v4/cb/b5/1f/cbb51f14-c56c-f35d-421b-c89f5592a923/AppIcon-0-0-1x_U007epad-0-0-0-1-0-0-sRGB-0-85-220.png/512x512bb.jpg",
"description": "...",
"price": 0.0,
"currency": "USD",
"url": "https://apps.apple.com/us/app/whatsapp-messenger/id310633997?uo=4",
"bundle_id": "net.whatsapp.WhatsApp",
"min_os_version": "15.1",
"content_rating": "12+",
"release_notes": "...",
"installs": null
}
Fields a store does not publish are null: bundle_id, min_os_version on Play; installs on the App Store. Play's version is null when it "varies with device".
/v1/apps/{store}/{app_id}/reviewsUp to 50 reviews per page, newest first by default.
| sort | recent (default), helpful, rating. The App Store has no rating sort and answers 400. |
|---|---|
| country | Two-letter storefront, default us |
| cursor | The next_cursor from the previous page, passed back verbatim |
$ curl "https://appreviews.vibeserved.com/v1/apps/google/com.whatsapp/reviews?sort=recent" \
-H "Authorization: Bearer $KEY"
{
"store": "google",
"app_id": "com.whatsapp",
"country": "us",
"sort": "recent",
"reviews": [
{
"id": "b927c27d-71e8-4636-b7ab-7cef2c786436",
"author": "Amma Gana",
"rating": 5,
"title": null,
"body": "Whatsapp",
"version": "2.26.32.83",
"created_at": "2026-09-02T16:55:53Z",
"helpful_count": 0,
"developer_reply": {
"body": "Thanks for the feedback.",
"replied_at": "2026-09-03T10:29:55Z"
},
"url": null
}
],
"next_cursor": "v1.WyJnb29nbGUiLCJjb20ud2hhdHNhcHAiLCJ1cyIsInJlY2VudCIsIkNzY0IiXQ.k3Qx7f2Zt0JgXQ"
}
App Store reviews have title and url and no developer_reply. Play reviews have developer_reply and no title or url. Everything else is identical across stores.
/v1/mefreeBalance and limits for the calling key. Never costs a credit, so it is safe to poll.
$ curl https://appreviews.vibeserved.com/v1/me -H "Authorization: Bearer $KEY"
{
"credits": 4812,
"key_prefix": "ar_7Hk2mP9q",
"rate_limit": {
"per_minute": 60
}
}
/v1/demofreePublic sample endpoint. No key, no credits. Lists a few sample apps; GET /v1/demo/{id} returns a fixed reviews-shaped payload for that app. Same fields as the real reviews endpoint, with demo: true. The homepage embeds these samples in the hero.
$ curl https://appreviews.vibeserved.com/v1/demo/apple-whatsapp
/mcpMCP server
The same three operations as MCP tools, served over Streamable HTTP at https://appreviews.vibeserved.com/mcp. Web clients sign in with OAuth (you click Allow once, a key named after the client appears on your dashboard); editors and scripts can use the URL with OAuth too, or send an API key in the Authorization header. Metering is identical to REST: lookup_app and get_reviews cost one credit per successful call, get_balance is free, failures are free.
| lookup_app | store, app_id, country. App metadata for one storefront. |
|---|---|
| get_reviews | store, app_id, country, sort, cursor. One page of up to 50 reviews plus next_cursor. |
| get_balance | Credits left and the rate limit for the key. |
ChatGPT
Custom connectors need Developer mode, which is on paid plans.
- Settings, then Connectors (or Apps), then Advanced, and turn on Developer mode.
- Back in Connectors choose Create. Name it appreviews, set the MCP server URL to
https://appreviews.vibeserved.com/mcp, authentication OAuth. - Create, then Connect. You land on this site, log in if needed, click Allow.
- In a chat, open the plus menu, enable the appreviews connector, and ask for an app's reviews.
Claude (web and desktop)
- Settings, then Connectors, then Add custom connector.
- Name appreviews, URL
https://appreviews.vibeserved.com/mcp. Leave the advanced OAuth fields empty; Claude discovers them. - Add, then Connect, log in here, click Allow.
Cursor
One-click install, then sign in. Cursor ignores API-key headers when OAuth discovery is on (same for any server that publishes /.well-known/oauth-*). Click Add to Cursor, then allow access — no key to paste. That matches ChatGPT, Claude and Grok.
Want a file instead?
{
"mcpServers": {
"appreviews": {
"url": "https://appreviews.vibeserved.com/mcp"
}
}
}
Claude Code can take a baked key — see below. Cursor cannot prefill one.
Claude Code
claude mcp add --transport http appreviews https://appreviews.vibeserved.com/mcp
# then inside Claude Code run /mcp and pick appreviews to sign in,
# or skip OAuth with a key:
claude mcp add --transport http appreviews https://appreviews.vibeserved.com/mcp \
--header "Authorization: Bearer ar_..."
Grok
- Open
grok.com/connectors, New connector, Custom. - Name appreviews, server URL
https://appreviews.vibeserved.com/mcp(the MCP URL, not the authorize URL), Continue. - If Grok shows "OAuth credentials required", fill the form below and leave Client secret empty.
- Save and connect, log in here, click Allow.
| Client ID | appreviews-grok |
|---|---|
| Client secret | leave empty |
| Authorization endpoint | https://appreviews.vibeserved.com/oauth/authorize |
| Token endpoint | https://appreviews.vibeserved.com/oauth/token |
| Scopes | mcp |
| Token auth method | none (PKCE) |
Any other client
Point it at https://appreviews.vibeserved.com/mcp. Clients that speak MCP authorization discover everything from https://appreviews.vibeserved.com/.well-known/oauth-protected-resource and https://appreviews.vibeserved.com/.well-known/oauth-authorization-server: authorization code with PKCE S256, dynamic client registration at /oauth/register, public clients only, refresh tokens, access tokens good for an hour. Clients without OAuth send Authorization: Bearer ar_... or X-Api-Key instead. Each OAuth connection is an API key named after the client on your dashboard; revoke it there to disconnect.
The server implements the stateless 2026-07-28 revision and the 2025 revisions that begin with initialize; there are no sessions and no server-initiated streams. Tool failures come back as results with isError: true so the model can read the reason and recover, and they never cost a credit.
Talk to it by hand
$ curl https://appreviews.vibeserved.com/mcp -H "Authorization: Bearer $KEY" \
-H "MCP-Protocol-Version: 2026-07-28" -H "Mcp-Method: tools/call" -H "Mcp-Name: lookup_app" \
-H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"lookup_app","arguments":{"store":"apple","app_id":"310633997"},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28"}}}'
Status
GET https://appreviews.vibeserved.com/status is free and unauthenticated. Every 15 minutes we call both stores through the real code path; the response says whether the last probe of each store succeeded and when. If a store is failing, its calls return a free 503 upstream_unavailable until it is fixed.
Cursors
next_cursoris opaque and signed. Pass it back unchanged with the samestore,app_id,countryandsort; anything else is400.next_cursor: nullmeans the end. The App Store publishes at most 500 reviews per storefront (10 pages).- Cursors are not stable forever; upstream ordering shifts as new reviews land. Walk a listing in one sitting.
Errors
Every error is { "error": { "code": "...", "message": "..." } } and none of them cost a credit.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Bad store, id, country, sort or cursor |
| 401 | unauthorized | Missing, unknown or revoked key |
| 402 | insufficient_credits | Balance is 0; buy a pack on pricing |
| 404 | not_found | No app with that id in that storefront |
| 429 | rate_limited | Over 60 requests this minute; see Retry-After |
| 503 | upstream_unavailable | Apple or Google did not answer properly; retry later |