---
title: "App Store Reviews API: Apple App Store Data as JSON"
description: "Call GET /v1/apple-app-store/product-reviews with an app's product_id to get ratings, titles and review text as JSON. Parameters, a real response, 1 credit."
url: https://perceptlayer.com/blog/app-store-reviews-api
---

[Blog](https://perceptlayer.com/blog) / [API guides](https://perceptlayer.com/blog/category/api-guides)

# App Store Reviews API: Apple App Store Data as JSON

31 Aug 2026 Perceptlayer 8 min read

To get App Store reviews for any app as JSON, call `GET /v1/apple-app-store/product-reviews` with the app's `product_id` and `store=apps`. The response lists each review with its rating, title, text and date, plus a pagination block for the next page. A successful call costs 1 credit, and a failed call costs nothing.

## Key takeaways

-   Apple's App Store Connect API is the tool developers use to manage their own apps. For competitor or market research, work from a public app ID instead.
-   `GET /v1/apple-app-store/product-reviews` takes a `product_id`, a `store` and a `country`, and returns `reviews` plus a `reviews_pagination` block.
-   Each recorded review carries `id`, `title`, `rating`, `text`, `date` and `is_edited`.
-   Details and Charts use the same key and cost 1 credit per call each. Failed calls return `X-Credits-Used: 0`.
-   1,000 free credits arrive every month after you verify an email address, with no credit card.

## Why can't App Store Connect return reviews for other people's apps?

Apple's App Store Connect API is the tool developers use to manage their own apps. It has a Customer Reviews resource ( [Apple Developer Documentation, Customer Reviews](https://developer.apple.com/documentation/appstoreconnectapi/customer-reviews)), but it's part of an API you sign in to as a team that publishes apps. We wouldn't plan on it for a competitor's reviews, and you should check Apple's documentation for what your own account can read.

That's the right tool when you're reading and answering feedback on your own app. If you're doing market research, competitor tracking or building a review dataset across many apps, you need a source that works from a public app ID. That's the gap this endpoint fills: it works from a public app ID, so you only need the ID. Apple's own API is the place for replies: its Customer Review Responses resource ( [Apple Developer Documentation, Customer Review Responses](https://developer.apple.com/documentation/appstoreconnectapi/customer-review-responses)) is the place to manage replies to reviews. This API doesn't publish replies.

## How do you find an app's product ID?

The `product_id` is the numeric ID in the app's App Store URL (the digits after `id`). If you only know the name, use the search endpoint. It takes one required parameter, `query`, and returns matching apps for the `store` and `country` you choose.

```bash
curl "https://api.perceptlayer.com/v1/apple-app-store/search?query=facebook&store=apps&country=us" \
  -H "X-API-Key: $API_KEY"
```

We don't have a recorded search response to show, so this article doesn't name the field that holds the ID. Run the call in the playground on the [Apple App Store API page](https://perceptlayer.com/apis/apple-app-store) and read the ID from the output. The numeric ID in the App Store URL is the more reliable route. The search call costs 1 credit. If you already have the ID from a URL, skip this step.

The `store` parameter accepts one of `apps`, `mac`, `books`, `audiobooks`, `movies`, `tv`, `music` or `podcasts`. For iPhone and iPad apps, use `apps`. The `country` parameter is a code of up to two characters, such as `us`.

## How do you request an app's reviews?

Send a GET request to `/v1/apple-app-store/product-reviews` with the `product_id`, `store` and, optionally, `num` to set how many reviews you want. No parameter is strictly required by the catalogue, but without an app ID there is nothing to look up.

```bash
curl "https://api.perceptlayer.com/v1/apple-app-store/product-reviews?product_id=324684580&store=apps&num=20" \
  -H "X-API-Key: $API_KEY"
```

Send the key in the `X-API-Key` header, as above. Where headers aren't possible, the `api_key` query parameter works too. See [authentication in the docs](https://docs.perceptlayer.com/authentication) for both forms. Keys start with `sk_live_`, and you can [get a free API key](https://perceptlayer.com/signup) in a minute.

### Which parameters does the endpoint take?

All parameters are optional in the catalogue. These are the ones you'll use for reviews.

| Parameter | Type | What it does |
| --- | --- | --- |
| `product_id` | string, up to 255 characters | The app's ID from its store URL |
| `id` | string, up to 255 characters | Listed in the catalogue alongside `product_id` |
| `store` | string | One of `apps`, `mac`, `books`, `audiobooks`, `movies`, `tv`, `music`, `podcasts` |
| `country` | string, up to 2 characters | The storefront country, such as `us` |
| `num` | integer | How many reviews to request |
| `offset` | integer | Where to start in the list of reviews |
| `next_page_token` | string, up to 100 characters | The token from the previous page, for the next one |
| `season_id` | string, up to 255 characters | Listed in the catalogue; not used in the request above |

The catalogue documents types and limits for these parameters and nothing more. It doesn't state defaults or page sizes, so set `num` explicitly if you depend on a number.

## What does the response look like?

The response has three parts: `search_parameters` echoing your request, a `reviews` array and a `reviews_pagination` block. This is a real, trimmed response for the request above. We've left out reviewer usernames and cut the text where it says `…`.

```json
{
  "search_parameters": {
    "product_id": "324684580",
    "store": "apps",
    "num": 20,
    "country": "us",
    "engine": "apple_app_store_product_reviews"
  },
  "reviews": [
    {
      "id": "11994640656",
      "title": "Favorite app ever",
      "rating": 5,
      "text": "I personally love this app. I have had it for over 4 years, and it’s been an app I use daily. If you are thinking about getting it, for sure get the Premium pla…",
      "date": "2024-11-26T17:10:59Z",
      "is_edited": false
    },
    …
  ],
  "reviews_pagination": {
    "offset": 0,
    "limit": 20,
    "next_offset": 20,
    "next_page_token": "20",
    "end_of_history": false
  }
}
```

Each review has an `id`, a `title`, a numeric `rating`, the review `text`, an ISO 8601 `date` and an `is_edited` flag. The raw response also carries an `author` field, which we removed from the excerpt. If you store reviews, decide whether you need it at all; ratings, text and dates are enough for most analysis.

The `…` at the end of each `text` value in the sample marks where we trimmed the excerpt.

## How do you page through all the reviews?

Use `reviews_pagination`. It gives you `next_offset`, `next_page_token` and an `end_of_history` flag. Pass the token back as `next_page_token` (or the offset as `offset`) to fetch the next page, and stop when `end_of_history` is `true`. Every page is a separate call, so every page costs 1 credit.

```python
import os
import requests

BASE = "https://api.perceptlayer.com/v1/apple-app-store/product-reviews"
HEADERS = {"X-API-Key": os.environ["API_KEY"]}

params = {"product_id": "324684580", "store": "apps", "num": 20, "country": "us"}
reviews = []

for _ in range(5):  # hard cap: at most 5 calls, 5 credits
    resp = requests.get(BASE, headers=HEADERS, params=params, timeout=30)
    resp.raise_for_status()
    body = resp.json()
    reviews.extend(body["reviews"])
    page = body["reviews_pagination"]
    if page["end_of_history"]:
        break
    params["next_page_token"] = page["next_page_token"]

print(len(reviews), "reviews")
```

The loop has a fixed cap so a large app can't run up your balance by accident.

### How do you turn the pages into a result?

Once `reviews` is filled, you can work with the `rating` and `date` fields from the recorded response without any more calls. This adds a count per star rating and the share of low ratings, then lists the one-star and two-star reviews from the last 90 days. `date` is an ISO 8601 string, so comparing it as text works.

```python
from collections import Counter
from datetime import datetime, timedelta, timezone

by_rating = Counter(r["rating"] for r in reviews)
for stars in sorted(by_rating, reverse=True):
    print(stars, "stars:", by_rating[stars])

low = sum(n for stars, n in by_rating.items() if stars <= 2)
print(f"{low / len(reviews):.0%} of {len(reviews)} reviews are 1 or 2 stars")

cutoff = (datetime.now(timezone.utc) - timedelta(days=90)).strftime("%Y-%m-%dT%H:%M:%SZ")
recent_low = [r for r in reviews if r["rating"] <= 2 and r["date"] >= cutoff]
for r in recent_low:
    print(r["date"][:10], r["rating"], r["title"])
```

The output is a rating breakdown and a list of recent complaints you can read, which is a usable first pass at what's going wrong in an app. The numbers describe only the pages you fetched, not every review the app has. If `reviews` is empty, the division fails, so check `end_of_history` and your parameters first. For retries, backoff and the lost-reply case, read [paginate a web data API in Python](https://perceptlayer.com/blog/paginate-web-data-api-python). Requests have no idempotency key, so a call whose reply was lost may have succeeded and been billed. [Retrying without paying twice](https://perceptlayer.com/blog/retry-web-api-calls-without-paying-twice) covers it.

## What do the Details and Charts endpoints add?

The same API also has `GET /v1/apple-app-store/details`, which takes the same parameters as reviews, and `GET /v1/apple-app-store/charts`, which takes `store`, `chart` ( `top-free`, `top-paid`, `top-grossing`, `most-played`, `top-subscriber` or `top-episodes`), `genre`, `country` and `limit`. We don't have a recorded response for either, so this article doesn't show their fields. Try them in the playgrounds on the [Charts](https://perceptlayer.com/apis/apple-app-store/charts) and [Details](https://perceptlayer.com/apis/apple-app-store/details) pages. Related endpoints include [Developer](https://perceptlayer.com/apis/apple-app-store/developer) (by `artist_id`) and [Apps Product](https://perceptlayer.com/apis/apple-app-store/apps-product).

## What does it cost?

Every endpoint on the Apple App Store API costs 1 credit per successful call. Failed calls cost nothing and return `X-Credits-Used: 0`. Successful responses carry `X-Credits-Used` and `X-Credits-Remaining`, so you can watch your balance in code. The [credits docs](https://docs.perceptlayer.com/credits) explain the accounting.

A worked example: one chart call, then reviews for each of its 10 apps with 5 pages each.

| Step | Calls | Credits |
| --- | --- | --- |
| Charts, `limit=10` | 1 | 1 |
| Reviews, 10 apps × 5 pages | 50 | 50 |
| Total | 51 | 51 |

51 credits sits inside the 1,000 free credits you get each month. At scale, credits come in prepaid packs:

| Pack | Credits | Requests a second included |
| --- | --- | --- |
| Starter | 10,000 | 5 |
| Build | 50,000 | 5 |
| Growth | 200,000 | 5 |
| Pro | 500,000 | 5 |
| Scale | 1,000,000 | 10 |
| Volume | 5,000,000 | 20 |

To pull 5 pages for each of 2,000 apps, that's 2,000 × 5 = 10,000 calls × 1 credit = 10,000 credits, which is exactly the Starter pack. Reviews for 10,000 apps at 5 pages each is 10,000 × 5 = 50,000 calls × 1 credit = 50,000 credits, the Build pack. Purchased credits last 12 months, and there's no subscription. See [pricing](https://perceptlayer.com/pricing) for what credits cost and for faster request rates.

## What can go wrong?

Errors return an HTTP status and a JSON body with `error.code`, `error.message` and `error.request_id`. The ones you'll meet most are `invalid_api_key` (401), `insufficient_credits` (402), `invalid_parameters` (422), `rate_limited` (429) and `temporarily_unavailable` (503). The service is prepaid. When the balance runs out you get a 402 and nothing further is debited, with no automatic top-up.

A 429 or 503 carries a `Retry-After` header with the seconds to wait, so honour it instead of retrying in a tight loop. The [errors docs](https://docs.perceptlayer.com/errors) list every code, and [rate limits](https://docs.perceptlayer.com/rate-limits) explain the 429 behaviour.

Data is collected from publicly available sources and returned as found at the time of the call. Reviews can change after you fetch them, so store the `date` and the time you fetched them.

If you're building an agent rather than a pipeline, the same key works over MCP. See [AI agents (MCP)](https://docs.perceptlayer.com/ai-agents) and [MCP server for web scraping](https://perceptlayer.com/blog/mcp-server-for-web-scraping). To compare iOS with Android, the [Google Play Store API guide](https://perceptlayer.com/blog/google-play-store-api) covers the same job on the other store. For a comparable reviews walkthrough on another site, see the [Trustpilot reviews API guide](https://perceptlayer.com/blog/trustpilot-reviews-api) or the [Google Maps reviews API guide](https://perceptlayer.com/blog/google-maps-reviews-api-parameters). More pull-by-source guides are in the [API guides category](https://perceptlayer.com/blog/category/api-guides).

Next step: [get a free API key](https://perceptlayer.com/signup), then run the `product-reviews` call above in the playground on the [Apple App Store API page](https://perceptlayer.com/apis/apple-app-store).

## APIs in this post

-   [Apple App Store **1 credit per call** · 13 endpoints](https://perceptlayer.com/apis/apple-app-store)

## Frequently asked questions

### Can I get reviews for an app I don't own?

Yes, this endpoint takes a public `product_id`, so ownership isn't required. App Store Connect also has a [Customer Reviews](https://developer.apple.com/documentation/appstoreconnectapi/customer-reviews) resource, but it sits inside an API for managing your own apps, so we'd use it for your own apps only. You can't post replies through Perceptlayer, though. Apple's [Customer Review Responses](https://developer.apple.com/documentation/appstoreconnectapi/customer-review-responses) resource is the place for that.

### How much does it cost to pull reviews for one app?

Each successful call costs 1 credit and returns one page of reviews, so cost equals the number of pages you fetch. Five pages is 5 credits. Calls that fail cost nothing and return `X-Credits-Used: 0`. The free tier of 1,000 credits per month covers 1,000 pages with no credit card.

### Can I get reviews from a specific country?

Use the `country` parameter, a code of up to two characters such as `us`. The recorded request above returned `"country": "us"` in `search_parameters`. Run the call once per country you care about; each is a separate call and costs 1 credit.

### How do I get the next page of reviews?

Read `reviews_pagination` in the response. Pass its `next_page_token` as `next_page_token` (or `next_offset` as `offset`) in your next request. Keep going until `end_of_history` is `true`. Each page is billed as its own call, so cap your loop to control spend.

### Does this return personal data?

Reviews can include author details and free text written by individuals. Treat them as personal data in your own system: keep only the fields you need, and don't use scraped reviews to contact people. Your lawful basis and retention rules are your responsibility.

app store reviews apple mobile apps app data

## More from the blog

1.  [API guides](https://perceptlayer.com/blog/category/api-guides) 2 Oct 2026 Perceptlayer 6 min read
    
    ## [AliExpress Product API: Search, Reviews and Shipping](https://perceptlayer.com/blog/aliexpress-api-product-search-reviews)
    
    Chain AliExpress search, product, product-reviews and product-shipping, with every required parameter, at 1 credit per call, and cost a 100-product review pull.
    
2.  [API guides](https://perceptlayer.com/blog/category/api-guides) 25 Aug 2026 Perceptlayer 8 min read
    
    ## [Booking.com Hotel Prices API: Search, Rooms and Reviews](https://perceptlayer.com/blog/booking-com-hotel-prices-api)
    
    Eleven Booking.com endpoints as JSON: search, prices, rooms and reviews, with parameters and a 1,000-hotel price check costed in credits.
    
3.  [API guides](https://perceptlayer.com/blog/category/api-guides) 25 Aug 2026 Perceptlayer 8 min read
    
    ## [Google Hotels API: Hotel Prices for Your Dates as JSON](https://perceptlayer.com/blog/google-hotels-api)
    
    One GET to /v1/google-hotels/search returns Paris hotels with nightly rate, total rate and rating for your dates as JSON. Parameters, a response and cost.
