{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Maps Scraper — Leads, Emails, Phone Numbers & Contacts",
    "description": "Search Google Maps for local businesses by keyword and location. One row per place: name, category, address, phone numbers, website, ratings, opening hours, place ID. Optional website contacts: emails, social media, WhatsApp. Filter leads free: no website, low rated, unclaimed, new businesses.",
    "version": "1.1",
    "x-build-id": "eiWrXK5tcA2fKDc8g"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/kestrel~google-maps-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-kestrel-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/kestrel~google-maps-scraper/runs": {
      "post": {
        "operationId": "runs-sync-kestrel-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/kestrel~google-maps-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-kestrel-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": {
          "searches": {
            "title": "Search terms",
            "type": "array",
            "description": "Business type or keyword, one per entry, exactly as typed into Google Maps: [\"dentist\"] or [\"coffee shop\", \"bakery\"]. Every term is searched in every entry of `locations`, so do not repeat the city here. A full phrase that already says where (\"pubs near Prague 2\") also works with `locations` left empty.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "locations": {
            "title": "Locations",
            "type": "array",
            "description": "Where to search, as free text, one per entry: [\"Austin, TX\"], [\"Lyon, France\"], [\"Shibuya, Tokyo\"], a ZIP code or a neighbourhood. Add the state or country when a name is ambiguous. Each location is verified on Google Maps first: an unknown location ends that search with an explanation and $0 charged, never with places from somewhere else.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "maxPlacesPerSearch": {
            "title": "Max places per search",
            "minimum": 1,
            "maximum": 20000,
            "type": "integer",
            "description": "Maximum places delivered AND charged per search term per location, counted after filters. Cost ceiling = this number × $0.003. One Google Maps query lists about 120–220 places; set `fullCoverage` to true to go beyond that.",
            "default": 100
          },
          "enrichContacts": {
            "title": "Find emails & social links",
            "type": "boolean",
            "description": "Set true to get emails and social links. For each place with a website, the home page plus contact, about, team and imprint pages are read for: emails (`emails`, `email_primary`), phone numbers, Facebook, Instagram, LinkedIn, X, YouTube, TikTok and WhatsApp. Adds $0.002 only for places where something was found (about 1 in 2; an email for about 1 in 3). Off = places only.",
            "default": false
          },
          "onlyWithEmail": {
            "title": "Only places with an email",
            "type": "boolean",
            "description": "Set true to deliver and charge ONLY places where an email address was found. Turns `enrichContacts` on and reads further down Google's list to fill `maxPlacesPerSearch`. Use for \"give me N businesses with emails\".",
            "default": false
          },
          "hasWebsite": {
            "title": "Website",
            "enum": [
              "any",
              "yes",
              "no"
            ],
            "type": "string",
            "description": "\"any\" (default), \"yes\" = only places that list a website, \"no\" = only places WITHOUT a website (prospects for web design and marketing agencies). Free; filtered places are not charged.",
            "default": "any"
          },
          "hasPhone": {
            "title": "Phone",
            "enum": [
              "any",
              "yes",
              "no"
            ],
            "type": "string",
            "description": "\"any\" (default), \"yes\" = only places with a phone number, \"no\" = only places without one. Free; filtered places are not charged.",
            "default": "any"
          },
          "isClaimed": {
            "title": "Claimed listing",
            "enum": [
              "any",
              "yes",
              "no"
            ],
            "type": "string",
            "description": "\"any\" (default), \"no\" = only UNCLAIMED listings (Google still shows \"Claim this business\": owners who have not set up their profile — prospects for local SEO and profile management), \"yes\" = only claimed listings. Free; filtered places are not charged.",
            "default": "any"
          },
          "minRating": {
            "title": "Min rating",
            "minimum": 0,
            "maximum": 5,
            "type": "number",
            "description": "Keep places rated at least this many stars (1–5). 0 = no limit. Places with no rating do not pass. Free filter.",
            "default": 0
          },
          "maxRating": {
            "title": "Max rating",
            "minimum": 0,
            "maximum": 5,
            "type": "number",
            "description": "Keep places rated at most this many stars, e.g. 3.9 to find low rated businesses for reputation services. 0 = no limit. Places with no rating do not pass. Free filter.",
            "default": 0
          },
          "minReviews": {
            "title": "Min reviews",
            "minimum": 0,
            "type": "integer",
            "description": "Keep places with at least this many Google reviews (established businesses). 0 = no limit. Free filter.",
            "default": 0
          },
          "maxReviews": {
            "title": "Max reviews",
            "minimum": 0,
            "type": "integer",
            "description": "Keep places with at most this many Google reviews (new or under-marketed businesses). 0 = no limit. Free filter.",
            "default": 0
          },
          "categoriesInclude": {
            "title": "Categories to include",
            "type": "array",
            "description": "Keep a place only if one of its Google Maps categories contains one of these words, case-insensitive: [\"dentist\", \"dental\"]. Removes off-topic results before they are charged.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "skipClosed": {
            "title": "Skip closed places",
            "type": "boolean",
            "description": "Set true to drop permanently and temporarily closed places before billing.",
            "default": false
          },
          "onlyNew": {
            "title": "Only new places",
            "type": "boolean",
            "description": "Monitoring: set true to deliver and charge only places that earlier runs with the same `monitorKey` have not delivered — i.e. new businesses since last time. Run it on a schedule; each run returns only the delta.",
            "default": false
          },
          "monitorKey": {
            "title": "Monitor key",
            "type": "string",
            "description": "Name of the memory `onlyNew` compares against. Use one key per list you maintain, e.g. \"austin-dentists\". Letters, digits, dash, underscore.",
            "default": "default"
          },
          "startUrls": {
            "title": "Google Maps URLs, place ids or CIDs",
            "type": "array",
            "description": "Known places or saved searches instead of (or besides) `searches`, e.g. [\"ChIJb5gBC-u0RIYRHkntaUcdJGs\", \"https://maps.google.com/?cid=7720327853776914718\"]. Accepts Google Maps place URLs, search URLs (google.com/maps/search/…), short links (maps.app.goo.gl/…), place IDs (ChIJ…) and CIDs. A place returns one full row: use it to look up the phone, website or emails of specific businesses.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "language": {
            "title": "Language",
            "type": "string",
            "description": "Language code for category names, opening hours and descriptions: en, de, fr, es, pt-BR, ja, ar … Default en.",
            "default": "en"
          },
          "country": {
            "title": "Country",
            "type": "string",
            "description": "Two-letter country code Google should assume for ambiguous names and phone formats: us, gb, de, fr, br, in, jp, ae … Default us.",
            "default": "us"
          },
          "fullCoverage": {
            "title": "Full coverage (grid)",
            "type": "boolean",
            "description": "Set true to collect MORE than the ~120–220 places one Google Maps query lists: the area is split into a grid and every cell is searched. Works with `locations` or with latitude/longitude/radiusKm, `boundingBox` or `polygon`. Each place is still delivered and charged once.",
            "default": false
          },
          "maxPlacesTotal": {
            "title": "Max places in the whole run",
            "minimum": 0,
            "maximum": 1000000,
            "type": "integer",
            "description": "Hard cap across every search in the run. 0 = no cap beyond the per-search limit and your spending limit.",
            "default": 0
          },
          "latitude": {
            "title": "Latitude",
            "type": "string",
            "description": "Centre of a circular search area, for example 30.2672. Use with Longitude and Radius instead of Locations.",
            "default": ""
          },
          "longitude": {
            "title": "Longitude",
            "type": "string",
            "description": "Centre of a circular search area, for example -97.7431.",
            "default": ""
          },
          "radiusKm": {
            "title": "Radius (km)",
            "minimum": 0.2,
            "maximum": 200,
            "type": "number",
            "description": "Radius around the centre, 0.2–200 km. Google ranks by prominence as well as distance, so turn on \"Only inside my area\" to drop anything beyond this radius before billing.",
            "default": 5
          },
          "withinRadiusOnly": {
            "title": "Only inside my area",
            "type": "boolean",
            "description": "Drop places outside the circle, box or polygon before billing. Without it Google may include prominent places a little beyond the area.",
            "default": false
          },
          "boundingBox": {
            "title": "Bounding box",
            "type": "object",
            "description": "A rectangle as {\"south\": 30.20, \"west\": -97.80, \"north\": 30.30, \"east\": -97.70}.",
            "default": {}
          },
          "polygon": {
            "title": "Polygon",
            "type": "array",
            "description": "A custom shape as a list of [latitude, longitude] points, for example [[30.20,-97.80],[30.30,-97.80],[30.25,-97.70]]. (A GeoJSON Polygon object is accepted through the API.)",
            "default": []
          },
          "gridCellKm": {
            "title": "Grid cell size (km)",
            "minimum": 0,
            "maximum": 50,
            "type": "number",
            "description": "Side of one grid cell in km (0.5–50). 0 = size cells automatically so the area fits in Max grid cells. Smaller cells find more places in dense cities and take longer.",
            "default": 0
          },
          "maxGridCells": {
            "title": "Max grid cells",
            "minimum": 1,
            "maximum": 400,
            "type": "integer",
            "description": "Upper bound on cells per search; cells are searched from the centre outwards.",
            "default": 64
          },
          "categoriesExclude": {
            "title": "Categories to exclude",
            "type": "array",
            "description": "Drop a place if any of its Google Maps categories contains one of these words: [\"supplier\", \"school\"].",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "nameContains": {
            "title": "Name contains",
            "type": "array",
            "description": "Keep a place only if its name contains one of these words.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "nameExcludes": {
            "title": "Name excludes",
            "type": "array",
            "description": "Drop a place if its name contains any of these words — for example chain names.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "excludePlaceIds": {
            "title": "Skip these place ids",
            "type": "array",
            "description": "Place ids (ChIJ…), CIDs or feature ids you already have. They are skipped before billing.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "excludeDatasetId": {
            "title": "Skip places from a dataset",
            "type": "string",
            "description": "Id of an earlier dataset of this actor: every place_id in it is skipped before billing.",
            "default": ""
          },
          "maxPagesPerSite": {
            "title": "Pages to read per website",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Home page plus the most promising contact, about, team and imprint pages, up to this many.",
            "default": 5
          },
          "sessions": {
            "title": "Parallel sessions",
            "minimum": 1,
            "maximum": 32,
            "type": "integer",
            "description": "Proxy sessions (IPs) used in parallel.",
            "default": 6
          },
          "perIp": {
            "title": "Requests per second per IP",
            "minimum": 0.1,
            "maximum": 3,
            "type": "number",
            "description": "Pace for each session.",
            "default": 1
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Apify datacenter proxies work for Google Maps and are the default; residential is not needed.",
            "default": {
              "useApifyProxy": true
            }
          },
          "locationQuery": {
            "title": "Location (compatibility alias)",
            "type": "string",
            "description": "Same as one entry in Locations.",
            "default": ""
          },
          "maxCrawledPlacesPerSearch": {
            "title": "Max places per search (compatibility alias)",
            "type": "integer",
            "description": "Same as Max places per search.",
            "default": 0
          },
          "countryCode": {
            "title": "Country (compatibility alias)",
            "type": "string",
            "description": "Same as Country.",
            "default": ""
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}