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:
| Task | Queries needed | Cost at SerpBase |
|---|---|---|
| PAA for 100 seed keywords | 100 | $0.03 |
| Depth-2 expansion (100 seeds) | ~1,500 | $0.45 |
| Content briefs for 50 topics | 50 | $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=gbfor UK questions,gl=defor 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.
Product Workflow: Turning PAA Into a Keyword Tool
A useful People Also Ask workflow is not just a list of questions. The better version groups questions by intent, tracks repeated questions across seed terms, and records the search location used to collect them.
| Step | Output |
|---|---|
| Collect seed keywords | A controlled keyword list from GSC, ads, or customer language |
| Pull PAA results | Questions, source URLs, and SERP context |
| Cluster questions | Intent groups for guides, FAQs, and comparisons |
| Map to pages | New article, existing page update, or support doc |
| Refresh monthly | Detect changed questions and new source pages |
Related reading: People Also Ask API for content research, People Also Ask API for keyword research, and Google Search Results JSON API.
FAQ
Should PAA questions be copied directly? No. Use them as intent signals, then answer in your own structure.
What makes this useful for SEO tools? Repetition across queries shows which questions are durable enough to prioritize.