{
  "openapi": "3.0.1",
  "info": {
    "title": "App Store Search Scraper",
    "description": "Search the Apple App Store across any storefront and get the full 40-field app record - ratings, pricing, size, version history, screenshots and publisher - plus customer reviews attached free inside the row, read with the retry logic Apple's flaky review feed actually needs.",
    "version": "0.1",
    "x-build-id": "YvAArPLoIbOORTTcT"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/cirkit~app-store-search-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-cirkit-app-store-search-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/cirkit~app-store-search-scraper/runs": {
      "post": {
        "operationId": "runs-sync-cirkit-app-store-search-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/cirkit~app-store-search-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-cirkit-app-store-search-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": {
          "searchTerms": {
            "title": "Search keywords",
            "type": "array",
            "description": "Keywords to search the App Store for. Apple caps every search at 200 apps and ignores paging, so add more keywords (and more storefronts below) rather than expecting one keyword to return thousands.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "countries": {
            "title": "Storefronts",
            "type": "array",
            "description": "Two-letter country codes for the App Store storefronts to search. Each storefront has its own catalogue, pricing and ranking, so us + gb + de returns far more distinct apps than us alone. Duplicates are removed across storefronts before anything is charged.",
            "default": [
              "us"
            ],
            "items": {
              "type": "string"
            }
          },
          "platforms": {
            "title": "Platforms",
            "type": "array",
            "description": "Which App Store catalogue to search: iphone, ipad or mac. Each is a separate catalogue, so listing more than one widens the result set.",
            "default": [
              "iphone"
            ],
            "items": {
              "type": "string"
            }
          },
          "appIds": {
            "title": "App IDs, bundle IDs or URLs",
            "type": "array",
            "description": "Look specific apps up directly. Accepts a numeric App Store ID (570060128), a reverse-DNS bundle ID (com.duolingo.DuolingoMobile), or a full App Store URL — whichever you happen to have.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "chartCountries": {
            "title": "Top-chart storefronts",
            "type": "array",
            "description": "Two-letter country codes to pull Apple's official top-apps chart for. Every row from a chart carries its chartRank.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "chartType": {
            "title": "Chart",
            "enum": [
              "top-free",
              "top-paid"
            ],
            "type": "string",
            "description": "Which chart to pull. Apple publishes top-free and top-paid for apps; there is no top-grossing chart for apps.",
            "default": "top-free"
          },
          "chartLimit": {
            "title": "Chart size",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "How many ranked apps to take from each chart.",
            "default": 50
          },
          "maxItems": {
            "title": "Max apps",
            "minimum": 0,
            "type": "integer",
            "description": "Hard cap on how many apps this run returns, and therefore on what it costs. Duplicates and filters are applied before this cap.",
            "default": 100
          },
          "maxResultsPerTerm": {
            "title": "Apps per keyword",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "How many apps to take from each keyword-and-storefront pair. Apple's own hard ceiling is 200 regardless of what is asked for here.",
            "default": 50
          },
          "genreId": {
            "title": "Genre filter",
            "type": "integer",
            "description": "Restrict results to one App Store genre, for example 6017 Education, 6015 Finance, 6013 Health & Fitness, 6002 Utilities, 6014 Games, 6000 Business. Leave empty to search every genre."
          },
          "searchAttribute": {
            "title": "Match on",
            "enum": [
              "any",
              "softwareDeveloper"
            ],
            "type": "string",
            "description": "Which field the keyword has to match. 'Developer' is much stricter than the default, which matches app names, developers and descriptions.",
            "default": "any"
          },
          "minRating": {
            "title": "Minimum rating",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "Drop apps rated below this (1-5). Applied before the max-apps cap, so you get a full page of apps that pass rather than whatever survives. Leave empty for no rating filter."
          },
          "freeOnly": {
            "title": "Free apps only",
            "type": "boolean",
            "description": "Keep only apps priced at zero in the storefront searched.",
            "default": false
          },
          "includeReviews": {
            "title": "Include customer reviews",
            "type": "boolean",
            "description": "Attach customer reviews to each app row, with rating, title, body, author, app version and helpful-vote counts. Reviews ride inside the app row, so they cost nothing extra. Apple's review feed is genuinely flaky — this Actor retries empty pages, walks past them instead of stopping, and falls back to the other sort order rather than reporting an app as having no reviews.",
            "default": false
          },
          "maxReviewsPerApp": {
            "title": "Reviews per app",
            "minimum": 0,
            "maximum": 500,
            "type": "integer",
            "description": "How many reviews to attach when the option above is on. Apple's hard ceiling is 500 (10 pages of 50) per app and storefront.",
            "default": 50
          },
          "reviewsSortBy": {
            "title": "Review order",
            "enum": [
              "mostrecent",
              "mosthelpful"
            ],
            "type": "string",
            "description": "Which review order to ask Apple for first. If that order comes back degraded, the Actor automatically tries the other one before giving up.",
            "default": "mostrecent"
          },
          "maxRunSeconds": {
            "title": "Time budget (seconds)",
            "minimum": 60,
            "type": "integer",
            "description": "Stop opening new searches after this many seconds and push what has been collected. Protects a very wide search grid from running into the platform timeout and billing the full run. Leave empty for the default."
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Apple's endpoints are open and answer datacenter IPs, so the default proxy setting is all this Actor needs. Residential is available but buys nothing here.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}