Google Search organic results
Ranked Google listings with titles, URLs and snippets, pages 1 through 10.
`organicResults` returns each listing's position, title, URL, snippet and page. Depth is set with `pages`, charged per extra page.
Returned in result
| Field |
|---|
organicResults |
Request
curl -X POST "https://api.answerline.dev/v1/monitor/google" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"project management software","country":"US","include":{"aioverview":{"markdown":true}}}'
What organic results are
Organic results are the unpaid listings Google ranks for a query: the blue title, the green or gray URL line, and the snippet. They are what rank tracking has always measured, and they still decide which pages collect clicks after ads, the AI Overview and other modules have taken their share.
result.organicResults returns those listings in page order for the query and market you request. The usual jobs are daily rank tracking by market, first-page share against competitors, finding the pages Google prefers for a topic before writing or updating content, and grounding agents in current search results instead of a model’s memory.
Field reference
result.organicResults[]
| Field | Type | Meaning |
|---|---|---|
position |
number | 1-indexed position in the organic results. Counted continuously across all pages fetched. |
title |
string | Title of the listing as shown. |
link |
string | URL of the result. When Google served a redirect, this is the resolved destination. |
displayedLink |
string | The URL line as Google displays it, often with breadcrumbs. |
snippet |
string | Text snippet under the title. |
date |
string | Publication date when Google shows one. Absent otherwise. |
page |
number | Results page the listing appeared on, 1-indexed. |
sitelinks |
object | Sitelinks under the listing, when shown. |
sitelinks.inline[] |
array | Inline sitelinks, each with title (string), link (string) and optional redirectLink (string). |
redirectLink |
string | Google’s /goto redirect for the link, in the absolute form POST /v1/monitor/google/goto accepts. Present only when Google served the link as a redirect. |
organicResults is always present as an array, including when a query returns nothing.
Annotated excerpt
Values are illustrative; names and types follow the POST /v1/monitor/google result schema. The request set pages: 2.
{
"success": true,
"result": {
"organicResults": [
{
"position": 1,
"title": "Standing Desks Buying Guide (2026) | Example Office",
"link": "https://www.example-office.com/guides/standing-desks",
"displayedLink": "https://www.example-office.com › guides",
"snippet": "Height range, motor type and stability matter more than...",
"date": "Aug 12, 2026", // only when Google shows a date
"page": 1,
"sitelinks": {
"inline": [
{ "title": "Best under $500", "link": "https://www.example-office.com/guides/standing-desks#budget" }
]
}
},
{
"position": 11, // continues from page 1, not reset
"title": "Do standing desks help back pain? - Example Health",
"link": "https://health.example.org/standing-desk-back-pain",
"displayedLink": "https://health.example.org",
"snippet": "Alternating between sitting and standing...",
"page": 2
}
]
}
}
Cost and depth
No include flag is needed; organic results come with every Google Search request.
| Request | Credits |
|---|---|
| 1 page | $0.00103 |
each extra page (pages 2 to 10) |
+$0.00071 per page fetched |
include.aioverview |
+$0.00071 once, when Google shows an overview |
include.paaAioverview |
0 |
A task reserves its maximum and is charged for the pages fetched. Ten pages as a task cost at most $0.00742. Most rank tracking needs one or two pages; fetch deeper only for keywords where you already rank there. pages cannot be combined with url.
Example: domain rank report across a keyword set
The script queues one task per keyword, waits for them, and reports for each tracked domain its best position per keyword, how many keywords it ranks in the top 3 and top 10, and its share of all first-page organic slots.
import os
import time
from collections import defaultdict
from datetime import date
from urllib.parse import urlparse
import requests
API = "https://api.answerline.dev"
HEADERS = {"Authorization": f"Bearer {os.environ['API_KEY']}"}
KEYWORDS = ["standing desk", "best standing desk for home office", "electric standing desk under 500"]
TRACKED = {"example-office.com", "deskmaker.example", "ergo.example"}
DAY = date.today().isoformat()
def run_tasks(tasks):
resp = requests.post(f"{API}/v1/async/task/batch", headers=HEADERS, json=tasks, timeout=60)
resp.raise_for_status()
pending = {item["task"]["id"]: tasks[item["index"]] for item in resp.json()["results"] if item["success"]}
done = []
while pending:
time.sleep(10)
for task_id in list(pending):
body = requests.get(f"{API}/v1/async/task/{task_id}", headers=HEADERS, timeout=30).json()
if body["task"]["status"] in ("COMPLETED", "FAILED"):
task = pending.pop(task_id)
if body["task"]["status"] == "COMPLETED":
done.append((task["payload"]["query"], body["response"]["result"]))
return done
def registrable(url):
host = (urlparse(url).hostname or "").removeprefix("www.")
return next((d for d in TRACKED if host == d or host.endswith("." + d)), None)
tasks = [
{
"taskType": "GOOGLE",
"payload": {"query": kw, "country": "US", "pages": 2},
"idempotencyKey": f"desks-rank-{i}-{DAY}",
}
for i, kw in enumerate(KEYWORDS)
]
best = defaultdict(dict) # domain -> keyword -> best position
page_one_slots = defaultdict(int)
total_page_one = 0
for keyword, result in run_tasks(tasks):
for item in result["organicResults"]:
if item["page"] == 1:
total_page_one += 1
domain = registrable(item["link"])
if not domain:
continue
if item["page"] == 1:
page_one_slots[domain] += 1
best[domain].setdefault(keyword, item["position"]) # first hit is the best position
for domain in sorted(TRACKED):
ranks = best[domain]
top3 = sum(1 for p in ranks.values() if p <= 3)
top10 = sum(1 for p in ranks.values() if p <= 10)
share = page_one_slots[domain] / (total_page_one or 1)
print(f"{domain:22} top3 {top3}/{len(KEYWORDS)} top10 {top10}/{len(KEYWORDS)} page-1 share {share:5.1%}")
for kw in KEYWORDS:
print(f" {kw:40} {ranks.get(kw, '-')}")
Because organicResults is ordered by position, the first listing found for a domain is its best rank. Store the full result per keyword and day: a later question such as “which URL ranked, and did it change” needs link history, not only the number.
Pitfalls
Position counts organic listings only, so position 1 can sit below ads, an AI Overview and a local pack. To explain traffic changes, read ads, aioverview and localResults from the same response alongside rank.
Rankings differ by country and over time. Change one dimension at a time and never mix countries in one series.
Decide whether blog.example.com counts as example.com and apply the rule everywhere. Match on link, the resolved destination, rather than displayedLink, which is display text.
date, sitelinks and redirectLink appear only when Google shows them. Use .get().
A single day’s drop is noise until it repeats. Track a rolling median, or re-run a keyword before alerting on a large move.
Ten pages for every keyword costs up to seven times as much as one. Tier the keyword list: shallow daily checks for most, deeper weekly checks for the rest.
Related
- Google Search engine guide: market targeting, async batches, webhooks and billing.
- Rank tracking and local rank tracking.
- Rank tracking pipelines with batches and tracking SERP feature changes.
- Other modules on the same page: ads, local pack, AI Overview.
- Web search API for grounding agents in organic results.
Questions
How many pages of Google organic results can I request?
Set pages from 1 to 10. One page costs $0.00103, and each extra page adds $0.00071, charged for the pages actually fetched, so ten pages cost at most $0.00742 before any AI Overview add-on.
Does position restart on page 2?
No. organicResults is one array across every page fetched, with position counted from 1 through the whole list and page recording which results page each listing appeared on.
Do organic positions include ads or SERP features?
No. organicResults contains organic listings only. Ads are returned in ads with their own block positions, and modules such as the AI Overview, People Also Ask and the local pack have their own fields.
Can I track rankings for a specific city or on mobile?
Yes. Send location (City,Region,Country, e.g. Austin,Texas,United States) or uule for a city, and device (desktop, mobile, ios or android) for the page. Keep them fixed within a tracking series.
What is redirectLink on an organic result?
When Google served a listing's link as a redirect, redirectLink holds Google's redirect URL and link holds the destination it resolves to. On most listings the key is absent.
More Google Search data
ads
The ads Google shows for a query, with block position, copy, destination and shopping-card prices.
People Also Ask
The People Also Ask questions Google clusters around a query, with their answers.
People are saying
The 'People are saying' discussion links Google shows for a query.
related searches
The related queries Google suggests at the foot of the page.
knowledge graph
The knowledge panel Google shows for an entity: description, website, profiles, key facts and Knowledge Graph ID.
local pack
Map-pack results with names, ratings and positions for local queries.
AI Overview
Google's AI Overview for a query: answer text, cited sources and citation pills, or null when absent.