{
  "openapi": "3.0.1",
  "info": {
    "title": "Apple App Store Reviews Scraper - iOS App Reviews & Ratings",
    "description": "App Store scraper for iOS app reviews and app details from Apple's official public feeds, many countries. Star, date and keyword filters, new-review alerts, optional AI summary. $0.10/1,000 reviews.",
    "version": "0.1",
    "x-build-id": "94PB8196pnYupeDeo"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/tidytools~apple-app-store-reviews/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-tidytools-apple-app-store-reviews",
        "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/tidytools~apple-app-store-reviews/runs": {
      "post": {
        "operationId": "runs-sync-tidytools-apple-app-store-reviews",
        "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/tidytools~apple-app-store-reviews/run-sync": {
      "post": {
        "operationId": "run-sync-tidytools-apple-app-store-reviews",
        "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 (links, ids, bundle ids or search terms)",
            "type": "array",
            "description": "Main input: the run needs at least one line here. One app per line, any mix of: an App Store link (https://apps.apple.com/us/app/instagram/id389801252), a numeric app id (389801252 or id389801252), a bundle id (com.burbn.instagram) or a search term (e.g. habit tracker — the top result, or the top N with \"Search results per term\"). Prefix with id:, bundle: or search: to force one kind. Invalid lines and apps that are not found get an error row and are not charged.",
            "items": {
              "type": "string"
            }
          },
          "countries": {
            "title": "Countries (App Store storefronts)",
            "type": "array",
            "description": "Two-letter country codes, e.g. us, gb, de, fr, jp, br, in. Reviews and app details are read from each country's store (Apple keeps reviews per country). Search terms are searched in the first country. Default: us.",
            "default": [
              "us"
            ],
            "items": {
              "type": "string"
            }
          },
          "mode": {
            "title": "What to return",
            "enum": [
              "both",
              "reviews",
              "details"
            ],
            "type": "string",
            "description": "App details are one row per app and country; reviews are one row per review. Values: both = App details + reviews; reviews = Reviews only; details = App details only (name, developer, price, rating, rating count, version, release notes, size, languages, screenshots…).",
            "default": "both"
          },
          "maxReviewsPerCountry": {
            "title": "Max reviews per app and country",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Apple's public reviews feed serves at most 500 reviews per app and country (10 pages of 50, most recent or most helpful first). Counted after your filters.",
            "default": 500
          },
          "maxReviews": {
            "title": "Max reviews (whole run)",
            "minimum": 1,
            "maximum": 1000000,
            "type": "integer",
            "description": "Stop after this many reviews in total. You pay only for reviews returned: 10,000 reviews cost at most $1 on the Free plan.",
            "default": 10000
          },
          "sortBy": {
            "title": "Sort reviews by",
            "enum": [
              "mostRecent",
              "mostHelpful",
              "lowestRating",
              "highestRating",
              "oldest"
            ],
            "type": "string",
            "description": "Which reviews Apple serves (newest or most helpful) and the order of the output rows. Values: mostRecent = Most recent first (Apple's newest-first feed); mostHelpful = Most helpful first (Apple's most-helpful feed); lowestRating = Lowest rating first (reads all 500 recent reviews, then sorts); highestRating = Highest rating first (reads all 500 recent reviews, then sorts); oldest = Oldest first (of the 500 most recent).",
            "default": "mostRecent"
          },
          "searchResultsPerTerm": {
            "title": "Search results per term",
            "minimum": 1,
            "maximum": 50,
            "type": "integer",
            "description": "For search-term lines: take the top N apps of the App Store search (1 = first match only).",
            "default": 1
          },
          "minRating": {
            "title": "Minimum stars",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Keep reviews with at least this many stars. Filtered-out reviews are not charged.",
            "default": 1
          },
          "maxRating": {
            "title": "Maximum stars",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Keep reviews with at most this many stars, e.g. 2 for complaints only.",
            "default": 5
          },
          "sinceDate": {
            "title": "Reviews since",
            "type": "string",
            "description": "A date (2026-09-01) or a period (7 days, 2 weeks, 3 months). Older reviews are skipped and not charged; with the newest-first order, reading stops at the first older page."
          },
          "keywords": {
            "title": "Review contains (any of)",
            "type": "array",
            "description": "Keep reviews whose title or text contains at least one of these words or phrases (case-insensitive), e.g. crash, subscription, dark mode.",
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "Review must not contain",
            "type": "array",
            "description": "Drop reviews whose title or text contains any of these.",
            "items": {
              "type": "string"
            }
          },
          "appVersions": {
            "title": "App versions",
            "type": "array",
            "description": "Keep reviews written for these app versions only, e.g. 448.0.0, or 448 for every 448.x version.",
            "items": {
              "type": "string"
            }
          },
          "aiInsights": {
            "title": "AI insights per app (extra charge)",
            "type": "boolean",
            "description": "One extra row per app: an AI summary of the reviews returned in this run, with top praises, complaints, feature requests and bug reports (each with an example quote). Charged per app ($0.02 on the Free plan) only when the summary is produced; needs at least 10 reviews.",
            "default": false
          },
          "insightsLanguage": {
            "title": "Insights language",
            "type": "string",
            "description": "Language of the AI summary, e.g. German or Japanese. Default: English. Example quotes stay in the reviewers' words."
          },
          "onlyNewReviews": {
            "title": "Only new reviews since the last run",
            "type": "boolean",
            "description": "Remember the reviews of every app and country and return only reviews that were not there on the previous run of the same monitor (the first run returns everything and becomes the baseline). Reviews already seen are not output and not charged. Ideal for daily schedules.",
            "default": false
          },
          "monitorName": {
            "title": "Monitor name",
            "type": "string",
            "description": "Runs with the same name are compared with each other (letters, digits, dashes). Use different names for different app lists. Default: \"default\"."
          },
          "dedupeReviews": {
            "title": "Remove duplicate reviews",
            "type": "boolean",
            "description": "Apple's feed can shift while it is read (new reviews push older ones to the next page), so the same review may appear twice. Duplicates are removed by review id and never charged.",
            "default": true
          },
          "emptyPageRetries": {
            "title": "Retries for empty feed pages",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Apple's reviews feed often answers with an empty page for a page that has reviews. Each empty page is asked again up to this many times (with a fresh URL so a cached empty answer is not reused). Higher = more complete, a bit slower.",
            "default": 40
          },
          "maxConcurrency": {
            "title": "Apps in parallel",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many apps are processed at the same time. App lookups and searches are always spaced about 3 seconds apart, as Apple asks (about 20 calls per minute).",
            "default": 3
          },
          "feedConcurrency": {
            "title": "Feed requests in parallel",
            "minimum": 1,
            "maximum": 16,
            "type": "integer",
            "description": "How many reviews-feed requests run at the same time across all apps. When Apple answers \"rate limited\" (HTTP 403/429), every request pauses together and retries later (not charged). Lower it if runs report many rate-limited requests (SUMMARY.feed).",
            "default": 4
          },
          "appTimeoutSecs": {
            "title": "Time limit per app (seconds)",
            "minimum": 60,
            "maximum": 3600,
            "type": "integer",
            "description": "An app that takes longer gets a timeout error row (not charged) so one slow app cannot hold the run.",
            "default": 900
          },
          "proxyConfiguration": {
            "title": "Proxy (optional)",
            "type": "object",
            "description": "Only used for requests sent from Apify's network (all requests of this Actor). Apify proxy usage is billed to your Apify account. Not needed normally."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}