# App Store Reviews Scraper with Sentiment (`datawharf/app-store-reviews-sentiment`) Actor

Scrape App Store reviews with a built-in positive, neutral, or negative sentiment tag. Export review text, star ratings, versions, and dates to CSV, Excel, or JSON. Pay per review, no subscription. A clean App Store reviews scraper for sentiment analysis and release monitoring.

- **URL**: https://apify.com/datawharf/app-store-reviews-sentiment.md
- **Developed by:** [Brad Holder](https://apify.com/datawharf) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.20 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## App Store Reviews and Sentiment

Pull customer reviews for any Apple App Store app, each one already tagged with its sentiment, and get them back as clean, spreadsheet-ready rows. This tool runs on Apple's public customer-reviews feed, so it is fast and reliable, and needs no API key, no login, and no proxies. Unlike raw review scrapers, every review comes with a positive, neutral, or negative label worked out from its star rating, so you can start analyzing straight away instead of processing the data first. It is a pay-per-review App Store reviews scraper with built-in sentiment, made for sentiment analysis, release monitoring, and voice-of-customer research.

- Scrape App Store reviews for any app
- Get positive, neutral, or negative sentiment per review
- Track review sentiment after an app release
- Pull reviews by country and app version
- Export App Store reviews to CSV, Excel, or JSON

Because it uses an official public feed rather than fragile page scraping, there is nothing to break when a web page changes, which makes it dependable for scheduled monitoring.

### What it does

You give it one or more app IDs and a storefront, and it returns the app's reviews with the full text, title, star rating, a sentiment tag, the app version, reviewer name, helpful-vote counts, and the date. Results export to CSV, Excel, or JSON like any Apify dataset.

### Who it is for

- App developers and product teams who want to read and categorize their users' feedback without building a pipeline first.
- Support and community teams watching for negative reviews after a release so they can respond quickly.
- Marketers and ASO specialists mining review language for the words users actually use.
- Analysts and data scientists who want labelled review text for sentiment models or dashboards.

### Use cases

1. Release health check. After you ship an update, pull the newest reviews and sort by sentiment to see at a glance whether the release landed well or triggered complaints, with the app version on every row.
2. Competitor listening. Pull reviews for a set of competitor apps in one run and read their negative reviews to find the gaps and frustrations you can win on.
3. Scheduled negative-review alerts. Run it daily on your own app filtered to the newest reviews, and route the negative ones to your team so nothing slips through.
4. Voice-of-customer research. Collect hundreds of reviews across countries to understand how sentiment and requests differ by market.

### Input

| Field | Type | Description |
| --- | --- | --- |
| appIds | list of text | Apple app IDs to pull reviews for. Required. |
| country | text | Two-letter storefront code (us, ca, gb, de). Default us. |
| maxReviews | number | How many reviews per app (1 to 500). Default 200. |
| sort | choice | Most recent or most helpful. Default most recent. |

#### Example input

```json
{
  "appIds": ["389801252", "835599320"],
  "country": "us",
  "maxReviews": 200,
  "sort": "mostrecent"
}
````

### Output

One row per review. Fields: appName, appId, country, score (stars), sentiment (positive, neutral, or negative), title, text, version, userName, voteSum, voteCount, date, reviewUrl, reviewId, scrapedAt.

#### Example row

```json
{
  "appName": "Instagram",
  "appId": "389801252",
  "country": "US",
  "score": 2,
  "sentiment": "negative",
  "title": "Too many ads lately",
  "text": "The app is fine but the number of ads in my feed has gotten out of hand.",
  "version": "421.0.0",
  "userName": "photofan_2026",
  "voteSum": 4,
  "voteCount": 5,
  "date": "2026-07-14T09:20:00-07:00",
  "reviewUrl": "https://itunes.apple.com/us/review?id=389801252",
  "reviewId": "10954854441",
  "scrapedAt": "2026-07-16T12:00:00.000Z"
}
```

### About the sentiment tag

The sentiment label is worked out directly from the star rating: 4 or 5 stars is positive, 3 is neutral, and 1 or 2 is negative. This is transparent and predictable, and it means there is no external AI service in the loop to add cost or break. The full review text is always included, so if you want deeper analysis you can run your own model on top.

### Pricing

This tool uses pay per event pricing. You pay a small fee per review row returned, and nothing for apps that have no reviews. There is no monthly subscription. Pulling 500 reviews for one app costs about ten cents. Because each review arrives already labelled by sentiment, you save the processing step other scrapers leave to you.

### How it works

For each app the tool reads Apple's public customer-reviews feed for your chosen storefront, paging through results up to your limit. Apple's feed returns up to 500 reviews per country per app, so for wider coverage you can run the same app across several countries. A short delay runs between pages to stay within Apple's public rate limits.

### Frequently asked questions

#### Do I need an Apple developer account or API key?

No. The customer-reviews feed is public. This tool needs no key, no login, and no cookies.

#### How do I find an app's ID?

Open the app's App Store page. The ID is the number right after /id in the address, for example apps.apple.com/us/app/instagram/id389801252 has the ID 389801252.

#### Why can I only get 500 reviews per app?

Apple's public feed returns a maximum of 500 reviews per country per app. To gather more, run the same app across several storefronts, since reviews are country specific.

#### How is the sentiment decided?

From the star rating: 4 to 5 is positive, 3 is neutral, 1 to 2 is negative. It is simple and predictable, and the full text is included so you can analyze further yourself.

#### Can I pull reviews for several apps at once?

Yes. Put multiple app IDs in the list and each app's reviews come back in the same run, with the app name and ID on every row so you can tell them apart.

#### Can I monitor reviews over time?

Yes. Save your input as a task and use Apify Schedules to run it daily. Each run stores a fresh dataset, so you build a history you can chart or alert on.

### Related tools by DataWharf

- [App Store ASO Keyword Tool](https://apify.com/datawharf/app-store-aso-keyword-tool) - track App Store keyword rankings, difficulty, and where your app ranks.
- [App Store Keyword Search](https://apify.com/datawharf/app-store-keyword-search) - search the App Store by keyword and export structured app data.

# Actor input Schema

## `appIds` (type: `array`):

Apple app IDs to pull reviews for. The app ID is the number after /id in an App Store URL, for example 389801252 for Instagram.

## `country` (type: `string`):

Two-letter App Store region code, for example us, ca, gb, or de. Reviews are specific to each country's store.

## `maxReviews` (type: `integer`):

How many reviews to pull per app (1 to 500). Apple's public feed caps at 500 per country.

## `sort` (type: `string`):

Which reviews to fetch first.

## Actor input object example

```json
{
  "appIds": [
    "389801252",
    "835599320"
  ],
  "country": "us",
  "maxReviews": 200,
  "sort": "mostrecent"
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "appIds": [
        "389801252"
    ],
    "sort": "mostrecent"
};

// Run the Actor and wait for it to finish
const run = await client.actor("datawharf/app-store-reviews-sentiment").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "appIds": ["389801252"],
    "sort": "mostrecent",
}

# Run the Actor and wait for it to finish
run = client.actor("datawharf/app-store-reviews-sentiment").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "appIds": [
    "389801252"
  ],
  "sort": "mostrecent"
}' |
apify call datawharf/app-store-reviews-sentiment --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=datawharf/app-store-reviews-sentiment",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "App Store Reviews Scraper with Sentiment",
        "description": "Scrape App Store reviews with a built-in positive, neutral, or negative sentiment tag. Export review text, star ratings, versions, and dates to CSV, Excel, or JSON. Pay per review, no subscription. A clean App Store reviews scraper for sentiment analysis and release monitoring.",
        "version": "0.1",
        "x-build-id": "j7EtxKyBjKZTYnAMu"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/datawharf~app-store-reviews-sentiment/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-datawharf-app-store-reviews-sentiment",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/datawharf~app-store-reviews-sentiment/runs": {
            "post": {
                "operationId": "runs-sync-datawharf-app-store-reviews-sentiment",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/datawharf~app-store-reviews-sentiment/run-sync": {
            "post": {
                "operationId": "run-sync-datawharf-app-store-reviews-sentiment",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "appIds"
                ],
                "properties": {
                    "appIds": {
                        "title": "App IDs",
                        "type": "array",
                        "description": "Apple app IDs to pull reviews for. The app ID is the number after /id in an App Store URL, for example 389801252 for Instagram.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "country": {
                        "title": "Storefront (country)",
                        "type": "string",
                        "description": "Two-letter App Store region code, for example us, ca, gb, or de. Reviews are specific to each country's store.",
                        "default": "us"
                    },
                    "maxReviews": {
                        "title": "Max reviews per app",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "How many reviews to pull per app (1 to 500). Apple's public feed caps at 500 per country.",
                        "default": 200
                    },
                    "sort": {
                        "title": "Sort order",
                        "enum": [
                            "mostrecent",
                            "mosthelpful"
                        ],
                        "type": "string",
                        "description": "Which reviews to fetch first.",
                        "default": "mostrecent"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
