People also search for and related searches: expand keywords and map entities
“People also search for” is used for three different things on Google, and only two of them are data you can collect reliably. Related searches are the query suggestions near the bottom of a results page. The knowledge panel’s “People also search for” is a list of related entities inside an entity panel. And the back-click box is a set of suggestions Google has shown directly below a result after a searcher clicks it and comes back.
POST /v1/monitor/google returns the first two as relatedSearches[] and knowledgeGraph.peopleAlsoSearchFor[]; the third is not returned. Two workflows follow: breadth-first keyword expansion with cost control, and entity research.
Definitions
- Related searches: suggested queries for the search as a whole. Returned as
result.relatedSearches[], each withqueryandlink(a Google search URL for that query). - Knowledge panel related entities: the “People also search for” list inside a knowledge panel. Returned as
result.knowledgeGraph.peopleAlsoSearchFor[], each withnameandlink. - Back-click box: suggestions shown beneath a result the searcher clicked and returned from. Not returned as a field.
- Expansion level: one round of running the queries discovered in the previous round.
Related searches
Google’s visual elements gallery calls this block a “related searches group” and describes it as “a cluster of related searches that other people have done” (checked 2026-09-17).
In the response:
{
"success": true,
"result": {
"organicResults": [ { "position": 1, "title": "…", "link": "…" } ],
"relatedSearches": [
{ "query": "espresso machine for beginners", "link": "https://google.com/search?q=espresso+machine+for+beginners" },
{ "query": "best espresso machine under 500", "link": "https://google.com/search?q=best+espresso+machine+under+500" }
]
}
}
The queries above are placeholders. Related searches are queries rather than questions, which makes them a different kind of input from People Also Ask, whose entries are phrased as questions. Use both: related searches for keyword breadth, People Also Ask for question-level content.
The knowledge panel’s People also search for
When Google resolves a query to an entity (a company, person, film, place), the page can include a knowledge panel. The API returns it as result.knowledgeGraph, which is omitted when no panel appears. Among its fields are title, type, kgmid (the Knowledge Graph id), description, website and peopleAlsoSearchFor[]:
{
"knowledgeGraph": {
"title": "Example Brand",
"type": "Coffee company",
"kgmid": "/g/…",
"website": "https://example.com",
"peopleAlsoSearchFor": [
{ "name": "Competitor One", "link": "https://www.google.com/search?q=Competitor+One" },
{ "name": "Competitor Two", "link": "https://www.google.com/search?q=Competitor+Two" }
]
}
}
These are entities, not keywords. For a brand, the list can read like a competitor set; for a person or a film, it is a set of associated people or works. Treat it as Google’s view of which entities belong together, captured for one market and device at one time.
The back-click box
The third meaning is a box that appears after a “short click”. Search Engine Roundtable reported its new design on 2018-02-13 and described triggering it by searching, clicking a result, “and then click the back button to go back to the search results” (Search Engine Roundtable, checked 2026-09-17). A SISTRIX article (published 2018-03-22, modified 2022-05-12) says the box shows “directly below the result they just returned from” and that Google only shows it on the first results page (SISTRIX, checked 2026-09-17). Both are third-party observations, not Google documentation.
Because this box depends on a searcher clicking a result and returning, it is not part of the results page for a fresh query, and this API does not return it. If a tool claims to report “People also search for” for arbitrary keywords, check whether it means related searches, knowledge panel entities or this box. They are different data.
Comparison
| Related searches | Knowledge panel People also search for | Back-click box | |
|---|---|---|---|
| What it lists | Queries | Entities | Queries |
| When it appears | Varies by query | Only with a knowledge panel | After a click and return |
| Field | relatedSearches[] (query, link) |
knowledgeGraph.peopleAlsoSearchFor[] (name, link) |
None |
| Best use | Keyword expansion | Entity and competitor research | Not collectable here |
Workflow 1: breadth-first keyword expansion
Breadth-first expansion runs all seeds, then all new queries they surfaced, level by level. Doing it level by level (instead of following one chain deep) keeps the topic centered on your seeds and makes cost predictable.
Rules that keep it useful
- Normalize before comparing: lowercase, trim, collapse whitespace, strip punctuation. “Espresso machine, beginners” and “espresso machine beginners” are one query.
- Deduplicate against everything already run, not only the current level.
- Filter off-topic drift: require at least one seed term, or a term from an allow-list, in each new query. Without a filter, expansion can drift from “espresso machine” toward loosely related queries such as “coffee shop near me”.
- Cap depth and budget. Two or three levels is usually enough. Stop earlier when a level adds few new queries.
- Keep the market fixed: the same
countryorgl,hlanddevicefor the whole run; related searches differ by market.
Code
The script submits each level as async GOOGLE tasks in batches of up to 500, polls until they finish, and computes the next level. For large runs replace polling with a webhook, as in the async batch pipeline.
import hashlib
import os
import re
import time
import requests
API = "https://api.answerline.dev"
HEADERS = {"Authorization": f"Bearer {os.environ['ANSWERLINE_API_KEY']}"}
COUNTRY, HL = "US", "en"
CREDITS_PER_TASK = 3 # Google Search async task, one page, no add-ons
def norm(q: str) -> str:
return re.sub(r"\s+", " ", re.sub(r"[^\w\s]", " ", q.lower())).strip()
def key(q: str) -> str:
return f"rs:{COUNTRY}:{HL}:{hashlib.sha256(norm(q).encode()).hexdigest()[:24]}"
def run(queries: list[str]) -> list[dict]:
tasks = [{"taskType": "GOOGLE", "payload": {"query": q, "country": COUNTRY, "hl": HL}, "idempotencyKey": key(q)}
for q in queries]
ids = []
for i in range(0, len(tasks), 500):
r = requests.post(f"{API}/v1/async/task/batch", json=tasks[i:i + 500], headers=HEADERS, timeout=120)
r.raise_for_status()
ids += [x["task"]["id"] for x in r.json()["results"] if x["success"]]
done = {}
while len(done) < len(ids):
time.sleep(15)
for tid in ids:
if tid in done:
continue
body = requests.get(f"{API}/v1/async/task/{tid}", headers=HEADERS, timeout=30).json()
if body["task"]["status"] in ("COMPLETED", "FAILED"):
done[tid] = body
return [b["response"]["result"] for b in done.values() if b["task"]["status"] == "COMPLETED"]
def expand(seeds: list[str], topic_terms: set[str], max_levels: int = 3, budget: int = 3000) -> dict[str, int]:
seen = {norm(s): 0 for s in seeds}
frontier, spent = list(seeds), 0
for level in range(max_levels):
affordable = (budget - spent) // CREDITS_PER_TASK
frontier = frontier[:affordable]
if not frontier:
break
spent += len(frontier) * CREDITS_PER_TASK
new = []
for result in run(frontier):
for rs in result.get("relatedSearches") or []:
n = norm(rs["query"])
if n in seen or not (set(n.split()) & topic_terms):
continue
seen[n] = level + 1
new.append(rs["query"])
print(f"level {level}: ran {len(frontier)}, found {len(new)} new, spent up to {spent} credits")
if len(new) < 10:
break
frontier = new
return seen # normalized query -> level first seen
keywords = expand(["espresso machine", "burr grinder"], topic_terms={"espresso", "grinder", "coffee", "machine"})
How the script behaves:
spentcounts the maximum cost of tasks submitted. Tasks that fail are not charged, so the spend is at most this.- The idempotency key is derived from market, language and the normalized query. Re-running the script after a crash does not create a task twice; a key that already exists comes back as an error for that item, and its earlier result must be read from your own store. Keep the task ids you get back if you plan to resume.
- The level a query was first seen at is a rough measure of distance from your seeds. Level-1 queries are closer to the seed intent than level-3 queries.
Cost
Each query is one Google Search request, and related searches arrive with the rest of the page, so there is no extra charge for them. From the current credit prices, one page costs 3 credits as an async task and 5 as a synchronous call.
| Level | Queries run (illustrative) | Async credits |
|---|---|---|
| 0 (seeds) | 50 | 150 |
| 1 | 320 | 960 |
| 2 | 600 (capped by budget) | 1,800 |
| Total | 970 | 2,910 |
The query counts are invented for illustration; your own will depend on the topic and the filter. Three levers matter most: the topic filter, deduplication across levels, and the budget cap. The same responses also carry peopleAlsoAsk[] and organicResults[], so store the full result: you can mine questions and see who ranks for each discovered keyword without paying again. For estimating larger runs, see estimating your monitoring bill.
Workflow 2: entity research with knowledge panels
The knowledge panel list lets you map how Google groups entities in a market: brands with competitors, people with collaborators, products with alternatives.
- Start with entity names (your brand, competitors, key people).
- Run each as a query and keep results that include
knowledgeGraph. - Record the entity by
kgmid, which is stable where names are ambiguous. - Add an edge from the entity to each
peopleAlsoSearchFor[].name. - Run the new names as the next level, deduplicated by name and, once resolved, by
kgmid.
type Edge = { from: string; to: string };
async function panel(query: string) {
const res = await fetch("https://api.answerline.dev/v1/monitor/google", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ANSWERLINE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ query, country: "US", hl: "en" }),
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const { result } = await res.json();
return result.knowledgeGraph as
| { title: string; kgmid?: string; type?: string; peopleAlsoSearchFor?: { name: string; link: string }[] }
| undefined;
}
export async function entityGraph(seeds: string[], levels = 2) {
const nodes = new Map<string, { title: string; type?: string; query: string }>();
const edges: Edge[] = [];
const ran = new Set<string>();
let frontier = seeds;
for (let level = 0; level < levels && frontier.length; level++) {
const next: string[] = [];
for (const q of frontier) {
if (ran.has(q.toLowerCase())) continue;
ran.add(q.toLowerCase());
const kg = await panel(q);
if (!kg) continue;
const id = kg.kgmid ?? kg.title;
nodes.set(id, { title: kg.title, type: kg.type, query: q });
for (const p of kg.peopleAlsoSearchFor ?? []) {
edges.push({ from: id, to: p.name });
next.push(p.name);
}
}
frontier = next;
}
return { nodes, edges };
}
This example uses synchronous calls for readability, at 5 credits each; for more than a few dozen entities, submit them as async tasks at 3. Edges point to names because a related entity’s kgmid is only known once you run it; resolve names to ids after each level.
What to look for in the graph:
- Competitor sets. Entities that appear in each other’s lists are candidates for a group Google associates closely. Compare it with the competitors you track in competitor analysis.
- Missing links. If your brand never appears in competitors’ lists, Google is not associating you with that set yet.
- Entity type drift.
typeshows how Google labels each entity. A brand labeled with a category you do not serve is worth investigating. - Changes over time. Re-run monthly and diff edges, as in SERP feature change tracking.
The same entity names make good prompts for AI assistants. Asking ChatGPT for alternatives to a brand and comparing the answer with the knowledge panel list shows whether both surfaces group the market the same way; competitor AI answer monitoring covers that side.
Pitfalls
- Mixing the three meanings. Label data as related searches or knowledge panel entities in reports, never just “people also search for”.
- Testing for an empty panel list instead of the panel.
knowledgeGraphis omitted when there is no panel; check for the key first. - Unbounded expansion. Without a topic filter and budget, a run drifts and costs grow per level.
- Changing the market mid-run. Related searches for
country: "GB"are not the same list as for"US". - Discarding the rest of the response. Each expansion query also returned organic results and PAA; storing them saves a second pass.
Related posts: what is a SERP, Google rank tracking on a SERP API, featured snippets and AI Overviews, and the keyword research use case.
Field shapes for both lists are on the Google Search engine page.
Questions
What is the difference between related searches and People also search for?
Related searches are query suggestions for the search as a whole, returned as relatedSearches[] with query and link. People also search for inside a knowledge panel lists related entities, returned as knowledgeGraph.peopleAlsoSearchFor[] with name and link, and only appears when the page has a knowledge panel.
Does the API return the People also search for box that appears after clicking back to Google?
No. That box is shown below a result after a searcher clicks it and returns to the results page, and it is not returned. The related-query data you can get is relatedSearches[] and, on entity queries, knowledgeGraph.peopleAlsoSearchFor[].
How do I expand a keyword list with related searches?
Run your seeds, collect every relatedSearches[].query, normalize and deduplicate them against what you have already run, and run the new ones as the next level. Stop at a fixed depth, a budget, or when a level adds few new queries.
How much does keyword expansion cost?
Each query is one Google Search request: 3 credits as an async task or 5 as a synchronous call, with one page. Related searches and the knowledge panel come in the same response, so there is no extra charge for them.
How can I use knowledge panel related entities for research?
Run an entity's name, read knowledgeGraph.kgmid and peopleAlsoSearchFor[], then run those names to build a graph of entities Google associates with each other. Use kgmid as the stable identifier, since names can be ambiguous.