API Examples

Ready-to-use code examples in multiple languages. Copy, paste, and start building.

Response format

Every successful request returns a JSON object with the following structure. All SERP elements are parsed and organized for you.

{
  "search_info": {
    "total_results": "About 21,600,000 results",
    "time_taken": "0.29 seconds"
  },
  "organic_results": [
    {
      "title": "Beautiful Soup: Build a Web Scraper With Python",
      "url": "https://realpython.com/beautiful-soup-web-scraper-python/",
      "website": "Real Python",
      "position": 1,
      "description": "Learn how to scrape web pages and parse HTML with Beautiful Soup.",
      "visible_url": "https://realpython.com › beautiful-soup-web-scraper-python",
      "sitelinks": [
        {
          "title": "Parse HTML",
          "url": "https://realpython.com/beautiful-soup-web-scraper-python/#parse-html",
          "description": "Inspect and extract structured content."
        }
      ]
    }
  ],
  "knowledge_graph": {
    "title": "Beautiful Soup",
    "category": "Python library",
    "description": "A Python package for parsing HTML and XML documents.",
    "source_name": "Wikipedia",
    "source_link": "https://en.wikipedia.org/wiki/Beautiful_Soup_(HTML_parser)",
    "facts": [
      {
        "key": "initial release",
        "value": "2004"
      }
    ]
  },
  "ai_overview": {
    "answer": "Beautiful Soup parses HTML into a tree that Python code can search and traverse.",
    "citations": [
      {
        "title": "Beautiful Soup documentation",
        "url": "https://www.crummy.com/software/BeautifulSoup/bs4/doc/"
      }
    ]
  }
}

The response is sparse: fields are omitted when Google did not render that module. Rich module fields include calculator_result, translation_result, flight_result, sports_result, jobs, hotels, products, image_pack, ai_overview, movies. See the complete search response schema.

Code examples by language

Each example makes a GET request to the search endpoint and prints the results. Replace the API key with your own from the dashboard.

cURL

curl -G https://api.serpsearch.com/api/v1/search \
  -H "Authorization: Bearer gt_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  --data-urlencode "query=best project management tools" \
  -d "page=1"

Python

import requests

response = requests.get(
    "https://api.serpsearch.com/api/v1/search",
    headers={"Authorization": "Bearer gt_live_xxxxxxxxxxxxxxxxxxxxxxxx"},
    params={"query": "best project management tools", "page": 1},
)
response.raise_for_status()
data = response.json()

for result in data["organic_results"]:
    print(f"{result['position']}. {result['title']}")
    print(f"   {result['url']}")
    print(f"   {result.get('description', '')}\n")

JavaScript

const response = await fetch(
  "https://api.serpsearch.com/api/v1/search?query=best+project+management+tools&page=1",
  {
    headers: {
      Authorization: "Bearer gt_live_xxxxxxxxxxxxxxxxxxxxxxxx",
    },
  }
);

if (!response.ok) {
  const { error } = await response.json();
  throw new Error(`${error.code}: ${error.message}`);
}

const data = await response.json();
data.organic_results.forEach((result) => {
  console.log(`${result.position}. ${result.title}`);
  console.log(`   ${result.url}\n`);
});

Go

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "net/url"
)

func main() {
    params := url.Values{}
    params.Set("query", "best project management tools")
    params.Set("page", "1")

    req, _ := http.NewRequest("GET",
        "https://api.serpsearch.com/api/v1/search?"+params.Encode(), nil)
    req.Header.Set("Authorization",
        "Bearer gt_live_xxxxxxxxxxxxxxxxxxxxxxxx")

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    var data map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&data)
    searchInfo := data["search_info"].(map[string]interface{})
    fmt.Printf("Found %v\n", searchInfo["total_results"])
}

Ruby

require "net/http"
require "json"
require "uri"

uri = URI("https://api.serpsearch.com/api/v1/search")
uri.query = URI.encode_www_form(
  query: "best project management tools",
  page: 1
)

req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer gt_live_xxxxxxxxxxxxxxxxxxxxxxxx"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

data = JSON.parse(res.body)
data["organic_results"].each do |result|
  puts "#{result['position']}. #{result['title']}"
  puts "   #{result['url']}\n\n"
end

PHP

<?php
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => "https://api.serpsearch.com/api/v1/search?"
        . http_build_query([
            "query" => "best project management tools",
            "page"  => 1,
        ]),
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer gt_live_xxxxxxxxxxxxxxxxxxxxxxxx",
    ],
    CURLOPT_RETURNTRANSFER => true,
]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
foreach ($data["organic_results"] as $result) {
    echo $result["position"] . ". " . $result["title"] . "\n";
    echo "   " . $result["url"] . "\n\n";
}

Common patterns

Useful patterns for pagination, geo-targeting, error handling, and more.

Handle optional rich modules

Google only returns modules that were present on that SERP, so test for a field before reading it.

const data = await response.json();

if (data.calculator_result) {
  console.log(data.calculator_result.result);
}

if (data.ai_overview) {
  console.log(data.ai_overview.answer);
  data.ai_overview.citations?.forEach(({ title, url }) => {
    console.log(title, url);
  });
}

if (data.sports_result?.status === "Scheduled") {
  // Scheduled teams are retained, but scores are not invented.
  console.log(data.sports_result.teams.map(({ name }) => name));
}

Pagination

Retrieve multiple pages of results by incrementing the page parameter.

# Page 1 (results 1-10)
GET /api/v1/search?query=ai+tools&page=1

# Page 2 (results 11-20)
GET /api/v1/search?query=ai+tools&page=2

# Page 3 (results 21-30)
GET /api/v1/search?query=ai+tools&page=3

Geo-targeted results

Get localized search results for different locations.

# London, UK results
GET /api/v1/search?query=football+scores&location=London,+UK

# Paris, France results
GET /api/v1/search?query=résultats+football&location=Paris,+France

# São Paulo, Brazil results
GET /api/v1/search?query=resultados+futebol&location=São+Paulo,+Brazil

Error handling

All errors follow a consistent envelope format for easy handling.

// Check for errors in every response
const response = await fetch(url, { headers });

if (!response.ok) {
  const { error } = await response.json();

  switch (error.code) {
    case "RATE_LIMIT_EXCEEDED":
      const retryAfter = response.headers.get("Retry-After");
      // Wait and retry
      break;
    case "QUOTA_EXCEEDED":
      // Upgrade plan or wait for billing period reset
      break;
    default:
      console.error(error.code, error.message);
  }
}

Search with geo-targeting

Use the location parameter to geo-target your search results.

curl -G https://api.serpsearch.com/api/v1/search \
  -H "Authorization: Bearer gt_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  --data-urlencode "query=machine learning frameworks comparison 2024" \
  --data-urlencode "location=New York,New York,United States" \
  -d "page=1"

Ready to integrate?

Read the full API reference for detailed parameter docs, error codes, and response headers.