{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Maps Scraper Pro: Reviews, Photos & Emails",
    "description": "Built to beat Google Maps Scraper: on the same 100 places, the same star breakdown, popular times, review topics, owner text and hotel details, faster; 2.4x the Leeds plumbers in a whole-city run; 98% of results in the city you asked for (theirs 77%). Every add-on at 70% of its price.",
    "version": "0.1",
    "x-build-id": "jcpiXQYDcoYnNfjsx"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/tidyharvest~google-maps-scraper-pro/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-tidyharvest-google-maps-scraper-pro",
        "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/tidyharvest~google-maps-scraper-pro/runs": {
      "post": {
        "operationId": "runs-sync-tidyharvest-google-maps-scraper-pro",
        "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/tidyharvest~google-maps-scraper-pro/run-sync": {
      "post": {
        "operationId": "run-sync-tidyharvest-google-maps-scraper-pro",
        "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": {
          "searches": {
            "title": "Searches",
            "type": "array",
            "description": "What you would type into Google Maps, one per line: `coffee shops`, `plumbers`, `wine bars in San Francisco`. For a list of known businesses, one per line as `Name, street, city` (or paste Google Maps place links; for exact place ids use Place IDs below) and set Max places per search to 1: each line gets its best match, labelled by how well name and street agree, and a line with no confident match comes back as a free `lookupMatch: none` row. With a Location below, write just the category (`coffee shops`).",
            "items": {
              "type": "string"
            }
          },
          "placeIds": {
            "title": "Place IDs or links",
            "type": "array",
            "description": "Exact places, one per line: a placeId (`ChIJ...`), a CID, or a Google Maps place link. Each comes back as that exact place. Use with or instead of Searches.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Google Maps links",
            "type": "array",
            "description": "Google Maps links, one per line: a place link returns that place; a search link (`google.com/maps/search/coffee/@37.76,-122.42,14z`) runs that search on that part of the map.",
            "items": {
              "type": "string"
            }
          },
          "location": {
            "title": "Location (whole-area mode)",
            "type": "string",
            "description": "A city, district or region (`Austin, TX`, `Brooklyn`, `Bruges, Belgium`). Each search then covers the whole area, past Google Maps' ~120-results-per-search limit. Places outside the area's boundary are dropped and not charged."
          },
          "customGeolocation": {
            "title": "Draw your own area (GeoJSON)",
            "type": "object",
            "description": "Instead of a Location: a GeoJSON `Polygon` or `MultiPolygon` (longitude, latitude order), a `Point` with `radiusKm`, or a bounding box `[south, west, north, east]`. Each search then covers that shape, and places outside it are dropped and not charged."
          },
          "postalCodes": {
            "title": "Postal codes",
            "type": "array",
            "description": "Run each search once per postal code (`80302`, `LS7`, `75011`). Set Country to the codes' country.",
            "items": {
              "type": "string"
            }
          },
          "city": {
            "title": "City",
            "type": "string",
            "description": "Instead of Location: city, with County and State below if needed (set Country too)."
          },
          "county": {
            "title": "County",
            "type": "string",
            "description": "Optional, with City or State."
          },
          "state": {
            "title": "State",
            "type": "string",
            "description": "Optional, with City or County."
          },
          "splitArea": {
            "title": "Cover the whole area",
            "type": "boolean",
            "description": "With a Location: keep searching until the whole area is covered or the search budget is used. Off = one search of up to ~120 places centred on the location.",
            "default": true
          },
          "maxCellsPerSearch": {
            "title": "Max Google searches per category (whole-area mode)",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Search budget per category in whole-area mode. The run stops earlier when the area is covered. 60 covers one category in a city of ~100k; raise it for large cities or broad categories like restaurants.",
            "default": 60
          },
          "broadMatch": {
            "title": "Broad match (whole-area mode)",
            "type": "boolean",
            "description": "Also keep places whose main category is close to your search (Gas engineer for plumbers). More places, a few less exact; off keeps results strictly on-category.",
            "default": false
          },
          "maxPlacesPerSearch": {
            "title": "Max places per search",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "Cap per search. Default 60 for a normal search (Google stops at ~120); no cap in whole-area mode unless you set one. 1 = lookup mode for lists of known businesses (see Searches)."
          },
          "latitude": {
            "title": "Latitude (optional)",
            "type": "number",
            "description": "Center the search here. Use with Longitude and Radius."
          },
          "longitude": {
            "title": "Longitude (optional)",
            "type": "number",
            "description": "Center the search here."
          },
          "radiusMeters": {
            "title": "Radius in meters (optional)",
            "minimum": 100,
            "maximum": 100000,
            "type": "integer",
            "description": "Search area around the coordinates. Default 10,000."
          },
          "strictLocation": {
            "title": "Only places in the area you asked for",
            "type": "boolean",
            "description": "Google sometimes mixes in places from another city with the same name (Glasgow, Delaware for `electricians in Glasgow`) or another country. On: those are dropped and not charged (counted in the run's SUMMARY). Service-area businesses with no public address are kept.",
            "default": true
          },
          "scrapePlaceDetails": {
            "title": "Place details: reviews, star breakdown, popular times, photos",
            "type": "boolean",
            "description": "Open each place's own page for: the 1-5 star breakdown, popular times by hour, review topics with counts, the business's own description and posts, owner, \"located in\", order and booking links, hotel class, amenities and nightly price, and the total photo count. Add-on: $1.40 per 1,000 places (charged only when the page answers). Reviews and photos below are priced separately.",
            "default": false
          },
          "maxReviews": {
            "title": "Reviews per place (with place details)",
            "minimum": 0,
            "maximum": 8,
            "type": "integer",
            "description": "0-8: the reviews Google shows on the place's page, with text, stars, date, reviewer, owner reply and the diner/hotel answers. $0.35 per 1,000 reviews.",
            "default": 0
          },
          "reviewsSort": {
            "title": "Sort reviews",
            "enum": [
              "mostRelevant",
              "newest",
              "highestRanking",
              "lowestRanking"
            ],
            "type": "string",
            "description": "Order of the reviews returned (of the ones Google shows on the place's page).",
            "default": "mostRelevant"
          },
          "reviewsStartDate": {
            "title": "Only reviews newer than",
            "type": "string",
            "description": "A date (`2026-05-03`) or a period (`8 days`, `3 months`, `1 year`)."
          },
          "reviewsFilterString": {
            "title": "Only reviews mentioning",
            "type": "string",
            "description": "Keep reviews containing any of these words (space or comma separated)."
          },
          "reviewsOrigin": {
            "title": "Review source",
            "enum": [
              "all",
              "google"
            ],
            "type": "string",
            "description": "Hotels also show partner reviews.",
            "default": "all"
          },
          "scrapeReviewsPersonalData": {
            "title": "Include reviewers' data",
            "type": "boolean",
            "description": "Reviewer name, id, profile link and photo, and the review link. Off: reviews come without them.",
            "default": true
          },
          "maxImages": {
            "title": "Photos per place (with place details)",
            "minimum": 0,
            "maximum": 20,
            "type": "integer",
            "description": "0-20 photo links per place (with size), Street View last. $0.35 per 1,000 photos; Street View thumbnails are free.",
            "default": 0
          },
          "scrapeImageAuthors": {
            "title": "Photo authors",
            "type": "boolean",
            "description": "Add each photo's author and date (slower: about a second per photo). Included in the photo price.",
            "default": false
          },
          "includeContacts": {
            "title": "Find emails, phones and social profiles",
            "type": "boolean",
            "description": "Read each place's own website (contact, about and team pages) for emails (typed: company inbox, named person, or other), extra phone numbers and Instagram, Facebook, TikTok, X, YouTube and LinkedIn links. Add-on: $1.40 per 1,000 places whose website answers (no website, dead, parked or blocked sites are free).",
            "default": false
          },
          "checkEmails": {
            "title": "Check emails",
            "type": "boolean",
            "description": "With website contacts: check each email's syntax, mail server (MX), disposable, role and free-mail status. $0.30 per 1,000 emails checked.",
            "default": false
          },
          "keywords": {
            "title": "Keywords (match any)",
            "type": "array",
            "description": "Keep a place only if its name, categories or description contains one of these.",
            "items": {
              "type": "string"
            }
          },
          "minRating": {
            "title": "Minimum rating",
            "minimum": 0,
            "maximum": 5,
            "type": "number",
            "description": "Keep places rated at least this (0-5)."
          },
          "minReviews": {
            "title": "Minimum reviews",
            "minimum": 0,
            "type": "integer",
            "description": "Keep places with at least this many reviews."
          },
          "requireWebsite": {
            "title": "Only places with a website",
            "type": "boolean",
            "description": "Drop places that list no website.",
            "default": false
          },
          "website": {
            "title": "Website",
            "enum": [
              "allPlaces",
              "withWebsite",
              "withoutWebsite"
            ],
            "type": "string",
            "description": "Keep places by whether they list a website. Free (no filter fee).",
            "default": "allPlaces"
          },
          "categoryFilterWords": {
            "title": "Place categories",
            "type": "array",
            "description": "Keep only places with one of these categories (`dentist`, `italian restaurant`): matched against every category Google lists for the place. Free.",
            "items": {
              "type": "string"
            }
          },
          "searchMatching": {
            "title": "Name matching",
            "enum": [
              "all",
              "only_includes",
              "only_exact"
            ],
            "type": "string",
            "description": "Keep places whose name contains, or equals, the search term (the part before `in <place>`). Free.",
            "default": "all"
          },
          "skipClosedPlaces": {
            "title": "Skip permanently closed places",
            "type": "boolean",
            "description": "Leave out places Google marks as permanently closed (not charged). Off: they are returned with `permanentlyClosed: true`.",
            "default": false
          },
          "language": {
            "title": "Language",
            "type": "string",
            "description": "Result language code, for example `en`, `es`, `de`.",
            "default": "en"
          },
          "country": {
            "title": "Country bias",
            "type": "string",
            "description": "Two-letter country code that biases results, for example `us`, `gb`, `mx`.",
            "default": "us"
          },
          "parallelSessions": {
            "title": "Parallel connections",
            "minimum": 1,
            "maximum": 16,
            "type": "integer",
            "description": "How many connections work at once. More is faster; 1 is the slowest and steadiest.",
            "default": 4
          },
          "maxItems": {
            "title": "Max places in total",
            "minimum": 0,
            "type": "integer",
            "description": "Hard cap on results for the whole run (also caps your cost). 0 or empty = no limit."
          },
          "dedupeAcrossSearches": {
            "title": "Skip places already returned",
            "type": "boolean",
            "description": "Return each place once per run. Turn off when you look up a list of businesses and want one row per input line, even for duplicates.",
            "default": true
          },
          "skipPlaceIds": {
            "title": "Skip places you already have (ids)",
            "type": "array",
            "description": "placeId, fid or cid values to leave out (not charged). For scheduled runs that should return only new places.",
            "items": {
              "type": "string"
            }
          },
          "skipDatasetIds": {
            "title": "Skip places from earlier runs (dataset ids)",
            "type": "array",
            "description": "Dataset ids (or dataset URLs) of earlier runs of this actor: every place in them is skipped and not charged.",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}