{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Search Results Scraper",
    "description": "Scrape Google Search result pages (SERPs) and extract structured data: organic results, paid ads, related queries, and People Also Ask. Supports country/language targeting, time filters, pagination, and CSV-friendly output.",
    "version": "1.0",
    "x-build-id": "nDmW0BLJ6lEgRaqm9"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/crawlerbros~google-search-results-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-crawlerbros-google-search-results-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/crawlerbros~google-search-results-scraper/runs": {
      "post": {
        "operationId": "runs-sync-crawlerbros-google-search-results-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/crawlerbros~google-search-results-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-crawlerbros-google-search-results-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": [
          "queries"
        ],
        "properties": {
          "queries": {
            "title": "Search Queries",
            "minItems": 1,
            "type": "array",
            "description": "List of Google Search queries. Each query will be searched separately and results combined in the output. Blank/whitespace-only entries are dropped before searching (a warning is logged with the count).",
            "items": {
              "type": "string"
            }
          },
          "maxResults": {
            "title": "Max Results Per Query",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Maximum number of organic results to return per search query.",
            "default": 100
          },
          "countryCode": {
            "title": "Country",
            "enum": [
              "",
              "us",
              "uk",
              "ca",
              "au",
              "de",
              "fr",
              "es",
              "it",
              "br",
              "mx",
              "in",
              "jp",
              "kr",
              "nl",
              "be",
              "at",
              "ch",
              "se",
              "no",
              "dk",
              "fi",
              "pl",
              "cz",
              "pt",
              "ie",
              "nz",
              "za",
              "sg",
              "hk",
              "tw",
              "ph",
              "th",
              "id",
              "my",
              "vn",
              "ar",
              "cl",
              "co",
              "pe",
              "tr",
              "ru",
              "ua",
              "il",
              "ae",
              "sa",
              "eg",
              "ng",
              "ke"
            ],
            "type": "string",
            "description": "Country for the search. Determines the Google domain and the searcher-location (gl) signal sent to Google, and is also used to steer the automatic GOOGLE_SERP/RESIDENTIAL proxy chain toward an exit IP in that country (skipped only if you set a custom Proxy configuration below). Leave empty for US (google.com); if Precise Location (uule) is set and this is left empty, the country is instead derived from the uule value itself.",
            "default": ""
          },
          "restrictResultsCountry": {
            "title": "Restrict results to country (cr)",
            "enum": [
              "",
              "us",
              "uk",
              "ca",
              "au",
              "de",
              "fr",
              "es",
              "it",
              "br",
              "mx",
              "in",
              "jp",
              "kr",
              "nl",
              "be",
              "at",
              "ch",
              "se",
              "no",
              "dk",
              "fi",
              "pl",
              "cz",
              "pt",
              "ie",
              "nz",
              "za",
              "sg",
              "hk",
              "tw",
              "ph",
              "th",
              "id",
              "my",
              "vn",
              "ar",
              "cl",
              "co",
              "pe",
              "tr",
              "ru",
              "ua",
              "il",
              "ae",
              "sa",
              "eg",
              "ng",
              "ke"
            ],
            "type": "string",
            "description": "Only return pages whose content originates from/targets this country (Google's cr parameter). This is different from Country above (which only sets the searcher's location/gl and the Google domain) - e.g. set this to Germany to only get results from German sites regardless of which Google domain or Country is used above. Leave empty for no restriction.",
            "default": ""
          },
          "languageCode": {
            "title": "Language",
            "type": "string",
            "description": "Language for the Google interface/UI itself (hl parameter). E.g. 'en', 'de', 'fr', 'es'. Leave empty for default. This does NOT restrict which language the matched pages are written in - use 'Restrict results language' for that.",
            "default": ""
          },
          "restrictResultsLanguage": {
            "title": "Restrict results language (lr)",
            "type": "string",
            "description": "Only return results for pages written in this language, regardless of the UI language above (Google's 'lr' parameter). Enter a bare language code like 'en' or 'de'. To match documents in any of several languages, separate codes with a comma, e.g. 'en,fr' (sent to Google as an OR: lang_en|lang_fr). Leave empty for no restriction.",
            "default": ""
          },
          "maxPagesPerQuery": {
            "title": "Max Pages Per Query",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Maximum number of search result pages to crawl per query. More pages means more results but slower execution.",
            "default": 1
          },
          "resultsPerPage": {
            "title": "Results Per Page",
            "minimum": 10,
            "maximum": 100,
            "type": "integer",
            "description": "Number of results per page (Google 'num' parameter). Allowed values: 10, 20, 30, 40, 50, 100. Google has largely stopped honoring this for organic results since late 2023 and typically still returns roughly 7-10 organic results per page fetch regardless of this setting - use Max Pages Per Query to fetch more results instead.",
            "default": 10
          },
          "timePeriod": {
            "title": "Time Period",
            "enum": [
              "",
              "hour",
              "day",
              "week",
              "month",
              "year"
            ],
            "type": "string",
            "description": "Filter results by time period. Leave empty for any time.",
            "default": ""
          },
          "safeSearch": {
            "title": "SafeSearch filter",
            "enum": [
              "",
              "active",
              "off"
            ],
            "type": "string",
            "description": "Filter explicit content from results (Google's safe= parameter). Leave empty for the account/default setting.",
            "default": ""
          },
          "mobileResults": {
            "title": "Mobile Results",
            "type": "boolean",
            "description": "If enabled, returns results for the mobile version of Google Search. Desktop results are returned by default.",
            "default": false
          },
          "forceAiOverviewCapture": {
            "title": "Force AI Overview capture (slower)",
            "type": "boolean",
            "description": "If enabled, forces every fetch into a slower, JavaScript-rendering mode and waits specifically for Google's AI Overview to finish loading, so 'aiOverview' can actually populate. By default the actor uses a fast fetch mode that never runs Google's JavaScript, so 'aiOverview' is almost always null regardless of whether Google shows one for your query - leaving this off means you should not expect AI Overview data. Turning it on makes each request noticeably slower and more resource-intensive, and it is still not a guarantee: Google may genuinely not render an AI Overview for a given query. For best results with this option, set Proxy Configuration to the Web Unblocker group. If that fetch fails, the actor falls back to the default fetch mode so other results are still returned, with 'aiOverview' left null.",
            "default": false
          },
          "csvFriendlyOutput": {
            "title": "CSV Friendly Output (1 result per row)",
            "type": "boolean",
            "description": "If enabled, outputs one organic/paid result per row instead of one SERP page per row. Suitable for CSV/Excel export. This is a lossy reshape: organic rows carry query, page, type, position, title, url, displayedUrl, snippet, siteLinks; paid rows carry query, page, type, title, url. AI Overview, knowledge panel, People Also Ask, related queries, local pack, top stories, sports table, and all opt-in extra boxes (weather, time zone, currency/unit converter, jobs, videos, shopping) are NOT included in any row - use the default JSON output if you need that data.",
            "default": false
          },
          "includeExtraBoxes": {
            "title": "Include extra info boxes (weather, time zone, currency/unit converter, stock, jobs, videos, shopping, dictionary)",
            "type": "boolean",
            "description": "If enabled, also extracts weather, time-zone, currency converter, unit converter, stock, jobs pack, video pack, shopping pack, and dictionary boxes when present on the results page.",
            "default": false
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Choose Apify proxy settings. Leave unset and the scraper automatically tries Google SERP, then RESIDENTIAL, then Apify Web Unblocker, then your account default - the GOOGLE_SERP and RESIDENTIAL attempts are automatically steered to an exit IP in your Country (or, if Country is left empty, the country derived from Precise Location/uule) so the proxy's real geolocation lines up with what you asked Google for instead of fighting it. This automatic steering only applies to the default chain; if you set a custom Proxy configuration here yourself (e.g. pinning apifyProxyGroups), set its own apifyProxyCountry too if geo-targeting matters."
          },
          "uule": {
            "title": "Precise location (uule)",
            "type": "string",
            "description": "Optional Google-encoded location string for city-level geo-targeting, more precise than Country when honored. It encodes a canonical place name (e.g. 'New York,New York,United States') as the literal prefix 'w+CAIQICI' followed by base64 - example for New York: w+CAIQICIH05ldyBZb3JrLE5ldyBZb3JrLFVuaXRlZCBTdGF0ZXM=. Easiest way to get one for your city: paste its canonical name (as it appears in Google Ads Geo Targets, e.g. https://developers.google.com/google-ads/api/data/geotargets) into a third-party uule builder such as valentin.app/uule.html and copy the resulting string starting with 'w+CAIQICI'. If Country above is left empty, its country is automatically derived from this value and used for both the gl signal and proxy-country steering, so you don't need to set both fields redundantly for the same location. Caveat: Google does not always honor this parameter even so - country-level targeting is reliable, but city-level precision beyond the country match is best-effort and its hit rate varies noticeably by city/region in our testing: it can fall back to the proxy IP's actual geographic location (which can be a different city or region, sometimes far from the encoded one) instead of the encoded one. Treat uule as a best-effort hint, not a guarantee, and spot-check results rather than assuming they reflect the targeted city. Leave empty to use Country only."
          },
          "dateFrom": {
            "title": "Date from",
            "type": "string",
            "description": "Only include results published on or after this date (YYYY-MM-DD). Must be used together with Date to."
          },
          "dateTo": {
            "title": "Date to",
            "type": "string",
            "description": "Only include results published on or before this date (YYYY-MM-DD). Must be used together with Date from."
          },
          "exactPhrase": {
            "title": "Exact phrase match",
            "type": "boolean",
            "description": "If enabled, wraps each query in quotes so Google matches it as an exact phrase (e.g. \"running shoes\") instead of matching the words independently and in any order.",
            "default": false
          },
          "site": {
            "title": "Site (site: operator)",
            "type": "string",
            "description": "Restrict results to this domain, e.g. nike.com. Unlike the other operators below, this one is verified: every organic result is checked against this domain and off-domain results Google slips in are dropped."
          },
          "intitle": {
            "title": "Word in title (intitle: operator)",
            "type": "string",
            "description": "Restrict results to pages that contain this word in the title, e.g. running. Sent to Google as-is; unlike Site above, results are not verified against it, so Google may still include pages that don't actually match."
          },
          "intext": {
            "title": "Word in text (intext: operator)",
            "type": "string",
            "description": "Restrict results to pages that contain this word in the body text, e.g. discount. Sent to Google as-is; unlike Site above, results are not verified against it, so Google may still include pages that don't actually match."
          },
          "inurl": {
            "title": "Word in URL (inurl: operator)",
            "type": "string",
            "description": "Restrict results to pages that contain this word in the URL, e.g. blog. Sent to Google as-is; unlike Site above, results are not verified against it, so Google may still include pages that don't actually match."
          },
          "fileType": {
            "title": "File type (filetype: operator)",
            "type": "string",
            "description": "e.g. pdf, doc, xls. Sent to Google as-is; unlike Site above, results are not verified against it, so Google may still include pages that don't actually match."
          },
          "excludeTerms": {
            "title": "Exclude terms (-word operator)",
            "type": "string",
            "description": "Words to exclude from results by prefixing them with '-', e.g. jaguar. Separate multiple words with a comma or space, e.g. 'jaguar, cats'."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}