appreviews
Reference

API

Base URL https://appreviews.vibeserved.com. Every response is JSON. Times are ISO 8601 in UTC. Two stores, three endpoints, one schema.

quick start
# 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, 429 and 503 responses never charge.
  • Upstream responses are cached for 10 minutes. A cache hit is still one request and still one credit.
  • Every metered 200 carries X-Credits-Remaining. /v1/me is free.
  • 60 requests per minute per key. Over that you get 429 with Retry-After in seconds.
  • At zero credits you get 402 until you buy a pack. Signup grants 300.
GET/v1/apps/{store}/{app_id}

App metadata for one storefront.

storeapple or google
app_idApple numeric track id (310633997) or Play package name (com.whatsapp)
countryTwo-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".

GET/v1/apps/{store}/{app_id}/reviews

Up to 50 reviews per page, newest first by default.

sortrecent (default), helpful, rating. The App Store has no rating sort and answers 400.
countryTwo-letter storefront, default us
cursorThe 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.

GET/v1/mefree

Balance 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
  }
}
GET/v1/demofree

Public 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
POST/mcp

MCP 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_appstore, app_id, country. App metadata for one storefront.
get_reviewsstore, app_id, country, sort, cursor. One page of up to 50 reviews plus next_cursor.
get_balanceCredits left and the rate limit for the key.

ChatGPT

Custom connectors need Developer mode, which is on paid plans.

  1. Settings, then Connectors (or Apps), then Advanced, and turn on Developer mode.
  2. Back in Connectors choose Create. Name it appreviews, set the MCP server URL to https://appreviews.vibeserved.com/mcp, authentication OAuth.
  3. Create, then Connect. You land on this site, log in if needed, click Allow.
  4. In a chat, open the plus menu, enable the appreviews connector, and ask for an app's reviews.

Claude (web and desktop)

  1. Settings, then Connectors, then Add custom connector.
  2. Name appreviews, URL https://appreviews.vibeserved.com/mcp. Leave the advanced OAuth fields empty; Claude discovers them.
  3. 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?

.cursor/mcp.json
{
  "mcpServers": {
    "appreviews": {
      "url": "https://appreviews.vibeserved.com/mcp"
    }
  }
}

Claude Code can take a baked key — see below. Cursor cannot prefill one.

Claude Code

terminal
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

  1. Open grok.com/connectors, New connector, Custom.
  2. Name appreviews, server URL https://appreviews.vibeserved.com/mcp (the MCP URL, not the authorize URL), Continue.
  3. If Grok shows "OAuth credentials required", fill the form below and leave Client secret empty.
  4. Save and connect, log in here, click Allow.
Client IDappreviews-grok
Client secretleave empty
Authorization endpointhttps://appreviews.vibeserved.com/oauth/authorize
Token endpointhttps://appreviews.vibeserved.com/oauth/token
Scopesmcp
Token auth methodnone (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_cursor is opaque and signed. Pass it back unchanged with the same store, app_id, country and sort; anything else is 400.
  • next_cursor: null means 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.

StatusCodeMeaning
400invalid_requestBad store, id, country, sort or cursor
401unauthorizedMissing, unknown or revoked key
402insufficient_creditsBalance is 0; buy a pack on pricing
404not_foundNo app with that id in that storefront
429rate_limitedOver 60 requests this minute; see Retry-After
503upstream_unavailableApple or Google did not answer properly; retry later