{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Maps Scraper - Business Leads, Emails & Reviews",
    "description": "Scrape Google Maps business data at scale: names, addresses, phones, websites, emails, opening hours, ratings and reviews. HTTP-first engine, 10-30x faster than browser scrapers, breaks the 120-result limit. Export to CSV, Excel, JSON.",
    "version": "1.7",
    "x-build-id": "ttbWwgdR1ISvARCFy"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/andrew_babo~google-maps-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-andrew_babo-google-maps-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/andrew_babo~google-maps-scraper/runs": {
      "post": {
        "operationId": "runs-sync-andrew_babo-google-maps-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/andrew_babo~google-maps-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-andrew_babo-google-maps-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": {
          "searchStringsArray": {
            "title": "Search terms",
            "type": "array",
            "description": "Queries to search on Google Maps, e.g. [\"coffee shop\", \"restaurant\"]. Combined with locationQuery or customGeolocation.",
            "items": {
              "type": "string"
            }
          },
          "locationQuery": {
            "title": "Location",
            "type": "string",
            "description": "Free-form location (city, region, country) geocoded via OpenStreetMap, e.g. \"New York, USA\". The area is automatically split into adaptive tiles to bypass the ~120 results per viewport limit."
          },
          "customGeolocation": {
            "title": "Custom geolocation (GeoJSON)",
            "type": "object",
            "description": "Optional GeoJSON Point/Polygon/MultiPolygon (or {type:'Feature', geometry: ...}). Overrides locationQuery. Point uses a 5 km radius by default."
          },
          "maxCrawledPlacesPerSearch": {
            "title": "Max places per search",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum number of places to scrape per search term. 0 or empty = unlimited.",
            "default": 100
          },
          "language": {
            "title": "Language",
            "type": "string",
            "description": "Google Maps interface language (hl param), e.g. en, es, vi.",
            "default": "en"
          },
          "countryCode": {
            "title": "Country code",
            "type": "string",
            "description": "Country for the Google geo parameter (gl param), lowercase ISO code, e.g. us, gb, sg.",
            "default": "us"
          },
          "categoryFilterWords": {
            "title": "Category filter words",
            "type": "array",
            "description": "Keep only places whose categories contain at least one of these words (case-insensitive). Empty = keep all.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "placeMinimumStars": {
            "title": "Minimum stars",
            "enum": [
              "",
              "2",
              "2.5",
              "3",
              "3.5",
              "4",
              "4.5"
            ],
            "type": "string",
            "description": "Keep only places with rating at least this value. Empty = no filter.",
            "default": ""
          },
          "skipClosedPlaces": {
            "title": "Skip permanently closed places",
            "type": "boolean",
            "description": "Exclude places marked as permanently closed.",
            "default": true
          },
          "scrapePlaceDetailPage": {
            "title": "Scrape place detail page",
            "type": "boolean",
            "description": "Visit each place's detail endpoint to enrich with phone, website, opening hours, photos, additional info. Disable for maximum speed (listing data only).",
            "default": true
          },
          "maxReviews": {
            "title": "Max reviews per place",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum reviews to scrape per place (0 = none). Reviews are fetched 10 per page.",
            "default": 0
          },
          "reviewsSort": {
            "title": "Reviews sort order",
            "enum": [
              "most_relevant",
              "newest",
              "highest_rating",
              "lowest_rating"
            ],
            "type": "string",
            "description": "Sort order for scraped reviews.",
            "default": "newest"
          },
          "reviewsStartDate": {
            "title": "Reviews start date",
            "type": "string",
            "description": "Optional ISO date (YYYY-MM-DD). Only keep reviews published after this date.",
            "default": ""
          },
          "maxImages": {
            "title": "Max images per place",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum image URLs to collect per place (0 = none). Images come from the detail payload.",
            "default": 10
          },
          "startUrls": {
            "title": "Start URLs",
            "type": "array",
            "description": "Direct Google Maps place/search URLs to scrape instead of searchStringsArray.",
            "default": [],
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "placeIds": {
            "title": "Place IDs",
            "type": "array",
            "description": "Direct Google place IDs (ChIJ... or 0x...:0x... CID pairs) to scrape details for, without searching.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "engine": {
            "title": "Engine",
            "enum": [
              "auto",
              "http",
              "browser"
            ],
            "type": "string",
            "description": "auto = HTTP-first with browser fallback on blocks/parse failures; http = HTTP only (fastest); browser = Playwright stealth only (slowest, most compatible).",
            "default": "auto"
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Maximum parallel HTTP requests. Adaptive controller (AIMD) may lower this automatically when blocks are detected. Leave empty to let Speed mode decide."
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify Proxy configuration. Residential proxies recommended for large runs. Not required for small runs.",
            "default": {
              "useApifyProxy": false
            }
          },
          "failOnZeroResults": {
            "title": "Fail run when nothing is scraped",
            "type": "boolean",
            "description": "When true (default) the run FAILS instead of silently succeeding if 0 places were scraped — e.g. when every listing request was blocked.",
            "default": true
          },
          "deepRecall": {
            "title": "Deep recall mode",
            "type": "boolean",
            "description": "Split the map area into more, smaller tiles for maximum coverage. Slower and uses more requests, still far cheaper than browser crawlers. Use when you need every place in an area.",
            "default": false
          },
          "includeRunSummary": {
            "title": "Include run summary in dataset",
            "type": "boolean",
            "description": "Push one extra item containing run statistics and field-coverage percentages at the end of the dataset.",
            "default": true
          },
          "detailMode": {
            "title": "Detail request mode",
            "enum": [
              "auto",
              "always",
              "never"
            ],
            "type": "string",
            "description": "always = always fetch the place detail payload (best field coverage), auto = only when the listing record is incomplete, never = listing only (fastest/cheapest).",
            "default": "auto"
          },
          "richDetailAttempts": {
            "title": "Rich detail attempts",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many times to retry a place detail request while Google withholds reviewsCount / the full 7-day opening hours. Higher = better coverage, slightly more requests. Leave empty to let Speed mode decide."
          },
          "detailFanout": {
            "title": "Detail fan-out",
            "minimum": 1,
            "maximum": 6,
            "type": "integer",
            "description": "How many detail attempts run in parallel, each on its own warm session. Higher = faster on lean shards, more requests in flight. Leave empty to let Speed mode decide."
          },
          "richListingAttempts": {
            "title": "Rich listing attempts",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Google returns a search page either without or with review counts and full opening hours. Retry the listing request up to this many times to land a rich page (cheap: one retry enriches ~20 places at once). Leave empty to let Speed mode decide."
          },
          "dedupeByPlaceId": {
            "title": "Deduplicate by place ID",
            "type": "boolean",
            "description": "Remove places already scraped by an earlier search term. Each item lists every matching term in matchedSearchStrings.",
            "default": true
          },
          "mode": {
            "title": "Output mode",
            "enum": [
              "ids",
              "basic",
              "full"
            ],
            "type": "string",
            "description": "ids = identifiers only (cheapest), basic = listing fields without detail requests, full = listing + detail enrichment.",
            "default": "full"
          },
          "bbox": {
            "title": "Bounding box",
            "type": "array",
            "description": "[south, west, north, east] in degrees. Overrides locationQuery."
          },
          "centerPoint": {
            "title": "Center point",
            "type": "array",
            "description": "Center of the search area as [lat, lng] (latitude first) or {\"lat\":..,\"lng\":..}. Used with radiusMeters. Wrong order fails the run with INVALID_COORDINATES."
          },
          "radiusMeters": {
            "title": "Radius (m)",
            "minimum": 100,
            "type": "integer",
            "description": "Radius in meters around centerPoint.",
            "default": 5000
          },
          "gridStepMeters": {
            "title": "Grid step (m)",
            "minimum": 0,
            "type": "integer",
            "description": "Seed grid cell size. Leave at 0 to let the actor pick one from the area size (a single viewport only returns ~120 places, so large areas are gridded automatically).",
            "default": 0
          },
          "cids": {
            "title": "CIDs",
            "type": "array",
            "description": "Decimal Google CIDs to hydrate into full place records.",
            "items": {
              "type": "string"
            }
          },
          "scrapeContacts": {
            "title": "Scrape contacts from website",
            "type": "boolean",
            "description": "Fetch each place website and extract emails + social links (1 extra request per place).",
            "default": false
          },
          "requestTimeoutSecs": {
            "title": "Request timeout (s)",
            "minimum": 5,
            "maximum": 300,
            "type": "integer",
            "description": "Timeout for each Google request in seconds.",
            "default": 30
          },
          "maxRunTimeSecs": {
            "title": "Max run time (s)",
            "minimum": 60,
            "maximum": 86400,
            "type": "integer",
            "description": "Hard wall-clock budget for the crawl in seconds.",
            "default": 3600
          },
          "scrapeReviewsDistribution": {
            "title": "Scrape review star distribution",
            "type": "boolean",
            "description": "Rescue the star histogram from the review feed when the place payload did not carry it (only for places with few enough reviews to count exactly). Turn off to save requests.",
            "default": true
          },
          "seedByCities": {
            "title": "Seed tiles by sub-locations",
            "type": "boolean",
            "description": "Add extra seed tiles for towns/districts inside the searched area. Improves recall in rural areas.",
            "default": true
          },
          "debugDumpPayload": {
            "title": "Debug: dump raw payloads",
            "minimum": 0,
            "maximum": 20,
            "type": "integer",
            "description": "Store the raw place-detail payload for the first N places in the key-value store (debugging only).",
            "default": 0
          },
          "reviewsDistributionMaxReviews": {
            "title": "Max reviews for distribution",
            "minimum": 0,
            "maximum": 2000,
            "type": "integer",
            "description": "Only derive reviewsDistribution when the place has at most this many reviews (the whole feed must be pulled to be exact).",
            "default": 200
          },
          "speedMode": {
            "title": "Speed mode",
            "enum": [
              "turbo",
              "fast",
              "balanced",
              "accurate"
            ],
            "type": "string",
            "description": "turbo = default: fastest wall-clock with full field coverage; fast = fewer retries; balanced = more listing retries; accurate = maximum retries.",
            "default": "turbo"
          },
          "maxPlacesPerTile": {
            "title": "Max places per tile (per wave)",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Cap on how many places a single map tile may contribute in one wave. Lower spreads results across the whole area; higher favours dense centres.",
            "default": 24
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}