{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Maps Places Extractor",
    "description": "Extract Places and businesses from Google Maps.  Scrap phone numbers, emails, website, business hours,  address and gps, Google Place ID. Use filters to include or exclude irrelevant leads.",
    "version": "0.0",
    "x-build-id": "eMQ6hNsS3vcQ8e9kZ"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/enckay~google-maps-places-extractor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-enckay-google-maps-places-extractor",
        "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/enckay~google-maps-places-extractor/runs": {
      "post": {
        "operationId": "runs-sync-enckay-google-maps-places-extractor",
        "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/enckay~google-maps-places-extractor/run-sync": {
      "post": {
        "operationId": "run-sync-enckay-google-maps-places-extractor",
        "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",
        "required": [
          "location"
        ],
        "properties": {
          "keywords": {
            "title": "Search Keywords",
            "type": "array",
            "description": "Keywords to search for (e.g., 'restaurants', 'dentists', 'coffee shops'). Each line is considered as 1 keyword search term. For multiple search terms, add multiple lines.\n\nIn dense areas like Manhattan, Google Maps only surfaces popular places, capping results at around 150 per search. Expanding into similar niches within the same business domain helps surface less popular, long-tail places that wouldn't otherwise appear. E.g., for restaurant coverage, use multiple niche names or cuisines to increase coverage (`[\"restaurant\", \"pizza restaurant\",\"sushi restaurant\", \"italian restaurant\"]`).\n\nAvoid overusing this, as each additional keyword multiplies the total scrape time.\n\nTakes precedence over the legacy \"keyword\" field if both are provided.",
            "items": {
              "type": "string"
            }
          },
          "keyword": {
            "title": "Search Keyword (legacy)",
            "type": "string",
            "description": "Deprecated: use \"Search Keywords\" instead. A single search term. Ignored if \"keywords\" is also provided."
          },
          "location": {
            "title": "Location",
            "type": "string",
            "description": "City, address, or ZIP code to search in (e.g., 'Brooklyn, NY', 'Austin, TX', '90210'). Uses Google Maps or OpenStreetMap geocoding for worldwide coverage."
          },
          "maxResults": {
            "title": "Maximum Results",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum number of unique businesses to scrape. Set to 0 for unlimited results until results is exhausted.",
            "default": 0
          },
          "minRating": {
            "title": "Minimum Rating",
            "minimum": 0,
            "maximum": 5,
            "type": "number",
            "description": "Only include businesses with this rating or higher (0 = no filter)",
            "default": 0
          },
          "minReviews": {
            "title": "Minimum Reviews",
            "minimum": 0,
            "type": "integer",
            "description": "Only include businesses with at least this many reviews (0 = no filter)",
            "default": 0
          },
          "filterByPriceLevel": {
            "title": "Filter by Price Level",
            "uniqueItems": true,
            "type": "array",
            "description": "Filter by price level symbols (leave empty for no filter). Select multiple to include all matching levels. Note: This is not strict.",
            "items": {
              "type": "string",
              "enum": [
                "$",
                "$$",
                "$$$",
                "$$$$"
              ]
            }
          },
          "minPrice": {
            "title": "Minimum Price",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum price in dollars (e.g., 50 will filter out businesses cheaper than $50). 0 = no filter",
            "default": 0
          },
          "maxPrice": {
            "title": "Maximum Price",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum price in dollars (e.g., 100 will filter out businesses more expensive than $100). 0 = no filter",
            "default": 0
          },
          "filterTemporarilyClosed": {
            "title": "Exclude Temporarily Closed",
            "type": "boolean",
            "description": "Filter out businesses that are temporarily closed",
            "default": false
          },
          "filterPermanentlyClosed": {
            "title": "Exclude Permanently Closed",
            "type": "boolean",
            "description": "Filter out businesses that are permanently closed",
            "default": false
          },
          "extractContactDetails": {
            "title": "Contact Details (Phone + Email)",
            "type": "boolean",
            "description": "Extract phone number and email from Google profile. Extraction rate: 70-85% for phones, 20-40% for emails.",
            "default": false
          },
          "extractAmenities": {
            "title": "Amenities (82 fields)",
            "type": "boolean",
            "description": "Extract all 82 business amenities: seating, accessibility, parking, payments, food/beverage options from Google Maps data.",
            "default": false
          },
          "extractBusyness": {
            "title": "Hourly Busyness Data",
            "type": "boolean",
            "description": "Extract 7-day hourly busyness patterns (168 datapoints) with smart contact timing recommendations.",
            "default": false
          },
          "extractPriceDistribution": {
            "title": "Price Distribution",
            "type": "boolean",
            "description": "Extract customer spending patterns by price range with percentages.",
            "default": false
          },
          "extractAtmosphere": {
            "title": "Atmosphere Descriptors",
            "type": "boolean",
            "description": "Extract atmosphere/vibe descriptors (casual, cozy, hip, upscale, etc.).",
            "default": false
          },
          "extractPhotos": {
            "title": "Photos",
            "type": "boolean",
            "description": "Extract multiple photo URLs from Google Maps data.",
            "default": false
          },
          "maxPhotos": {
            "title": "Maximum Photos",
            "minimum": 1,
            "maximum": 50,
            "type": "integer",
            "description": "Maximum number of photo URLs to extract per business",
            "default": 10
          },
          "extractSocialMedia": {
            "title": "Social Media (from Google)",
            "type": "boolean",
            "description": "Extract social media profile URLs from Google Maps business profile (Facebook, Instagram, Twitter, LinkedIn, TikTok, YouTube).",
            "default": false
          },
          "extractSocialMediaFromWebsite": {
            "title": "Social Media (from Website)",
            "type": "boolean",
            "description": "Scrape business website to find social media links not in Google profile. Requires valid website URL.",
            "default": false
          },
          "socialMediaPlatforms": {
            "title": "Social Media Platforms",
            "uniqueItems": true,
            "type": "array",
            "description": "Which social media platforms to extract",
            "items": {
              "type": "string",
              "enum": [
                "facebook",
                "instagram",
                "twitter",
                "linkedin",
                "tiktok",
                "youtube"
              ]
            },
            "default": [
              "facebook",
              "instagram",
              "twitter",
              "linkedin",
              "tiktok",
              "youtube"
            ]
          },
          "extractWebsiteEmails": {
            "title": "Website Email Extraction",
            "type": "boolean",
            "description": "Visit business websites to extract email addresses from contact pages. Success rate: 60-80% (vs 20-40% from Google). Requires valid website URL.",
            "default": false
          },
          "websiteTimeout": {
            "title": "Website Scraping Timeout (ms)",
            "minimum": 1000,
            "maximum": 30000,
            "type": "integer",
            "description": "Timeout for website scraping requests in milliseconds",
            "default": 5000
          },
          "websiteMaxPages": {
            "title": "Max Pages per Website",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Maximum number of pages to scrape per website (home + contact + about)",
            "default": 3
          },
          "maxEmails": {
            "title": "Maximum Emails per Business",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Maximum number of email addresses to extract from website",
            "default": 5
          },
          "calculateLeadScore": {
            "title": "Lead Quality Scoring",
            "type": "boolean",
            "description": "Calculate lead quality score (0-100) and priority classification (PREMIUM/HIGH/MEDIUM/LOW) based on extracted data.",
            "default": false
          },
          "extractReviews": {
            "title": "Extract Reviews",
            "type": "boolean",
            "description": "Extract customer reviews  review text, ratings, dates, and reviewer info. Runs concurrently with cell processing for optimal performance.",
            "default": false
          },
          "maxReviewsPerBusiness": {
            "title": "Max Reviews per Business",
            "minimum": 10,
            "maximum": 500,
            "type": "integer",
            "description": "Maximum number of reviews to extract per business. Higher numbers take longer but provide more data. Recommended: 50-100.",
            "default": 100
          },
          "extractGeographic": {
            "title": "Geographic Hierarchy (NEW)",
            "type": "boolean",
            "description": "Extract multi-level geographic location data with confidence scores (neighborhood, city, county, state, region, country). Enabled by default. Adds: geographicHierarchy, primaryLocation, locationCategories fields.",
            "default": true
          },
          "extractCountry": {
            "title": "Country Code (NEW)",
            "type": "boolean",
            "description": "Extract ISO country code (e.g., 'US', 'GB', 'CA'). Enabled by default. Adds: countryCode field.",
            "default": true
          },
          "extractTravel": {
            "title": "Travel Time & Accessibility (NEW)",
            "type": "boolean",
            "description": "Extract travel time intervals and calculate accessibility score based on proximity metrics. Enabled by default. Adds: travelTimes, accessibility fields.",
            "default": true
          },
          "concurrency": {
            "title": "Cell Processing Concurrency",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Number of search cells to process in parallel (higher = faster but more resource intensive). Recommended: 2-5.",
            "default": 2
          },
          "detailsConcurrency": {
            "title": "Business Details Concurrency",
            "minimum": 1,
            "maximum": 50,
            "type": "integer",
            "description": "Number of concurrent business detail extractions. Higher = faster extraction but more resource intensive. Recommended: 5-15.",
            "default": 10
          },
          "customPolygon": {
            "title": "Custom Search Polygon",
            "type": "object",
            "description": "Advanced: Provide custom GeoJSON Polygon or MultiPolygon to define exact search boundaries. Overrides automatic location geocoding. Must be valid GeoJSON geometry with closed coordinates."
          },
          "webhookUrl": {
            "title": "Webhook URL",
            "type": "string",
            "description": "Stream scraped businesses in real-time to this URL. Each POST contains a batch of businesses plus run metadata (runId, batchNumber, keyword, location, cursor). Use runId to identify which run the data belongs to when sharing a single endpoint across multiple jobs."
          },
          "webhookBatchSize": {
            "title": "Webhook Batch Size",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Maximum number of businesses per webhook POST. 2 retries on failure; worker auto-stops after 3 consecutive unreachable batches.",
            "default": 25
          },
          "exportToCsv": {
            "title": "Export to CSV",
            "type": "boolean",
            "description": "Export results as CSV file in addition to JSON (CSV file will be saved in key-value store as 'OUTPUT')",
            "default": false
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}