Back to Blog

People Also Ask API: Build a Keyword Research Tool Using Google's PAA Data

Google's People Also Ask boxes reveal real user questions and search intent at scale. Learn how to extract PAA data with a SERP API and use it for keyword research, content briefs, and FAQ strategy — with full Python examples.

April 21, 2026
By SerpBase Teamkeyword researchpeople also askcontent strategyseopython

People Also Ask API: Build a Keyword Research Tool Using Google's PAA Data

When you search on Google, you will often see a box labeled "People also ask" below the first few organic results. It contains 4-6 questions related to your query, each expandable to show a featured answer snippet.

This box is a gold mine for keyword research. Unlike tools that estimate search volume from historical data, PAA questions come directly from Google — they reflect real user intent, real language, and real information gaps that Google has decided are worth surfacing. Extracting PAA data at scale gives you a question intelligence layer that no static keyword database can replicate.

This guide shows how to extract PAA data using a SERP API and build practical keyword research tools on top of it.

What PAA Data Looks Like

A SERP API returns PAA questions in a people_also_ask array. Each entry includes the question, a snippet answer, and the source URL:

{
  "people_also_ask": [
    {
      "question": "What is the difference between a SERP API and a web scraper?",
      "snippet": "A SERP API returns structured JSON from Google search results without requiring you to parse HTML or manage proxies. A web scraper...",
      "link": "https://example.com/serp-api-guide",
      "displayed_link": "example.com"
    },
    {
      "question": "How much does a SERP API cost?",
      "snippet": "SERP API pricing varies widely. Budget options start at $0.30 per 1,000 queries...",
      "link": "https://example.com/pricing",
      "displayed_link": "example.com"
    }
  ]
}

Basic PAA Extraction

import requests

API_KEY = "your_api_key"

def get_paa(query: str, country: str = "us", lang: str = "en") -> list:
    resp = requests.post(
        "https://api.serpbase.dev/google/search",
        headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
        json={"q": query, "gl": country, "hl": lang, "page": 1},
        timeout=15,
    )
    resp.raise_for_status()
    data = resp.json()
    return data.get("people_also_ask", [])

# Extract PAA for a seed keyword
questions = get_paa("serp api")
for q in questions:
    print(f"Q: {q['question']}")
    print(f"   Source: {q.get('displayed_link', '')}")
    print()

Use Case 1: Question Expansion for Keyword Research

PAA questions are not just content ideas — they are actual search queries people type into Google. Collecting PAA for a seed keyword and then recursively pulling PAA for each question can produce hundreds of real, related queries in minutes.

import time
from collections import deque

def expand_questions(seed: str, depth: int = 2, max_questions: int = 50) -> dict:
    """
    BFS expansion: get PAA for seed, then PAA for each question found,
    up to a max depth and total question count.
    """
    seen = set()
    result = {}  # question -> source URL
    queue = deque([(seed, 0)])

    while queue and len(result) < max_questions:
        query, level = queue.popleft()

        if query in seen or level > depth:
            continue
        seen.add(query)

        questions = get_paa(query)
        for q in questions:
            text = q["question"]
            if text not in result:
                result[text] = q.get("link", "")
                if level + 1 <= depth:
                    queue.append((text, level + 1))

        time.sleep(0.3)

    return result

# Expand from one seed keyword
all_questions = expand_questions("content marketing", depth=2)
print(f"Found {len(all_questions)} unique questions:")
for question in list(all_questions.keys())[:20]:
    print(f"  - {question}")

A depth-2 expansion from a single seed typically yields 50-200 unique questions, all of them real Google PAA entries.

Use Case 2: Content Brief Generator

Every piece of content should answer the questions real users are asking. PAA data gives you an exact list of those questions for any topic.

def generate_content_brief(topic: str) -> dict:
    questions = get_paa(topic)
    related_resp = requests.post(
        "https://api.serpbase.dev/google/search",
        headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
        json={"q": topic, "gl": "us", "hl": "en"},
        timeout=15,
    ).json()

    related_searches = [
        r["query"] for r in related_resp.get("related_searches", [])
    ]
    top_urls = [
        r["link"] for r in related_resp.get("organic", [])[:5]
    ]

    return {
        "topic": topic,
        "faq_section": [q["question"] for q in questions],
        "related_keywords": related_searches,
        "competitor_urls_to_analyze": top_urls,
        "recommended_h2s": [
            f"What is {topic}?",
            f"How to use {topic}",
            f"Best practices for {topic}",
        ] + [q["question"] for q in questions[:3]],
    }

brief = generate_content_brief("serp api")
print("=== Content Brief ===")
print(f"FAQ Questions to answer:")
for q in brief["faq_section"]:
    print(f"  ? {q}")
print(f"\nRelated keywords to include:")
for kw in brief["related_keywords"][:5]:
    print(f"  - {kw}")

Use Case 3: FAQ Schema Generation

FAQ schema markup can earn your page extra space in Google search results. PAA data is a perfect source for FAQ content because it is drawn directly from real user questions.

import json

def generate_faq_schema(topic: str) -> dict:
    questions = get_paa(topic)

    faq_items = [
        {
            "@type": "Question",
            "name": q["question"],
            "acceptedAnswer": {
                "@type": "Answer",
                "text": q.get("snippet", "")
            }
        }
        for q in questions if q.get("snippet")
    ]

    schema = {
        "@context": "https://schema.org",
        "@type": "FAQPage",
        "mainEntity": faq_items
    }

    return schema

schema = generate_faq_schema("serp api")
print(json.dumps(schema, indent=2))
# Embed this in your page's <head> as application/ld+json

Use Case 4: Search Intent Clustering

PAA questions reveal the different angles users care about for a topic. Clustering them by intent type helps you plan content that covers a topic completely.

def classify_intent(question: str) -> str:
    q = question.lower()
    if any(w in q for w in ["what is", "what are", "what does", "define", "meaning"]):
        return "informational"
    if any(w in q for w in ["how to", "how do", "how can", "steps to", "guide"]):
        return "how-to"
    if any(w in q for w in ["best", "top", "which", "vs", "versus", "compare"]):
        return "comparative"
    if any(w in q for w in ["price", "cost", "cheap", "free", "buy", "pricing"]):
        return "commercial"
    return "other"

def cluster_by_intent(topic: str) -> dict:
    questions = expand_questions(topic, depth=1)
    clusters = {"informational": [], "how-to": [], "comparative": [], "commercial": [], "other": []}

    for question in questions:
        intent = classify_intent(question)
        clusters[intent].append(question)

    return clusters

clusters = cluster_by_intent("project management software")
for intent, qs in clusters.items():
    if qs:
        print(f"\n{intent.upper()} ({len(qs)} questions):")
        for q in qs[:3]:
            print(f"  - {q}")

Use Case 5: Content Gap Analysis

Compare PAA questions for your brand versus competitors to spot topics you have not written about yet.

def find_content_gaps(my_keyword: str, competitor_keyword: str) -> dict:
    my_questions = {q["question"] for q in get_paa(my_keyword)}
    time.sleep(0.5)
    comp_questions = {q["question"] for q in get_paa(competitor_keyword)}

    return {
        "only_mine": my_questions - comp_questions,
        "only_competitor": comp_questions - my_questions,
        "shared": my_questions & comp_questions,
    }

gaps = find_content_gaps("serpbase api", "serpapi alternative")
print("Questions competitors answer but you don't:")
for q in gaps["only_competitor"]:
    print(f"  - {q}")

Combining PAA with Related Searches

The related_searches field in a SERP response complements PAA well. PAA gives you questions; related searches give you noun phrases. Together they form a comprehensive keyword map.

def full_keyword_map(seed: str) -> dict:
    resp = requests.post(
        "https://api.serpbase.dev/google/search",
        headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
        json={"q": seed, "gl": "us", "hl": "en"},
        timeout=15,
    ).json()

    return {
        "seed": seed,
        "paa_questions": [q["question"] for q in resp.get("people_also_ask", [])],
        "related_terms": [r["query"] for r in resp.get("related_searches", [])],
        "top_ranking_urls": [r["link"] for r in resp.get("organic", [])[:5]],
    }

keyword_map = full_keyword_map("python web scraping")
print(f"PAA questions: {len(keyword_map['paa_questions'])}")
print(f"Related terms: {len(keyword_map['related_terms'])}")

Cost at Scale

PAA-based keyword research is query-efficient because each search returns multiple questions:

TaskQueries neededCost at SerpBase
PAA for 100 seed keywords100$0.03
Depth-2 expansion (100 seeds)~1,500$0.45
Content briefs for 50 topics50$0.015
Weekly gap analysis (20 topics)40$0.012

At $0.30/1,000 queries, even aggressive PAA research costs less than a cup of coffee.

Tips for Better PAA Data

  • PAA varies by query phrasing — "how to lose weight" and "weight loss tips" can return different PAA sets. Test multiple phrasings.
  • PAA changes over time — Run the same queries monthly to catch new questions Google adds.
  • PAA is geographic — Use gl=gb for UK questions, gl=de for Germany. PAA varies significantly by market.
  • Combine with organic rankings — A question that appears in PAA AND has low-authority pages ranking for it is a high-opportunity target.

Summary

People Also Ask data is one of the most underused signals in SEO. Every PAA entry is a confirmed user question that Google has validated as relevant and searchable. With a SERP API, you can collect thousands of these questions programmatically, cluster them by intent, use them for content briefs, generate FAQ schema, and identify content gaps — all without any browser automation or proxy infrastructure.

With SerpBase at $0.30 per 1,000 queries, a full keyword research workflow for a 100-keyword project costs less than $0.50 in API calls.

Get your free API key at SerpBase — 100 searches included, no credit card required.