{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Maps Business & Contact Scraper",
    "description": "Extract businesses from Google Maps by search term and location: name, address, phone, website, emails, social_links, rating, review_count, hours and coordinates. Emails and social profiles cost nothing extra. Export JSON, CSV or Excel.",
    "version": "2.0",
    "x-build-id": "mcQ08V4hRgVIXOJFH"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/herus13~google-maps-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-herus13-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/herus13~google-maps-scraper/runs": {
      "post": {
        "operationId": "runs-sync-herus13-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/herus13~google-maps-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-herus13-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",
        "required": [
          "searchStringsArray"
        ],
        "properties": {
          "searchStringsArray": {
            "title": "Search Queries",
            "type": "array",
            "description": "What to look for on Google Maps. Add one search term per entry, for example dentist, plumber or coffee shop. Every term is searched inside the place given in locationQuery, and every business found becomes one row. Required.",
            "items": {
              "type": "string"
            }
          },
          "locationQuery": {
            "title": "Location",
            "type": "string",
            "description": "Where to search, written the way you would type it into Google Maps: `Austin, TX`, `New York, USA`, `London, UK`, or a whole country. Leave empty to let each search term carry its own location."
          },
          "maxCrawledPlacesPerSearch": {
            "title": "Max Results Per Search",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Most businesses to return for each search term, from 1 to 500, counted after your filters. Default 100. The run keeps searching until it has this many matches or Google has no more results. Google shows about 120 businesses for a single map view, so a strict filter can return fewer — turn on geo_split to search a wider area.",
            "default": 100
          },
          "maxCrawledPlaces": {
            "title": "Max Places (total)",
            "minimum": 0,
            "type": "integer",
            "description": "Most businesses the whole run returns across all search terms together, counted after your filters. Default 0, which means no ceiling. You pay per business returned, so this caps your bill: 20 terms at 100 results each is 2,000 rows. The ceiling is shared out across your search terms, so every term gets a share instead of the first one using it all; a term that finds nothing hands its share back to the others.",
            "default": 0
          },
          "language": {
            "title": "Language",
            "enum": [
              "en",
              "es",
              "fr",
              "de",
              "it",
              "pt",
              "ja",
              "ko",
              "zh-CN",
              "zh-TW",
              "ar",
              "hi",
              "ru",
              "nl",
              "pl",
              "tr",
              "vi",
              "th",
              "id"
            ],
            "type": "string",
            "description": "Language of the Google Maps results and of the text inside each row. Default en. Supported codes: en, es, fr, de, it, pt, ja, ko, zh-CN, zh-TW, ar, hi, ru, nl, pl, tr, vi, th, id.",
            "default": "en"
          },
          "scrapeContacts": {
            "title": "Extract Emails & Social Links",
            "type": "boolean",
            "description": "Look up each business site and add the email addresses and social profile links it publishes to the row, as `emails`, `email_type` and `social_links`, plus `has_contact_form` when the site takes messages through a form instead of showing an address. Default true. These fields are part of the result price, so leaving this on costs nothing extra.",
            "default": true
          },
          "scrapeSocialMediaProfiles": {
            "title": "Social Media Profiles",
            "type": "object",
            "description": "Which social networks to collect from each business site. Default {\"facebooks\": true, \"instagrams\": true, \"youtubes\": true, \"tiktoks\": true, \"twitters\": true, \"linkedins\": true}; set a key to false to leave that network out. Has no effect while scrapeContacts is off.",
            "default": {
              "facebooks": true,
              "instagrams": true,
              "youtubes": true,
              "tiktoks": true,
              "twitters": true,
              "linkedins": true
            }
          },
          "scrapePlaceDetailPage": {
            "title": "Scrape Place Detail Page",
            "type": "boolean",
            "description": "Also open each business's own Google Maps page to fill in `hours`, `price_level` and any phone or site the search results left blank. Default false, because it makes a run noticeably longer. Emails and social profiles arrive without it.",
            "default": false
          },
          "maxReviews": {
            "title": "Max Reviews",
            "minimum": 0,
            "maximum": 500,
            "type": "integer",
            "description": "How many reviews to attach to each business, from 0 to 500. Default 0, which leaves reviews out. A business page carries roughly the first 8, so larger numbers return what that page holds. For a full review history use the Google Maps Reviews Scraper instead.",
            "default": 0
          },
          "reviewsSort": {
            "title": "Reviews Sort Order",
            "enum": [
              "newest",
              "mostRelevant",
              "highestRating",
              "lowestRating"
            ],
            "type": "string",
            "description": "Which reviews you get when maxReviews is above 0: newest for the most recent first, mostRelevant for Google's own ranking, highestRating for the best first, lowestRating for the worst first. Default newest.",
            "default": "newest"
          },
          "maxImages": {
            "title": "Max Images",
            "minimum": 0,
            "maximum": 50,
            "type": "integer",
            "description": "How many photo URLs to attach to each business, from 0 to 50. Default 0, which leaves images out.",
            "default": 0
          },
          "placeMinimumStars": {
            "title": "Minimum Rating",
            "enum": [
              "",
              "1",
              "2",
              "3",
              "4",
              "4.5"
            ],
            "type": "string",
            "description": "Keep only businesses rated at or above this many stars: 1, 2, 3, 4 or 4.5. Leave empty, the default, to keep every rating including businesses with no rating yet. Businesses this filter leaves out are not returned, not charged, and do not count toward your limits.",
            "default": ""
          },
          "skipClosedPlaces": {
            "title": "Skip Closed Places",
            "type": "boolean",
            "description": "Leave out businesses Google marks as permanently closed, so you do not pay for dead leads. Businesses this filter leaves out are not returned, not charged, and do not count toward your limits. Default true.",
            "default": true
          },
          "website": {
            "title": "Website Filter",
            "enum": [
              "allPlaces",
              "withWebsite",
              "withoutWebsite"
            ],
            "type": "string",
            "description": "Filter on whether the business has its own website: allPlaces keeps every business, withWebsite keeps only those that have one, withoutWebsite keeps only those that do not. A Facebook, Instagram, X, LinkedIn, YouTube or TikTok page is not a website: it arrives in `social_links` and the business counts as having no website. Businesses this filter leaves out are not returned, not charged, and do not count toward your limits. Default allPlaces.",
            "default": "allPlaces"
          },
          "geo_split": {
            "title": "Auto Geographic Splitting",
            "type": "boolean",
            "description": "Cover a large area by splitting it into a grid and searching each cell, which gets you past the roughly 120 businesses Google returns for one map view. Default false. Turn it on for anything wider than a single city.",
            "default": false
          },
          "geo_split_max_cells": {
            "title": "Max Grid Cells",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Upper bound on how many grid cells geo_split may use, from 1 to 500. Default 100. A wider area uses bigger cells to stay inside this bound.",
            "default": 100
          },
          "max_requests_per_minute": {
            "title": "Max Requests Per Minute",
            "minimum": 10,
            "maximum": 120,
            "type": "integer",
            "description": "Ceiling on how many requests the run sends per minute, from 10 to 120. Default 60. Lower it to be gentler on a long run, raise it to finish sooner.",
            "default": 60
          },
          "max_concurrency": {
            "title": "Max Concurrency",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many businesses are enriched at the same time, from 1 to 10. Default 10. Lower it for a gentler run; max_requests_per_minute still caps how fast requests go out.",
            "default": 10
          },
          "request_delay": {
            "title": "Request Delay (seconds)",
            "minimum": 0,
            "type": "integer",
            "description": "Extra seconds to wait between requests, on top of the per-minute ceiling. Default 0, which adds no wait at all.",
            "default": 0
          },
          "cache_provider": {
            "title": "Cache Provider",
            "enum": [
              "memory",
              "file",
              "apify"
            ],
            "type": "string",
            "description": "Where the run keeps the business data it has already collected, so the same place is not collected twice: memory for the run's own memory, file for the run's disk, apify for an Apify key-value store. Default memory.",
            "default": "memory"
          },
          "cache_ttl_seconds": {
            "title": "Cache TTL (seconds)",
            "minimum": 60,
            "maximum": 604800,
            "type": "integer",
            "description": "How long kept business data stays usable before it is collected again, in seconds, from 60 to 604800 (seven days). Default 86400, which is 24 hours.",
            "default": 86400
          },
          "proxyUrls": {
            "title": "Your own proxy URLs (optional)",
            "type": "array",
            "description": "Leave empty and the run uses a residential proxy that is included in the price of the run. To route through your own account instead, add one gateway URL per entry, for example http://user:pass@host:port. Works with DataImpulse, Bright Data, Oxylabs, Smartproxy or any provider that issues URLs. When you set this, only these URLs are used.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}