{
  "openapi": "3.0.1",
  "info": {
    "title": "App Store & Google Play Reviews Scraper API | iOS + Android",
    "description": "Scrape App Store and Google Play reviews in one run: ratings, text, dates, versions, developer replies, sentiment and topics, app details and top charts. One stable schema, CSV/Excel-ready. Multi-country, star/date/keyword filters, new-reviews-only monitoring. From $0.10 per 1,000 reviews.",
    "version": "1.0",
    "x-build-id": "SmDqUeAiioaG6jNox"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/aaronoptimus~app-store-reviews-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-aaronoptimus-app-store-reviews-scraper",
        "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/aaronoptimus~app-store-reviews-scraper/runs": {
      "post": {
        "operationId": "runs-sync-aaronoptimus-app-store-reviews-scraper",
        "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/aaronoptimus~app-store-reviews-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-aaronoptimus-app-store-reviews-scraper",
        "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",
        "properties": {
          "apps": {
            "title": "Apps (URLs, Apple ids or Android package names)",
            "type": "array",
            "description": "One app per line: an App Store URL (https://apps.apple.com/us/app/…/id324684580), a Google Play URL (https://play.google.com/store/apps/details?id=com.spotify.music), a numeric Apple app id (324684580) or an Android package name (com.spotify.music). Each app is fetched for every country you list.",
            "items": {
              "type": "string"
            }
          },
          "searchTerms": {
            "title": "Search terms (find apps by name)",
            "type": "array",
            "description": "Optional. App names or keywords to search in the selected store(s). The top \"Max results per search / chart\" apps of each search are fetched like the apps above (details + reviews). Turn on \"Include search results\" to also get the search result list itself.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "stores": {
            "title": "Stores",
            "enum": [
              "both",
              "ios",
              "android"
            ],
            "type": "string",
            "description": "Which store(s) to search and accept apps from. With \"both\", URLs and ids decide the store per app; search terms and top charts are run in both stores.",
            "default": "both"
          },
          "countries": {
            "title": "Countries",
            "type": "string",
            "description": "Store country code(s), e.g. us or us, gb, de. Every app is fetched for every country (details, reviews and charts differ by country). App Store sweep presets: top5, top10, top25, top50 or all (every App Store storefront) fetch App Store apps in those storefronts, de-duplicate reviews across them and report reviews per country; Google Play apps, searches and charts use the codes you list (or us). Apple shows at most 500 recent reviews per app per country, so more countries means more App Store reviews.",
            "default": "us"
          },
          "languages": {
            "title": "Languages",
            "type": "string",
            "description": "Language code(s) for app details and Google Play reviews, e.g. en or en, de. Google Play returns a different set of reviews per language, so each listed language is fetched; Apple reviews are per country only (the first language is used for details).",
            "default": "en"
          },
          "includeAppDetails": {
            "title": "App details",
            "type": "boolean",
            "description": "One item per app × country with title, developer, rating, rating count and histogram, price, installs (Android), version, release notes, category, content rating, size, minimum OS, data safety summary (Google Play) and more. Charged per app detail.",
            "default": true
          },
          "includeReviews": {
            "title": "Reviews",
            "type": "boolean",
            "description": "One item per review: reviewer name as displayed, rating, title, text, date, app version, helpful votes, developer reply, a link, plus free sentiment and topic tags. Charged per review delivered.",
            "default": true
          },
          "maxReviewsPerApp": {
            "title": "Max reviews per app",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "Per app, country and language. Google Play is paginated, so thousands are possible. App Store: Apple shows at most the 500 most recent reviews per app per country (use more countries or a sweep preset for more). You only pay for reviews delivered. Free-plan accounts get at most 50.",
            "default": 200
          },
          "reviewSort": {
            "title": "Review order",
            "enum": [
              "newest",
              "rating",
              "helpfulness"
            ],
            "type": "string",
            "description": "Newest first, highest rating first, or most helpful first. Apple's feed has no rating order, so for App Store apps the most recent reviews are fetched and sorted by rating. Reviews taken from the App Store web page are sorted the same way.",
            "default": "newest"
          },
          "reviewsNewerThan": {
            "title": "Only reviews newer than",
            "type": "string",
            "description": "Optional. A date like 2026-01-31, or a relative period like \"30 days\" or \"6 months\". With \"Newest first\", paging stops as soon as older reviews are reached, so this also keeps runs short. Older reviews are not delivered or charged."
          },
          "minRating": {
            "title": "Minimum rating",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Only keep reviews with at least this many stars (1–5). Reviews outside the rating range are not delivered or charged.",
            "default": 1
          },
          "maxRating": {
            "title": "Maximum rating",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Only keep reviews with at most this many stars (1–5). Set 1–2 to get complaints only.",
            "default": 5
          },
          "includeKeywords": {
            "title": "Only reviews containing",
            "type": "array",
            "description": "Optional. Keep only reviews whose title or text contains at least one of these words or phrases (case- and accent-insensitive), e.g. crash, refund, dark mode. Other reviews are not delivered or charged.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "Skip reviews containing",
            "type": "array",
            "description": "Optional. Drop reviews whose title or text contains any of these words or phrases. Dropped reviews are free.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "developerReplyFilter": {
            "title": "Developer reply",
            "enum": [
              "any",
              "withReply",
              "withoutReply"
            ],
            "type": "string",
            "description": "All reviews, only reviews the developer answered, or only unanswered reviews (handy for support teams). Reviews left out are free.",
            "default": "any"
          },
          "addSentimentAndTopics": {
            "title": "Sentiment & topics (free)",
            "type": "boolean",
            "description": "Tag every review with sentiment (positive / neutral / negative, from the stars plus a small word list) and topics (crash-bug, login-account, ads, pricing-subscription, performance, ui-ux, support, feature-request, privacy). Computed locally with keyword dictionaries for English, Spanish, German, French and Portuguese: no AI service, no extra cost.",
            "default": true
          },
          "includeSummary": {
            "title": "Per-app summary (free)",
            "type": "boolean",
            "description": "One free item per app × country: average rating of the reviews fetched, counts by star, average rating by app version, and the most frequent words in 1–2 star reviews (stop words removed).",
            "default": true
          },
          "includeComparison": {
            "title": "Competitor comparison (free)",
            "type": "boolean",
            "description": "When the run covers 2 or more apps, add one free comparison item: average rating, % of 1–2★ reviews, top negative topics, developer reply rate, median reply time, and rating by week and by app version, side by side.",
            "default": true
          },
          "onlyNewReviews": {
            "title": "Only new reviews (monitoring)",
            "type": "boolean",
            "description": "Deliver and charge only reviews that earlier runs haven't delivered yet, per store × app × country. The first run is the baseline (delivers what it fetches); schedule the task daily or hourly and connect a webhook, Slack or email to get new reviews only. Works best with \"Newest first\".",
            "default": false
          },
          "monitorKey": {
            "title": "Monitor name",
            "type": "string",
            "description": "Optional. Keeps independent monitors apart (e.g. one per team or task). Runs with the same name share what was already delivered. Stored in your account's key-value store \"app-reviews-monitor\"."
          },
          "includeSearchResults": {
            "title": "Include search results as items",
            "type": "boolean",
            "description": "Also deliver the search result list for each search term (rank, app id, title, developer, rating, price). Charged per listing entry. Off = search terms are only used to find apps.",
            "default": false
          },
          "maxSearchResults": {
            "title": "Max results per search / chart",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "How many apps to take from each search (these apps are then fetched) and how many entries to deliver per top chart.",
            "default": 20
          },
          "topCharts": {
            "title": "Top charts",
            "type": "array",
            "description": "Optional. One chart per line as collection:category. Google Play: topselling_free, topselling_paid or topgrossing, with an optional category like GAME, GAME_PUZZLE, FINANCE, PRODUCTIVITY (e.g. topselling_free:GAME). App Store: topfreeapplications, toppaidapplications, topgrossingapplications, newapplications, newfreeapplications or newpaidapplications with an optional numeric genre id (e.g. topfreeapplications:6014 for Games). Fetched for every country; charged per entry.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "outputFormat": {
            "title": "Output format",
            "enum": [
              "items",
              "rows"
            ],
            "type": "string",
            "description": "Items: one JSON record per review / app / listing entry / summary, with the same fields for both stores (best for API / code). Rows: one flat row per record with identical columns everywhere (best for CSV, Excel, Google Sheets, BI tools).",
            "default": "items"
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Off by default: both stores accept moderate datacenter traffic. Turn on Apify Proxy if you see many retries or run very large lists; sessions and IPs then rotate automatically on every block.",
            "default": {
              "useApifyProxy": false
            }
          },
          "maxConcurrency": {
            "title": "Parallel sessions",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many apps / searches to fetch at the same time, each with its own session. Higher is faster for big lists; lower is gentler on rate limits.",
            "default": 4
          },
          "maxRetries": {
            "title": "Max retries per request",
            "minimum": 0,
            "maximum": 15,
            "type": "integer",
            "description": "How many times to retry with a fresh session (and IP, with a proxy) when a store returns 429 / 403 / 5xx or a network error.",
            "default": 6
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}