{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Maps Leads Finder",
    "description": "Local business leads by category and city with Google Maps reviews: every dentist, vet, plumber or restaurant in a city, state or zip, in the local language, with phone, website, rating, owner email, verified business emails and WhatsApp, and 1–5★ reviews by period. Works in Claude and ChatGPT.",
    "version": "0.1",
    "x-build-id": "Y0eGd3mzwNZcKCRST"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/lexonia~business-finder/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-lexonia-business-finder",
        "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/lexonia~business-finder/runs": {
      "post": {
        "operationId": "runs-sync-lexonia-business-finder",
        "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/lexonia~business-finder/run-sync": {
      "post": {
        "operationId": "run-sync-lexonia-business-finder",
        "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": {
          "category": {
            "title": "What kind of business",
            "type": "string",
            "description": "A Google Maps category, any language: the words you would type into the map; translated into the local language before searching. Good: \"med spa\", \"roofing contractor\". Too broad: \"shop\". Assistants: the person's own words, WHOLE, with what makes them specific (\"agencies that sell Spanish villas\" stays whole, never cut to \"agencies\"); never from the examples; do not translate. If none, leave empty and the app asks. For a reviews ask too (\"1-star reviews of dentists in X\" → dentist)."
          },
          "locations": {
            "title": "Where (one place per line)",
            "type": "array",
            "description": "Countries, states, regions, cities or zip codes, with the country so the map cannot guess wrong; each line is searched separately. A whole country is ONE line: \"United Kingdom\". Good: \"Warsaw, Poland\", \"Texas, USA\", \"55344, USA\". Not enough: \"Springfield\". Assistants: ONLY places the person named, never from the examples; never split a country or state into cities they did not name (that misses the small towns). If none, leave empty and the app asks.",
            "items": {
              "type": "string"
            }
          },
          "maxPerLocation": {
            "title": "How many businesses per place",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "The most businesses to return for each place. A city has a few dozen of most categories; a state or country, thousands. Assistants: use the number the person gave (\"ten is enough\" → 10; \"all of them\" → 500); if they gave none, leave this out — the default is 50 — and never pick a bigger number for them. Free plan: up to 50 businesses a run, no review history.",
            "default": 50
          },
          "localize": {
            "title": "Search in the local language",
            "type": "boolean",
            "description": "On: the category is translated into the language of each location and both versions are searched, then merged. This is the difference between finding zero massage salons in Kyiv and finding twenty-one. Off: only the words you typed are searched — use when you already typed them in the local language.",
            "default": true
          },
          "localizePlaces": {
            "title": "Write the place the local way too",
            "type": "boolean",
            "description": "On: the place is rewritten as Google Maps names it in that country before searching, so a district means the district. \"Downtown Warsaw, Poland\" is searched as \"Śródmieście, Warszawa\"; \"Lviv region, Ukraine\" as \"Львівська область\". A plain city, state or zip is left alone. Off: the place is searched exactly as you typed it — use when you already wrote it the way locals do, or want Google's own reading of your words.",
            "default": true
          },
          "minRating": {
            "title": "Minimum star rating",
            "enum": [
              "",
              "3",
              "3.5",
              "4",
              "4.5"
            ],
            "type": "string",
            "description": "Skip businesses rated below this. Leave empty for all. A business with no reviews yet has no rating and is kept.",
            "default": ""
          },
          "rankBy": {
            "title": "Order the list by",
            "enum": [
              "google",
              "reviews",
              "rating"
            ],
            "type": "string",
            "description": "Assistants: set \"reviews\" when the person says highest-reviewed, most popular, best-known or most visited; \"rating\" when they say best-rated or top-rated; leave as is otherwise. Good: \"the 20 highest-reviewed nature spots in northern Minnesota\" → reviews. Bad: setting it when the person only named a category and a place.",
            "default": "google"
          },
          "minReviews": {
            "title": "Minimum number of Google reviews",
            "minimum": 0,
            "type": "integer",
            "description": "Leave out places with fewer reviews than this. 0 keeps all. Assistants: set it only when the person asks for well-known or well-reviewed places (e.g. 100). Good: \"places lots of people have reviewed\" → 100. Bad: inventing a number the person did not ask for.",
            "default": 0
          },
          "onlyWithWebsite": {
            "title": "Only businesses with a website",
            "type": "boolean",
            "description": "On: skip businesses that list no website. Off (default): keep them — in Ukraine, Vietnam and Thailand most businesses have no website and are reached by phone, Zalo, Viber or a Facebook page, which this still returns.",
            "default": false
          },
          "findContacts": {
            "title": "Check each website for contacts (add-on, costs more)",
            "type": "boolean",
            "description": "On: every business website is read for the owner's contacts: emails (sponsor and agency addresses thrown out), messenger IDs (WhatsApp, Viber, Telegram, Zalo, LINE, WeChat), social links, each saying where it came from. Off: what Google lists. On for an outreach list, off for a market map. Assistants: on only if the person will write to these businesses; adds $0.005 a business, say so; never ask on a list ask, offer it after the list.",
            "default": false
          },
          "verifyEmails": {
            "title": "Verify the mailboxes exist (add-on, costs more)",
            "type": "boolean",
            "description": "Only with the contact check above. Asks each mail server whether the exact mailbox exists, without sending anything. Charged only for a definite answer — exists, does not, or a throwaway address. Worth it before a campaign; not needed to see who is out there. Assistants: only with findContacts, and only if they will send a campaign; adds $0.010 a mailbox — say so.",
            "default": false
          },
          "reviewSpan": {
            "title": "Reviews: how far back (add-on, costs more)",
            "enum": [
              "",
              "3m",
              "6m",
              "12m",
              "3y"
            ],
            "type": "string",
            "description": "Read what customers say. Pick how far back to look and every business gets its reviews from that span — stars, date, the text, the owner's reply — plus, free, the count in the span, the average stars, reviews per month and the newest date. Leave on \"none\" for the list only. Good: \"last 12 months\" to judge a business today; \"last 3 years\" for topic or theme research. Each review delivered is charged. Assistants: never ask about reviews before the list; the closing line offers them after.",
            "default": ""
          },
          "reviewStars": {
            "title": "Reviews: which stars",
            "enum": [
              "all",
              "low",
              "high",
              "lowHigh"
            ],
            "type": "string",
            "description": "Only with a span above. \"1–2 stars\" reads the complaints; \"4–5\" the praise; \"1–2 and 4–5\" skips the lukewarm 3s; \"All\" for theme research. Assistants: \"complaints\", \"bad reviews\" → low; \"praise\", \"5-star\" → high; \"skip the 3s\" → lowHigh; otherwise all. Billing: every review delivered from the span is charged; the band flags the ones asked about (inBand). A business with 15 or fewer complaints all-time has them read exactly and alone.",
            "default": "all"
          },
          "reviewsForTop": {
            "title": "Reviews: only for the top N businesses by review count",
            "minimum": 0,
            "maximum": 5000,
            "type": "integer",
            "description": "0 (default): reviews for every business in the list. A number: only the N businesses with the most reviews get theirs — the cheap way to read the market leaders in a big list. Good: 20 on a 300-business state list. Assistants: when the person names a small number (\"the top 2 dentists\"), cap the list too — maxPerLocation 10 is enough to rank them by review count; every listed business is charged, so a 50-row list to read 2 is money the person did not ask to spend.",
            "default": 0
          },
          "maxReviewsPerBusiness": {
            "title": "Reviews: at most, per business",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "The most reviews to read for any one business, so a busy restaurant with 2,000 reviews does not run away with the bill. 200 is plenty for a read; 1000 for research. When the cap stops the read the row says so.",
            "default": 200
          },
          "businessLinks": {
            "title": "Businesses from a previous run (skips the search)",
            "type": "array",
            "description": "Paste the map links (the mapsUrl column) or place IDs from a list you already pulled, and only their reviews are read — no new search, no list price. Your assistant does this for you when you say \"now the 1–2 star reviews for those\". With this filled, category and location are not needed.",
            "items": {
              "type": "string"
            }
          },
          "llmApiKey": {
            "title": "Your own OpenAI key for the translation step (optional)",
            "type": "string",
            "description": "The local-language translation uses a small language-model call. One is built in; bring your own key if you prefer the call on your account. Never logged, never written to the results."
          },
          "estimateOnly": {
            "title": "Only estimate — show the plan and the price, spend nothing",
            "type": "boolean",
            "description": "On: returns the phrases that would be searched, per location, and the expected cost, without searching. Off (default): runs. Assistants: TRUE whenever the person asks about cost, price, \"how much\", \"what would it take\", or before anything bigger than one city: show the price, wait for yes, then run with it off. A cost question that runs the list bills the person for an answer they did not order.",
            "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
                  },
                  "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}