How to Build a Keyword Research Tool with Autocomplete and People Also Ask Data

Learn how to build a keyword research tool with autocomplete suggestions and People Also Ask data. Use Python to collect keyword ideas, questions, intent signals, and export results to CSV.

How to Build a Keyword Research Tool with Autocomplete and People Also Ask Data
Ethan Caldwell
Last updated on
6 min read

Quick answer: You can build a keyword research tool by combining autocomplete suggestions with People Also Ask questions. Autocomplete helps expand long-tail keyword ideas, while People Also Ask reveals question-based intent. A SERP API can collect these search signals, and Python can normalize them into a CSV file for SEO planning, content briefs, or AI workflows.

Keyword research is not only about search volume.

When people search, they reveal intent through the words they type, the suggestions they see, and the questions shown around a topic.

Two useful sources are:

  • Autocomplete data: search suggestions based on a seed keyword

  • People Also Ask data: question-style results related to a query

Together, they can help you find long-tail keywords, FAQ ideas, content angles, and search intent patterns.

For the data layer, you can use Talordata SERP API or another SERP API that returns structured search results. Talordata’s product page describes structured real-time search data across Google and major search engines, with JSON / HTML output and geo-targeting support.

Why Autocomplete and People Also Ask Matter

Autocomplete and People Also Ask answer different questions.

Data source

What it helps you find

Autocomplete

Long-tail keyword variations users may type

People Also Ask

Questions users may ask before clicking a result

Organic snippets

How ranking pages frame the topic

Related searches

Additional topic clusters

For example, from the seed keyword:

serp api

Autocomplete may return ideas like:

serp api pricing
serp api python
serp api for seo
serp api alternatives
serp api for ai agents

People Also Ask may return questions like:

What is a SERP API?
How do SERP APIs work?
Is it legal to scrape search results?
What is the best API for Google search results?

Autocomplete gives you what people may type. People Also Ask gives you what people may want to understand.

What We Will Build

We will create a Python workflow:

Seed keyword
→ Collect autocomplete suggestions
→ Collect People Also Ask questions
→ Normalize keyword ideas
→ Classify search intent
→ Export results to CSV

The final CSV can include:

Field

Meaning

seed_keyword

The original keyword

keyword

The collected keyword or question

source

Autocomplete or PAA

intent

Informational, commercial, technical, local, or general

word_count

Number of words in the keyword

content_angle

Suggested content format

collected_at

Collection timestamp

Step 1: Set Environment Variables

Use environment variables instead of hardcoding credentials.

export TALORDATA_API_KEY="your_api_key_here"
export TALORDATA_SERP_ENDPOINT="your_talordata_serp_endpoint_here"

On Windows PowerShell:

$env:TALORDATA_API_KEY="your_api_key_here"
$env:TALORDATA_SERP_ENDPOINT="your_talordata_serp_endpoint_here"

Install the package:

pip install requests

Use the endpoint and parameters shown in your Talordata dashboard or API documentation. Talordata’s docs provide query parameter sections for SERP API workflows.

Step 2: Create a Request Helper

Keep the request layer separate from parsing logic. This makes the script easier to adjust later.

import os
import requests


def require_env(name):
    value = os.getenv(name)
    if not value:
        raise RuntimeError(f"Missing required environment variable: {name}")
    return value


TALORDATA_API_KEY = require_env("TALORDATA_API_KEY")
TALORDATA_SERP_ENDPOINT = require_env("TALORDATA_SERP_ENDPOINT")


def call_serp_api(payload):
    headers = {
        "Authorization": f"Bearer {TALORDATA_API_KEY}",
        "Content-Type": "application/json"
    }

    response = requests.post(
        TALORDATA_SERP_ENDPOINT,
        json=payload,
        headers=headers,
        timeout=30
    )

    response.raise_for_status()
    return response.json()

Some APIs use GET instead of POST, or pass the API key as a query parameter. If your setup is different, only update this helper.

Step 3: Collect Autocomplete Suggestions

Autocomplete responses may use different field names, so the parser below supports several common formats.

def fetch_autocomplete(seed_keyword, location="United States", language="en"):
    payload = {
        "engine": "google_autocomplete",
        "q": seed_keyword,
        "location": location,
        "hl": language,
        "output": "json"
    }

    return call_serp_api(payload)


def extract_autocomplete_keywords(response_json):
    raw_items = (
        response_json.get("suggestions")
        or response_json.get("autocomplete_results")
        or response_json.get("completion_results")
        or []
    )

    keywords = []

    for item in raw_items:
        if isinstance(item, str):
            keywords.append(item)
        elif isinstance(item, dict):
            keyword = item.get("value") or item.get("suggestion") or item.get("keyword")
            if keyword:
                keywords.append(keyword)

    return keywords

If your API uses another engine name, such as autocomplete or google_suggest, change the engine value.

Step 4: Collect People Also Ask Questions

People Also Ask data usually comes from a regular Google search response. It may appear under keys such as related_questions, people_also_ask, or paa_results.

def fetch_google_search(query, location="United States", language="en", country="us"):
    payload = {
        "engine": "google",
        "q": query,
        "location": location,
        "hl": language,
        "gl": country,
        "num": 10,
        "output": "json"
    }

    return call_serp_api(payload)


def extract_paa_questions(response_json):
    raw_items = (
        response_json.get("related_questions")
        or response_json.get("people_also_ask")
        or response_json.get("paa_results")
        or []
    )

    questions = []

    for item in raw_items:
        if isinstance(item, str):
            questions.append(item)
        elif isinstance(item, dict):
            question = item.get("question") or item.get("title")
            if question:
                questions.append(question)

    return questions

PAA questions are useful for FAQ sections, explainer articles, comparison pages, and content briefs.

Step 5: Classify Search Intent

A simple rule-based classifier is enough for a first version.

def classify_intent(keyword):
    text = keyword.lower()

    if any(word in text for word in ["what", "why", "how", "guide", "tutorial"]):
        return "informational"

    if any(word in text for word in ["best", "top", "vs", "alternative", "compare"]):
        return "commercial"

    if any(word in text for word in ["price", "pricing", "cost", "free trial"]):
        return "commercial"

    if any(word in text for word in ["api", "python", "docs", "integration", "example"]):
        return "technical"

    if any(word in text for word in ["near me", "local", "map", "maps"]):
        return "local"

    return "general"

This will not be perfect, but it gives you a useful first grouping layer.

Step 6: Suggest Content Angles

Now add a simple rule to recommend content formats.

def suggest_content_angle(keyword, source):
    intent = classify_intent(keyword)

    if source == "paa":
        return "FAQ section or explainer paragraph"

    if intent == "technical":
        return "Developer tutorial"

    if intent == "commercial":
        return "Comparison or buying guide"

    if intent == "local":
        return "Local SEO landing page or local report"

    if intent == "informational":
        return "Educational blog post"

    return "Topic cluster supporting page"

This makes the output more useful for SEO and content teams.

Step 7: Export Keyword Ideas to CSV

import csv
from datetime import datetime, timezone


CSV_COLUMNS = [
    "seed_keyword",
    "keyword",
    "source",
    "intent",
    "word_count",
    "content_angle",
    "collected_at"
]


def clean_text(value):
    if not value:
        return ""
    return " ".join(str(value).split())


def build_rows(seed_keyword, keywords, source):
    collected_at = datetime.now(timezone.utc).isoformat()
    rows = []

    for keyword in keywords:
        cleaned = clean_text(keyword)

        if not cleaned:
            continue

        rows.append({
            "seed_keyword": seed_keyword,
            "keyword": cleaned,
            "source": source,
            "intent": classify_intent(cleaned),
            "word_count": len(cleaned.split()),
            "content_angle": suggest_content_angle(cleaned, source),
            "collected_at": collected_at
        })

    return rows


def dedupe_rows(rows):
    seen = set()
    unique_rows = []

    for row in rows:
        key = row["keyword"].lower()

        if key in seen:
            continue

        seen.add(key)
        unique_rows.append(row)

    return unique_rows


def export_to_csv(rows, filename="keyword_research_results.csv"):
    if not rows:
        print("No keyword ideas found.")
        return

    with open(filename, mode="w", newline="", encoding="utf-8") as file:
        writer = csv.DictWriter(file, fieldnames=CSV_COLUMNS)
        writer.writeheader()
        writer.writerows(rows)

    print(f"Exported {len(rows)} keyword ideas to {filename}")

Complete Python Example

import os
import csv
import requests

from datetime import datetime, timezone


CSV_COLUMNS = [
    "seed_keyword",
    "keyword",
    "source",
    "intent",
    "word_count",
    "content_angle",
    "collected_at"
]


def require_env(name):
    value = os.getenv(name)
    if not value:
        raise RuntimeError(f"Missing required environment variable: {name}")
    return value


TALORDATA_API_KEY = require_env("TALORDATA_API_KEY")
TALORDATA_SERP_ENDPOINT = require_env("TALORDATA_SERP_ENDPOINT")


def call_serp_api(payload):
    headers = {
        "Authorization": f"Bearer {TALORDATA_API_KEY}",
        "Content-Type": "application/json"
    }

    response = requests.post(
        TALORDATA_SERP_ENDPOINT,
        json=payload,
        headers=headers,
        timeout=30
    )

    response.raise_for_status()
    return response.json()


def fetch_autocomplete(seed_keyword, location="United States", language="en"):
    payload = {
        "engine": "google_autocomplete",
        "q": seed_keyword,
        "location": location,
        "hl": language,
        "output": "json"
    }

    return call_serp_api(payload)


def fetch_google_search(query, location="United States", language="en", country="us"):
    payload = {
        "engine": "google",
        "q": query,
        "location": location,
        "hl": language,
        "gl": country,
        "num": 10,
        "output": "json"
    }

    return call_serp_api(payload)


def clean_text(value):
    if not value:
        return ""
    return " ".join(str(value).split())


def extract_autocomplete_keywords(response_json):
    raw_items = (
        response_json.get("suggestions")
        or response_json.get("autocomplete_results")
        or response_json.get("completion_results")
        or []
    )

    keywords = []

    for item in raw_items:
        if isinstance(item, str):
            keywords.append(item)
        elif isinstance(item, dict):
            keyword = item.get("value") or item.get("suggestion") or item.get("keyword")
            if keyword:
                keywords.append(keyword)

    return keywords


def extract_paa_questions(response_json):
    raw_items = (
        response_json.get("related_questions")
        or response_json.get("people_also_ask")
        or response_json.get("paa_results")
        or []
    )

    questions = []

    for item in raw_items:
        if isinstance(item, str):
            questions.append(item)
        elif isinstance(item, dict):
            question = item.get("question") or item.get("title")
            if question:
                questions.append(question)

    return questions


def classify_intent(keyword):
    text = keyword.lower()

    if any(word in text for word in ["what", "why", "how", "guide", "tutorial"]):
        return "informational"

    if any(word in text for word in ["best", "top", "vs", "alternative", "compare"]):
        return "commercial"

    if any(word in text for word in ["price", "pricing", "cost", "free trial"]):
        return "commercial"

    if any(word in text for word in ["api", "python", "docs", "integration", "example"]):
        return "technical"

    if any(word in text for word in ["near me", "local", "map", "maps"]):
        return "local"

    return "general"


def suggest_content_angle(keyword, source):
    intent = classify_intent(keyword)

    if source == "paa":
        return "FAQ section or explainer paragraph"

    if intent == "technical":
        return "Developer tutorial"

    if intent == "commercial":
        return "Comparison or buying guide"

    if intent == "local":
        return "Local SEO landing page or local report"

    if intent == "informational":
        return "Educational blog post"

    return "Topic cluster supporting page"


def build_rows(seed_keyword, keywords, source):
    collected_at = datetime.now(timezone.utc).isoformat()
    rows = []

    for keyword in keywords:
        cleaned = clean_text(keyword)

        if not cleaned:
            continue

        rows.append({
            "seed_keyword": seed_keyword,
            "keyword": cleaned,
            "source": source,
            "intent": classify_intent(cleaned),
            "word_count": len(cleaned.split()),
            "content_angle": suggest_content_angle(cleaned, source),
            "collected_at": collected_at
        })

    return rows


def dedupe_rows(rows):
    seen = set()
    unique_rows = []

    for row in rows:
        key = row["keyword"].lower()

        if key in seen:
            continue

        seen.add(key)
        unique_rows.append(row)

    return unique_rows


def export_to_csv(rows, filename="keyword_research_results.csv"):
    if not rows:
        print("No keyword ideas found.")
        return

    with open(filename, mode="w", newline="", encoding="utf-8") as file:
        writer = csv.DictWriter(file, fieldnames=CSV_COLUMNS)
        writer.writeheader()
        writer.writerows(rows)

    print(f"Exported {len(rows)} keyword ideas to {filename}")


if __name__ == "__main__":
    seed_keyword = "serp api"
    location = "United States"

    autocomplete_json = fetch_autocomplete(seed_keyword, location=location)
    autocomplete_keywords = extract_autocomplete_keywords(autocomplete_json)

    search_json = fetch_google_search(seed_keyword, location=location)
    paa_questions = extract_paa_questions(search_json)

    rows = []
    rows.extend(build_rows(seed_keyword, autocomplete_keywords, "autocomplete"))
    rows.extend(build_rows(seed_keyword, paa_questions, "paa"))

    rows = dedupe_rows(rows)
    export_to_csv(rows)

After running the script, you should get:

keyword_research_results.csv

Example Output

seed_keyword,keyword,source,intent,word_count,content_angle,collected_at
serp api,serp api pricing,autocomplete,commercial,3,Comparison or buying guide,2026-06-22T00:00:00Z
serp api,serp api python,autocomplete,technical,3,Developer tutorial,2026-06-22T00:00:00Z
serp api,What is a SERP API?,paa,informational,5,FAQ section or explainer paragraph,2026-06-22T00:00:00Z
serp api,How do SERP APIs work?,paa,informational,5,FAQ section or explainer paragraph,2026-06-22T00:00:00Z

From here, you can send the CSV to Google Sheets, Airtable, Notion, a database, or an AI content planning workflow.

How to Use the Output for SEO Planning

For SEO planning, group keywords by intent:

Intent

Best content format

Informational

Blog posts, explainers, guides

Commercial

Comparison pages, alternative pages, buying guides

Technical

Developer tutorials, API docs, integration guides

Local

Local SEO landing pages, location reports

PAA questions

FAQ sections, H2 sections, content brief questions

For example, the output can become a content brief:

Topic: SERP API
Main angle: Developer tutorial

Supporting questions:
- What is a SERP API?
- How do SERP APIs work?
- Can I use a SERP API with Python?

Suggested sections:
- What the API returns
- Query parameters
- Python example
- CSV export
- FAQ

If you use Talordata SERP API for the workflow, you can extend the same structure to regular Google results, People Also Ask questions, autocomplete suggestions, related searches, and other search-result modules, depending on the data returned by your chosen endpoint. Talordata positions SERP API use cases around SEO monitoring, market research, ad verification, competitive intelligence, and AI workflows. Claim 1,000 free API responses >>

Best Practices

Save raw API responses during development. Autocomplete and PAA response structures can vary by query, location, and provider.

Keep the request layer separate from parsing. This makes it easier to change API endpoints later.

Do not rely only on autocomplete. It gives keyword variations, but not enough context by itself.

Do not rely only on People Also Ask. It gives useful questions, but it does not replace full SERP analysis.

Track location and language. Suggestions and PAA questions can change by country, city, and language.

Add search volume later. Autocomplete and PAA are good for discovery; search volume and ranking difficulty are separate metrics.

FAQ

What is the difference between autocomplete and People Also Ask?

Autocomplete shows keyword suggestions related to what users may type. People Also Ask shows question-style results related to what users may want to understand.

Can I build a keyword research tool with Python?

Yes. You can use Python to collect autocomplete suggestions, People Also Ask questions, normalize the results, classify intent, and export keyword ideas to CSV.

What is PAA data?

PAA stands for People Also Ask. It refers to question-style results that appear on Google for many searches. These questions are useful for FAQ sections, content briefs, and search intent analysis.

Is autocomplete data enough for keyword research?

No. Autocomplete is useful for discovering keyword variations, but it should be combined with SERP data, People Also Ask questions, search volume, and competitor analysis.

Can this workflow be used for content briefs?

Yes. You can group autocomplete keywords and PAA questions by intent, then turn them into article outlines, FAQ sections, comparison pages, or developer tutorials.

Scale Your Data
Operations Today.

Join the world's most robust proxy network.

Start Free Trial