{
  "openapi": "3.0.1",
  "info": {
    "title": "App Store Reviews Scraper — Deep, Multi-Country, Dev Replies",
    "description": "Apple App Store reviews from Apple's own review API: rating, title, body, author, date and developer reply, one row per review. Goes past the 500-review RSS cap — verified 150,000 reviews deep on one app — and sweeps many countries in one run. $0.10 per 1,000 reviews. No login, no token.",
    "version": "0.1",
    "x-build-id": "0JOzC3uNLnXvmtyrR"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapersdelight~appstore-reviews-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapersdelight-appstore-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/scrapersdelight~appstore-reviews-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapersdelight-appstore-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/scrapersdelight~appstore-reviews-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapersdelight-appstore-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",
            "type": "array",
            "description": "One or more apps, as full App Store URLs (https://apps.apple.com/us/app/whatsapp-messenger/id310633997) or bare numeric ids (310633997). The id is the number after \"id\" in any App Store URL. Every app is crossed with every country below. An id that does not exist is reported and skipped rather than silently returning nothing. Left empty, the Actor runs its WhatsApp sample so an API or agent call with no input still gets real rows.",
            "default": [
              "https://apps.apple.com/us/app/whatsapp-messenger/id310633997"
            ],
            "items": {
              "type": "string"
            }
          },
          "countries": {
            "title": "Countries (storefronts)",
            "type": "array",
            "description": "2-letter App Store storefront codes, one per entry: us, gb, de, fr, jp, br, in, au, kr, ca, mx, es, it, nl… (Apple runs ~175 storefronts; the README lists them). Reviews are storefront-specific, so every country is a separate corpus — this is how you sweep a competitor's reviews worldwide in one run. An unknown code is reported per app x country and never billed.",
            "default": [
              "us"
            ],
            "items": {
              "type": "string"
            }
          },
          "mode": {
            "title": "Mode",
            "enum": [
              "deep",
              "recent"
            ],
            "type": "string",
            "description": "\"deep\" (default) reads Apple's review API with unlimited pagination — verified 150,000 reviews deep on one app — in Apple's most-helpful order, and includes developer replies and the isEdited flag. \"recent\" reads Apple's newest-first feed instead: max 500 reviews per app x country (Apple's cap, not ours), and it is the ONLY mode that carries appVersion, helpful-vote counts and the author profile URL — Apple's API omits those in deep mode.",
            "default": "deep"
          },
          "minRating": {
            "title": "Minimum rating",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Keep only reviews rated at least this many stars (1-5). 0 = off. Set minRating 1 and maxRating 2 to mine complaints; 4-5 for testimonial material.",
            "default": 0
          },
          "maxRating": {
            "title": "Maximum rating",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Keep only reviews rated at most this many stars (1-5). 0 = off.",
            "default": 0
          },
          "onlyWithDeveloperResponse": {
            "title": "Only reviews the developer replied to",
            "type": "boolean",
            "description": "Keep only reviews carrying a developer reply. Deep mode only — Apple's newest-first feed (recent mode) does not carry replies at all, and the run stops with an error rather than silently returning nothing. Expect a minority of rows even for responsive publishers: measured 47% on Slack's first 100, 0% on Duolingo's.",
            "default": false
          },
          "maxItems": {
            "title": "Max reviews (total)",
            "minimum": 1,
            "type": "integer",
            "description": "Hard cap on reviews returned across the whole run, and therefore your cost ceiling: 600 = $0.06, 10,000 = $1, 100,000 = $10. Counts unique, delivered reviews only.",
            "default": 600
          },
          "maxReviewsPerAppCountry": {
            "title": "Max reviews per app x country",
            "minimum": 0,
            "type": "integer",
            "description": "Per-corpus cap, so one deep storefront cannot eat the whole run budget before the other countries get a turn. 0 = no per-corpus cap (each corpus is walked to exhaustion or until Max reviews is hit). The shipped default of 200 is what splits the default 600-review run evenly across us/gb/au.",
            "default": 0
          },
          "maxConcurrency": {
            "title": "Concurrency",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "How many app x country corpora are walked in parallel (pages within one corpus are sequential — that is how offset pagination works). Max 5, and deliberately modest: Apple rate-limits per IP and the retry logic already absorbs that; more workers mostly buys more 429s.",
            "default": 3
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "On by default (Apify datacenter) and that is deliberate: Apple 429-throttles a busy single IP — measured 65% raw success direct at concurrency 3 versus 100% (50/50 contiguous pages) through datacenter with this Actor's fresh-session retry. Residential is not needed; there is no bot wall, only a rate limit.",
            "default": {
              "useApifyProxy": true
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}