{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Maps Reviews Scraper — Date Range, New-Only, Complete",
    "description": "Scrape Google Maps reviews by URL, short link, place id or name. True date range, new-reviews-only monitoring, owner replies, exact dates, text-only and star filters, and a completeness check against the listed total on every place. No login. $0.40 per 1,000 reviews.",
    "version": "1.0",
    "x-build-id": "PcC751ftlUzBhikaT"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/kestrel~google-maps-reviews-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-kestrel-google-maps-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/kestrel~google-maps-reviews-scraper/runs": {
      "post": {
        "operationId": "runs-sync-kestrel-google-maps-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/kestrel~google-maps-reviews-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-kestrel-google-maps-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": {
          "places": {
            "title": "Places",
            "uniqueItems": true,
            "type": "array",
            "description": "One place per line, in any mix: a Google Maps place URL, a maps.app.goo.gl or share.google short link (followed for you), a place id (ChIJ…), a CID (the long number in ?cid=), a feature id (0x…:0x…), a Maps search URL, or just \"name, city\" — the actor finds the place itself, no place id needed. A column copied from Excel or Google Sheets can be pasted as it is. The same place given twice is read once.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Start URLs (same as Places)",
            "type": "array",
            "description": "An alias for Places, for integrations that always send startUrls (Make, n8n, Zapier, a Google Sheet of links) and for input copied from compass/google-maps-reviews-scraper. Every entry is read exactly like a line in Places.",
            "default": [],
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "placeIds": {
            "title": "Place ids (same as Places)",
            "type": "array",
            "description": "An alias for Places that takes Google place ids (ChIJ…), so the placeIds list of a Compass input or of a Google Places API export pastes straight in.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "maxReviewsPerPlace": {
            "title": "Max reviews per place",
            "minimum": 0,
            "maximum": 1000000,
            "type": "integer",
            "description": "0 = every review the place has. N = the first N in the chosen order that pass your filters. This is the main cost control: you pay per delivered review, so 100 reviews from 50 places is at most 5,000 reviews = $2.00.",
            "default": 100
          },
          "sort": {
            "title": "Order",
            "enum": [
              "newest",
              "most_relevant",
              "highest",
              "lowest"
            ],
            "type": "string",
            "description": "Newest first is what monitoring and date ranges need: the walk stops as soon as it passes your From date, so nothing older is read or paid for. Lowest rating first is the quick way to a place's complaints.",
            "default": "newest"
          },
          "fromDate": {
            "title": "From date",
            "type": "string",
            "description": "Only reviews published on or after this day: YYYY-MM-DD, or a look-back such as \"30 days\", \"2 weeks\", \"6 months\". With Newest first the actor stops reading at this date, so a weekly run over a place with 50,000 reviews reads one page, not a thousand.",
            "default": ""
          },
          "toDate": {
            "title": "To date",
            "type": "string",
            "description": "Only reviews published on or before this day: YYYY-MM-DD or a look-back such as \"7 days\". Together with From date this is a true date range — for example one calendar quarter.",
            "default": ""
          },
          "onlyNew": {
            "title": "Only new reviews since the last run",
            "type": "boolean",
            "description": "Monitoring mode. The actor remembers which reviews it delivered for each place and, on the next run, delivers and bills only the ones it has not delivered before. Put the run on a schedule and you get a feed of new reviews; a run that finds nothing new costs $0.",
            "default": false
          },
          "includeEdited": {
            "title": "Also deliver edited reviews",
            "type": "boolean",
            "description": "With Only new reviews on: deliver a review again when its author edited it after you received it (the row carries edited = true and both dates). With a date range: a review edited inside the range counts as inside it.",
            "default": false
          },
          "monitorKey": {
            "title": "Monitor key",
            "type": "string",
            "description": "The name of the memory that Only new reviews uses. Runs with the same key share one memory; give each separate feed (a client, a Slack channel, a test) its own key so they do not hide reviews from each other. Letters, digits and hyphens.",
            "default": "default"
          },
          "onlyWithText": {
            "title": "Only reviews with text",
            "type": "boolean",
            "description": "Skip star-only ratings. Roughly a third of Google reviews carry no text; with this on you read past them for free and pay only for reviews that say something — what sentiment analysis and AI summaries need.",
            "default": false
          },
          "minStars": {
            "title": "Min stars",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Keep reviews with at least this many stars. 0 = no lower bound.",
            "default": 0
          },
          "maxStars": {
            "title": "Max stars",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Keep reviews with at most this many stars, e.g. 2 for complaints only. 0 = no upper bound.",
            "default": 0
          },
          "keywords": {
            "title": "Keywords (any of)",
            "type": "array",
            "description": "Keep a review only if its text, or Google's translation of it, contains at least one of these words or phrases. Case-insensitive.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "Exclude keywords",
            "type": "array",
            "description": "Drop a review if its text or translation contains any of these words or phrases.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "reviewLanguages": {
            "title": "Review languages",
            "type": "array",
            "description": "Keep only reviews written in these languages, as two-letter codes: en, de, fr, es, ja … Star-only ratings have no language and are dropped when this is set.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "hasOwnerReply": {
            "title": "Owner reply",
            "enum": [
              "any",
              "yes",
              "no"
            ],
            "type": "string",
            "description": "\"Still waiting for a reply\" is the to-do list of a reputation manager; \"replied\" is how you study a competitor's tone.",
            "default": "any"
          },
          "hasPhotos": {
            "title": "Only reviews with photos",
            "type": "boolean",
            "description": "Keep only reviews that carry at least one photo.",
            "default": false
          },
          "translate": {
            "title": "Text",
            "enum": [
              "original",
              "translated",
              "both"
            ],
            "type": "string",
            "description": "Google translates every review that is not in your Language. Original leaves text as written; Translation puts the translation in text; Both fills text and text_translated. The owner's reply follows the same choice.",
            "default": "original"
          },
          "language": {
            "title": "Language",
            "type": "string",
            "description": "The interface language, as a code: en, de, fr, es, pt-BR, ja … It sets the language of translations, of place categories and of Google's relative dates (published_text). Exact dates do not depend on it.",
            "default": "en"
          },
          "country": {
            "title": "Country",
            "type": "string",
            "description": "The two-letter country Google is asked from (gl), e.g. us, gb, de. Rarely matters; change it if a place name resolves to the wrong country.",
            "default": "us"
          },
          "includePlaceRow": {
            "title": "Place summary row",
            "type": "boolean",
            "description": "One free row per place: rating, the total Google lists, the per-star histogram, how many reviews this run read and delivered, the completeness verdict and the 90-day rating trend.",
            "default": true
          },
          "sessions": {
            "title": "Parallel sessions",
            "minimum": 1,
            "maximum": 16,
            "type": "integer",
            "description": "How many proxy sessions (IPs) work at once. Places are read in parallel; pages of one place are read in order.",
            "default": 4
          },
          "perIp": {
            "title": "Requests per second per IP",
            "type": "string",
            "description": "Pacing for each session, e.g. 1 or 0.5. Lower is gentler on Google.",
            "default": "1"
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Datacenter proxies are enough and keep the run cheap. The actor rotates the IP whenever Google answers an empty or cut-down page.",
            "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
                  },
                  "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}