{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Maps Rank Tracker | Geo-Grid Heatmap & Competitors",
    "description": "Track where a business ranks on Google Maps at every point of a geo-grid (3×3 to 15×15). Competitors are ranked on the same scans at no extra cost. Average rank, share of local voice, top-3 share, top-10 competitor leaderboard, heatmap PNG, HTML report and change since your last scan.",
    "version": "0.1",
    "x-build-id": "Le0GUXCzndFmme5SG"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/corvuslab~google-maps-geo-grid-rank-tracker/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-corvuslab-google-maps-geo-grid-rank-tracker",
        "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/corvuslab~google-maps-geo-grid-rank-tracker/runs": {
      "post": {
        "operationId": "runs-sync-corvuslab-google-maps-geo-grid-rank-tracker",
        "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/corvuslab~google-maps-geo-grid-rank-tracker/run-sync": {
      "post": {
        "operationId": "run-sync-corvuslab-google-maps-geo-grid-rank-tracker",
        "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": {
          "businessName": {
            "title": "🏪 Business",
            "type": "string",
            "description": "The business to track: its name as it appears on Google Maps, its Google Maps link, its place ID (ChIJ…) or its CID. A link or place ID is always an exact match. The grid is centred on this business."
          },
          "keywords": {
            "title": "🔑 Search keywords",
            "type": "array",
            "description": "What customers type into Google Maps. One per line, up to 25. Each keyword is scanned across the whole grid.",
            "items": {
              "type": "string"
            }
          },
          "location": {
            "title": "🏙️ City or area",
            "type": "string",
            "description": "City, state or neighbourhood the business is in. Used to find the right business when you type a name. Not needed with a link, place ID or CID."
          },
          "businesses": {
            "title": "🆚 Competitors and more businesses",
            "type": "array",
            "description": "More businesses to rank on the same grid: competitors, or your client's other listings. Names, Google Maps links, place IDs or CIDs, one per line, up to 19. They are read from the same searches, so they add no scans and no cost.",
            "items": {
              "type": "string"
            }
          },
          "matchAllBranches": {
            "title": "Count any branch of a brand",
            "type": "boolean",
            "description": "Off: one exact listing is tracked. On: a point counts the first listing whose name matches (e.g. any 'Starbucks'), for brands with many branches.",
            "default": false
          },
          "gridSize": {
            "title": "Grid size",
            "minimum": 3,
            "maximum": 15,
            "type": "integer",
            "description": "Points per side. 5 means a 5 × 5 grid of 25 points; 7 means 49. Each point × keyword is one scan.",
            "default": 5
          },
          "radiusMiles": {
            "title": "Scan radius (miles)",
            "minimum": 0.25,
            "maximum": 25,
            "type": "number",
            "description": "How far the grid reaches from the centre in each direction, in miles. 2 covers a typical town; use more for a whole metro.",
            "default": 2
          },
          "radiusKm": {
            "title": "Scan radius (km)",
            "minimum": 0.4,
            "maximum": 40,
            "type": "number",
            "description": "The same radius in kilometres. When set, it replaces the radius in miles."
          },
          "gridShape": {
            "title": "Grid shape",
            "enum": [
              "square",
              "circle"
            ],
            "type": "string",
            "description": "A circle grid keeps only the points within the radius, so a 7 × 7 grid scans 29 points instead of 49.",
            "default": "square"
          },
          "separateGrids": {
            "title": "One grid per business",
            "type": "boolean",
            "description": "Off: one grid around the first business, every business ranked on it (no extra cost). On: each business gets its own grid centred on it, for agencies scanning several clients in one run.",
            "default": false
          },
          "centerLat": {
            "title": "Centre latitude (optional)",
            "type": "number",
            "description": "Centre the grid here instead of on the business. Set together with the centre longitude."
          },
          "centerLng": {
            "title": "Centre longitude (optional)",
            "type": "number",
            "description": "Set together with the centre latitude."
          },
          "zoom": {
            "title": "Map zoom",
            "minimum": 8,
            "maximum": 18,
            "type": "integer",
            "description": "The Google Maps zoom level each point is searched at. Higher zoom = a closer view, so ranks change faster from point to point.",
            "default": 13
          },
          "maxRank": {
            "title": "Deepest rank to check",
            "minimum": 1,
            "maximum": 60,
            "type": "integer",
            "description": "Positions past this count as not ranked. Up to 60.",
            "default": 20
          },
          "placeId": {
            "title": "Place ID of the business (optional)",
            "type": "string",
            "description": "If the business name has look-alikes nearby, add its place ID here and the name lookup picks exactly that listing."
          },
          "language": {
            "title": "Language",
            "type": "string",
            "description": "Language of the searches, as a 2-letter code (e.g. 'de', 'es'). Use the language your customers search in.",
            "default": "en"
          },
          "countryCode": {
            "title": "Country",
            "type": "string",
            "description": "2-letter country code of the searches (e.g. 'us', 'gb', 'de'). Leave empty to use the business's own country."
          },
          "compareWithPrevious": {
            "title": "Compare with the previous scan",
            "type": "boolean",
            "description": "Adds each point's previous rank and the change in average rank, share of voice and top-3 share since the last scan of the same business, keyword and grid. Schedule this actor to track progress week by week.",
            "default": true
          },
          "historyKey": {
            "title": "History name",
            "type": "string",
            "description": "Optional. Keeps a separate scan history under this name (e.g. one per client)."
          },
          "includePointRows": {
            "title": "Include one row per grid point",
            "type": "boolean",
            "description": "On: adds one row per grid point (rank, top 3 there, previous rank, a Google Maps link) next to the summary rows. Off: one summary row per business × keyword, which already holds the rank at every point in its rank grid.",
            "default": false
          },
          "generateHeatmaps": {
            "title": "Create heatmap images and the HTML report",
            "type": "boolean",
            "description": "Saves a PNG heatmap per business × keyword and one shareable HTML report for the run. Links are in each summary row.",
            "default": true
          },
          "notifyOn": {
            "title": "Send a notification",
            "enum": [
              "always",
              "changes",
              "drops"
            ],
            "type": "string",
            "description": "When to message the channels below. Nothing is sent unless a channel is filled in.",
            "default": "always"
          },
          "dropThreshold": {
            "title": "Drop alert threshold (positions)",
            "minimum": 0.1,
            "type": "number",
            "description": "With 'only when rankings dropped': alert when the average rank worsens by at least this many positions (or the top-3 share falls by 10 points, or the business disappears).",
            "default": 1
          },
          "telegramToken": {
            "title": "🔑 Telegram bot token",
            "type": "string",
            "description": "Telegram bot token (from @BotFather)."
          },
          "telegramChatId": {
            "title": "💬 Telegram chat ID",
            "type": "string",
            "description": "Telegram chat or channel ID. Required when a Telegram token is set."
          },
          "slackWebhookUrl": {
            "title": "💼 Slack webhook URL",
            "type": "string",
            "description": "Slack incoming webhook URL."
          },
          "discordWebhookUrl": {
            "title": "🎮 Discord webhook URL",
            "type": "string",
            "description": "Discord incoming webhook URL."
          },
          "whatsappAccessToken": {
            "title": "📱 WhatsApp access token",
            "type": "string",
            "description": "WhatsApp Cloud API access token. The recipient must have messaged your business number within the last 24h."
          },
          "whatsappPhoneNumberId": {
            "title": "📞 WhatsApp phone number ID",
            "type": "string",
            "description": "Your WhatsApp Business phone-number ID. Required when a WhatsApp token is set."
          },
          "whatsappTo": {
            "title": "📲 WhatsApp recipient",
            "type": "string",
            "description": "Recipient phone in E.164 format without + (e.g. \"15125550100\"). Separate several with commas."
          },
          "webhookUrl": {
            "title": "🪝 Webhook URL",
            "type": "string",
            "description": "Receives a JSON POST with every summary row and the report link after the scan (n8n / Make / Zapier / your own app)."
          },
          "webhookHeaders": {
            "title": "📋 Webhook headers",
            "type": "object",
            "description": "Optional JSON object of custom headers (e.g. {\"Authorization\":\"Bearer ...\"})."
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Leave empty: the actor picks the network itself so every grid point is searched as a local customer would see it. Set it only if your runs report that points could not be read."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}