{
  "openapi": "3.0.1",
  "info": {
    "title": "Full Scraper Reviews App Store & Google Play",
    "description": "Reviews, metadata and keyword rankings for iOS and Android apps, in one common schema, across every storefront. Full review sweep that does not lose reviews on the way. No login, no cookies.",
    "version": "0.1",
    "x-build-id": "hvoPGvZiAWj8bJLUG"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/alexmorain~app-store-play-store-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-alexmorain-app-store-play-store-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/alexmorain~app-store-play-store-scraper/runs": {
      "post": {
        "operationId": "runs-sync-alexmorain-app-store-play-store-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/alexmorain~app-store-play-store-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-alexmorain-app-store-play-store-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",
            "type": "array",
            "description": "The apps to collect, one per line. Four accepted forms, freely mixed in the same list:<br>• an App Store numeric id: <code>310633997</code><br>• a Google Play package name: <code>com.whatsapp</code><br>• a full App Store URL: <code>https://apps.apple.com/us/app/id324684580</code><br>• a full Google Play URL: <code>https://play.google.com/store/apps/details?id=com.spotify.music</code><br><br><b>Where to find them:</b> the numeric id is at the end of any App Store URL, right after <code>id</code>. The package name is the <code>id=</code> parameter of any Google Play URL. Pasting the URL straight from your browser always works.<br><br>Anything the Actor cannot read is skipped with an explanation in the log, and the rest of the list still runs. Leave this empty only if you run in keyword-ranking mode.",
            "items": {
              "type": "string"
            }
          },
          "countries": {
            "title": "Storefronts",
            "type": "array",
            "description": "ISO 3166-1 country codes of the app stores to sweep: <code>us</code>, <code>fr</code>, <code>gb</code>, <code>de</code>, <code>jp</code>... Case does not matter.<br><br><b>Why it matters:</b> both stores are partitioned by country. A US review never appears in the French store, and an app can be ranked 3rd in one country and absent from another. One app on three storefronts means three sweeps, three sets of reviews, and three billable units.<br><br>Start with one storefront, add more once you have seen the shape of the data. Leave empty for the US storefront only.",
            "items": {
              "type": "string"
            }
          },
          "include": {
            "title": "What to collect",
            "type": "array",
            "description": "Tick each item independently.<br>• <b>Reviews</b>: every review the store serves, swept to the real end of the feed.<br>• <b>App metadata</b>: the store profile of the app, name, developer, average rating, rating count, version, genre, price, installs, description and icon.<br>• <b>Keyword rankings</b>: for each search term you give below, the ranked list of apps in that storefront. App Store only in this version.<br><br>Reviews and metadata are covered by the same single unit per app and storefront, so leaving both ticked is strictly the best value. Rankings are billed separately, per keyword and storefront.",
            "items": {
              "type": "string",
              "enum": [
                "reviews",
                "metadata",
                "rankings"
              ],
              "enumTitles": [
                "Reviews",
                "App metadata",
                "Keyword rankings"
              ]
            },
            "default": [
              "reviews",
              "metadata"
            ]
          },
          "mode": {
            "title": "Mode",
            "enum": [
              "all",
              "new-only"
            ],
            "type": "string",
            "description": "<b>All reviews</b> returns everything the store serves, on every run. That is what you want the first time, and for any one-off analysis.<br><br><b>New reviews only</b> keeps a persistent registry per app and storefront and returns only reviews it has never seen. Schedule it daily and you get a clean feed of new feedback instead of the same corpus again. The first run in this mode still returns the whole backlog, since nothing has been seen yet.",
            "default": "all"
          },
          "maxReviewsPerApp": {
            "title": "Max reviews per app and storefront",
            "minimum": 1,
            "type": "integer",
            "description": "Upper bound on reviews collected for one app on one storefront.<br><br><b>It does not change the price</b>, which is per app and storefront whatever the volume, so raise it freely when you want depth. Use it to control run duration instead: <code>100</code> gives you the current mood of an app in seconds, <code>500</code> is a solid sample, several thousand walks the feed to its real end.<br><br>The sweep never stops on an apparently empty page, which is how it gets past the App Store quirk that makes RSS-based scrapers return nothing at all.",
            "default": 500
          },
          "keywords": {
            "title": "Keywords",
            "type": "array",
            "description": "Search terms to track, one per line: <code>music streaming</code>, <code>meditation</code>, <code>expense report</code>. For each term and each storefront the Actor records the ranked list of apps, position by position. This is App Store SEO tracking.<br><br>Only used when <b>Keyword rankings</b> is ticked above, so leave it empty otherwise. It works with no app in the list at all: keywords alone is a perfectly valid run.",
            "items": {
              "type": "string"
            }
          },
          "rankingDepth": {
            "title": "Ranking depth",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "How many ranked apps to record per keyword and storefront. <code>10</code> answers \"who owns the top of this search\", <code>50</code> covers the realistic discovery zone, <code>200</code> is the deepest the store serves. The price is per keyword and storefront, not per position, so depth is free.",
            "default": 50
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "<b>Leave this off.</b> Both stores are read over plain HTTP through their public endpoints and need no proxy in normal use; enabling one only makes the run slower. Turn it on if you sweep hundreds of app-storefront pairs in a single run and start seeing rate limits in the log.",
            "default": {
              "useApifyProxy": false
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}