{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Maps Scraper - Business Data, Reviews & Leads",
    "description": "Scrape Google Maps business listings without an API key — name, address, phone, website, rating, reviews, photos, hours, amenities & GPS. Precision targeting (batch, map URLs, custom area) + optional add-ons: emails, socials, contacts & ad intelligence. Export to CSV, Excel & JSON.",
    "version": "1.11",
    "x-build-id": "cKwq55laBUJwrNClX"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/buff_pineapple~google-maps-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-buff_pineapple-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/buff_pineapple~google-maps-scraper/runs": {
      "post": {
        "operationId": "runs-sync-buff_pineapple-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/buff_pineapple~google-maps-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-buff_pineapple-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": {
          "query": {
            "title": "Search Query",
            "type": "string",
            "description": "What to search for on Google Maps — exactly what you'd type in the search box. Works best as \"<category> in <location>\", e.g. \"restaurants in New York\" or \"dentists in Miami\". Plain phrases like \"coffee shops Seattle\" or \"plumbers 90210\" also work — the location is detected automatically. You can also leave this empty and use the Advanced targeting options below (batch queries, Google Maps URLs, or a custom area)."
          },
          "searchQueries": {
            "title": "Batch Search Queries (Precision Targeting)",
            "type": "array",
            "description": "Run several searches in one go — one query per line. Each is run through the full pipeline and results are merged and de-duplicated by place. Example: [\"dentists in Miami\", \"orthodontists in Miami\", \"dental clinics Fort Lauderdale\"]. Leave empty to use the single Search Query above.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Google Maps Start URLs",
            "type": "array",
            "description": "Scrape from Google Maps URLs (best-effort). A PLACE url (with a place feature id) fetches that single business. A SEARCH url (e.g. .../maps/search/...) re-runs that query. URLs that can't be parsed are skipped with a warning. Accepts plain URLs or {\"url\": \"...\"} objects.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "customGeolocation": {
            "title": "Custom Geolocation (coordinates / radius / polygon)",
            "type": "object",
            "description": "Search an EXACT area without geocoding a place name. Provide either a point + radius: {\"lat\": 40.7128, \"lng\": -74.006, \"radiusMeters\": 3000}, or a GeoJSON geometry: {\"type\": \"Polygon\", \"coordinates\": [[[lng,lat],...]]} (Polygon, MultiPolygon or Point supported). The search category comes from the Search Query field above. The area's bounding box is gridded directly."
          },
          "maxResults": {
            "title": "Max Results",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "Maximum number of businesses to extract. Set to 0 for unlimited (collect everything found).",
            "default": 100
          },
          "language": {
            "title": "Language",
            "type": "string",
            "description": "Two-letter language code for result text, e.g. en, es, fr, de, it, pt, ja.",
            "default": "en"
          },
          "zoom": {
            "title": "Zoom Level",
            "minimum": 1,
            "maximum": 21,
            "type": "integer",
            "description": "Google Maps zoom level (1-21). Lower values cover a larger area with less detail; higher values cover a smaller area with more detail. 13 is a good default for city-level searches.",
            "default": 13
          },
          "includeDetails": {
            "title": "Include Place Details",
            "type": "boolean",
            "description": "Fetch detailed info for each business (hours, phone, website, amenities). Slower but more complete.",
            "default": true
          },
          "includePhotos": {
            "title": "Include Photos",
            "type": "boolean",
            "description": "Add a 'photos' array of up to 10 business photo URLs (from the place-details response). Requires 'Include Place Details' to be on.",
            "default": true
          },
          "includePlaceExtras": {
            "title": "Include Amenities, Plus Code & Closed Status",
            "type": "boolean",
            "description": "Add 'amenities' (attribute strings), 'plus_code' (Google Plus Code) and 'permanently_closed' (boolean). Best-effort — fields are null when not present in Google's response. Requires 'Include Place Details'.",
            "default": true
          },
          "includePopularTimes": {
            "title": "Include Popular Times (experimental)",
            "type": "boolean",
            "description": "EXPERIMENTAL / rarely available. Attempts to extract the weekly 'popular_times' busy histogram. Google's HTTP place endpoint almost never includes this data (it is normally loaded by a separate browser-only request), so in practice 'popular_times' is null for virtually all places. Kept for forward-compatibility; do not rely on it. Off by default. Requires 'Include Place Details'.",
            "default": false
          },
          "includeReviews": {
            "title": "Include Reviews",
            "type": "boolean",
            "description": "Fetch reviews for each business. Increases run time and cost.",
            "default": false
          },
          "reviewsLimit": {
            "title": "Reviews per Business",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Maximum number of reviews to fetch per business (only used when Include Reviews is enabled).",
            "default": 5
          },
          "minReviewRating": {
            "title": "Minimum Review Rating",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Keep only reviews rated at or above this many stars (1-5). Applied after fetching. 0 = keep all ratings (off). Reviews with no rating are always kept.",
            "default": 0
          },
          "reviewKeyword": {
            "title": "Review Keyword Filter",
            "type": "string",
            "description": "Keep only reviews whose text contains this phrase (case-insensitive substring). Applied after fetching. Leave empty to keep all reviews. Example: 'refund', 'rude', 'clean'.",
            "default": ""
          },
          "reviewsSort": {
            "title": "Review Sort Order",
            "enum": [
              "newest",
              "relevant"
            ],
            "type": "string",
            "description": "Review ordering. Reviews are returned in Google's default order, which is 'Most relevant' first. Note: Google's HTTP review endpoint does not reliably expose a separate strict-newest ordering, so both options currently return the most-relevant order.",
            "default": "newest"
          },
          "includeEmails": {
            "title": "Find Email Addresses (experimental add-on)",
            "type": "boolean",
            "description": "EXPERIMENTAL / BETA. Optional lead-enrichment add-on. Visits each business website (plus its contact / about / imprint pages) and extracts email addresses. Adds run time and is billed separately, per enriched lead. Off by default — the base scraper is unaffected.",
            "default": false
          },
          "includeSocials": {
            "title": "Find Social Media Profiles (experimental add-on)",
            "type": "boolean",
            "description": "EXPERIMENTAL / BETA. Optional lead-enrichment add-on. Extracts social profile links (Facebook, Instagram, LinkedIn, X/Twitter, YouTube, TikTok, WhatsApp) from each business website. Adds run time and is billed separately, per enriched lead. Off by default.",
            "default": false
          },
          "emailOnly": {
            "title": "Only Keep Businesses With an Email",
            "type": "boolean",
            "description": "Filter: only output businesses for which at least one email address was found. Automatically enables email finding.",
            "default": false
          },
          "socialOnly": {
            "title": "Only Keep Businesses With a Social Profile",
            "type": "boolean",
            "description": "Filter: only output businesses for which at least one social profile was found. Automatically enables social profile finding.",
            "default": false
          },
          "onlyWithWebsite": {
            "title": "Only Keep Businesses With a Website",
            "type": "boolean",
            "description": "Filter: only output businesses that have a real website (excludes those with only a social page, a directory listing, or no site at all).",
            "default": false
          },
          "onlyWithoutWebsite": {
            "title": "Only Keep Businesses Without a Website",
            "type": "boolean",
            "description": "Filter: only output businesses that do NOT have a real website — prime prospects for web-design and digital agencies.",
            "default": false
          },
          "maxPagesPerSite": {
            "title": "Max Pages per Website (advanced)",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Advanced: max pages to crawl on each business website during lead/people enrichment (home + contact/about/team pages). Higher finds more contacts but is slower. Defaults to 4 (auto-raised to 6 when 'Find People / Contacts' is on)."
          },
          "includePersonnel": {
            "title": "Find People / Contacts (experimental add-on)",
            "type": "boolean",
            "description": "EXPERIMENTAL / BETA. Optional lead-enrichment add-on. Visits each business website and extracts the PEOPLE who work there — name, title, and their own email / phone / LinkedIn where published — as a 'contacts' list, plus a structured 'business_lead'. Only the business's own site is used. Off by default.",
            "default": false
          },
          "maxContactsPerBusiness": {
            "title": "Max Contacts per Business",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Maximum personnel contacts to output per business (highest-confidence first). Only used when 'Find People / Contacts' is enabled.",
            "default": 10
          },
          "personnelMinConfidence": {
            "title": "Minimum Contact Confidence",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "type": "string",
            "description": "Drop personnel contacts below this confidence tier. 'low' keeps everything (recall-first); raise to 'medium' or 'high' for precision. Only used when 'Find People / Contacts' is enabled.",
            "default": "low"
          },
          "onlyWithPersonnel": {
            "title": "Only Keep Businesses With a Contact",
            "type": "boolean",
            "description": "Filter: only output businesses for which at least one personnel contact was found. Automatically enables 'Find People / Contacts'.",
            "default": false
          },
          "includeMetaAds": {
            "title": "Find Meta (Facebook / Instagram) Ads (experimental add-on)",
            "type": "boolean",
            "description": "EXPERIMENTAL / BETA. Ad-intelligence add-on. Checks the public Meta Ad Library (https://www.facebook.com/ads/library) for each business and reports whether they are actively running ads on Facebook / Instagram — plus the active-ad count and a few sample creatives (call-to-action, landing page, ad copy). A strong buy signal for agencies. Matches conservatively on the business's Facebook page / website domain / name, so unrelated advertisers are not falsely attributed. Adds run time, uses residential proxy, billed separately per matched advertiser. Off by default.",
            "default": false
          },
          "includeGoogleAds": {
            "title": "Find Google Ads (experimental add-on)",
            "type": "boolean",
            "description": "EXPERIMENTAL / BETA. Ad-intelligence add-on. Checks the public Google Ads Transparency Center (https://adstransparency.google.com) for each business website and reports whether they are actively running ads on Google — Search, YouTube and Display — plus the advertiser name, ad count, when ads were last shown, and sample creatives. Matched exactly on the business's own website domain, so attribution is precise. Adds run time, billed separately per matched advertiser. Off by default.",
            "default": false
          },
          "onlyRunningAds": {
            "title": "Only Keep Businesses Currently Running Ads",
            "type": "boolean",
            "description": "Filter: only output businesses that are actively running ads. If neither 'Find Meta Ads' nor 'Find Google Ads' is selected, both are checked; otherwise only the selected source(s). Keeps any business currently advertising on an enabled platform.",
            "default": false
          },
          "adCountry": {
            "title": "Ad Library Country",
            "type": "string",
            "description": "Two-letter ISO country code for the ad lookups (where the ads are shown), e.g. US, GB, DE. Applies to both the Meta Ad Library search and the Google Ads Transparency Center region. Defaults to US. Used when an ad-intelligence add-on is enabled.",
            "default": "US"
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Required for reliable results. Google blocks datacenter IPs on Maps search, so this defaults to Apify Residential proxy. Leave as-is unless you know what you're doing.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          },
          "proxyUrl": {
            "title": "Custom proxy URL (advanced, optional)",
            "type": "string",
            "description": "Optional. A single HTTP proxy URL (http://user:pass@host:port) to use INSTEAD of Apify Proxy above. Leave empty to use the Proxy configuration."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}