AnswerLine Start free

, GEO · Fundamentals · Rank Tracking

Extending an SEO program to AI answers: the migration map

An SEO program already has keyword lists, market splits, a tracking schedule, competitor sets and a reporting routine, and nearly all of it carries over to AI answers. The unit of measurement changes: a position in a list becomes a mention or a citation inside a written answer, and a single daily check becomes one sample from a distribution. Below, each SEO practice is mapped to its AI-answer equivalent, followed by a pipeline that runs both on one topic list and a list of what to drop.

The map: what carries over

SEO practice AI-answer equivalent Where it lives in the API response
Keyword list Prompt set: the same intents, phrased as questions Request prompt
Market (country, city, language) country on every engine; ChatGPT and Gemini answer from 213 countries, Copilot, Perplexity and Grok from any country; Gemini also takes a US state; Google Search and AI Mode take location Request fields
Rank position Mention rate and citation share per prompt set result.text, result.sources[]
Position within the list Order of first mention in the answer text result.text
SERP features Answer blocks: citation pills, product listings result.citationPills[], result.inlineProducts[] (ChatGPT, with include.shopping)
Competitor rank diff Competitor mention and citation diff Same fields, other brands and domains
Scheduled rank checks Scheduled async batches POST /v1/async/task/batch
Rank tracker exports Stored raw JSON per run response.result of each finished task

The operating model carries over too. A keyword × market matrix becomes a prompt × market × engine matrix, and scheduled rank checks become async batches of up to 500 tasks, collected by polling or webhooks.

What changes shape

There is no single results page

Each engine searches, reads and cites differently. ChatGPT, Gemini, Perplexity, Copilot, Grok and AI Mode each need separate columns in every report. A blended “AI visibility score” hides the engine where you are absent, which is usually what you need to act on.

Results vary per run

A ranking checked twice in an hour usually returns the same position. An AI answer checked twice can name different brands and cite different pages. Treat each run as a draw: track rates over several runs, show the spread, and only call a change when it holds across runs. AI answer volatility and sampling vs census cover how many runs you need.

Answers are prose

A ranking is a position; an answer is written text. Your brand can be recommended, mentioned in passing, cited as evidence without being named, or absent. Mentions and citations are different events, and a report needs both.

Prompts are longer than keywords

“crm small business” becomes “What’s the best CRM for a 10-person sales team that already uses Gmail?” The added context (team size, existing tools, budget) changes which brands the answer recommends, so the prompt set needs several phrasings per intent, not one.

What stays the same

Migrating a keyword program

  1. Export the keyword list with its metadata: intent, market, priority, and the landing page you want to win.
  2. Rewrite keywords as prompts. Keep one row per intent and write two or three natural phrasings. Add comparison (“X vs Y for Z”) and problem (“how do I…”) prompts; they are where assistants recommend products. Prompt set design has templates.
  3. Map markets to request fields. Countries map to country. ChatGPT, Gemini, AI Mode and Google Search answer from 213 countries, and Copilot, Perplexity and Grok take any country; Gemini also takes a US state. Check each engine’s supported countries with GET /v1/countries?model=chatgpt (or gemini). For Google Search and AI Mode, keep your existing gl, hl and location settings.
  4. Choose engines per segment. Not every prompt needs every engine. Commercial prompts for a consumer product might warrant both ChatGPT and Gemini; a B2B developer tool might start with ChatGPT alone.
  5. Keep Google Search in the same run. Request the classic results with the AI Overview (include.aioverview) so you can compare ranking, AI Overview citation and assistant citation for the same topic.
  6. Schedule and store. Submit weekly batches with idempotency keys derived from prompt, market, engine and date, and store every raw response. Idempotency keys explained shows the pattern.
  7. Rebuild the report. Replace position charts with mention rate and citation share per engine, with competitor columns. An AI visibility report template is a starting layout.

Comparing rankings with citations

The most useful early report puts SEO and AI data side by side for each topic. For every keyword, compare the domains in Google’s organic top 10 with the domains cited in the AI Overview, in Gemini and in ChatGPT. Four cases come out:

Ranks organically Cited in answers Reading Action
Yes Yes Covered Protect the page; watch competitors
Yes No Engines prefer other sources Study the cited pages’ format and claims
No Yes Cited from outside classic top 10 Learn why; strengthen that page
No No Invisible Content or coverage gap

The pipeline below, in Python with requests, submits one batch with three tasks per keyword, waits for results, and prints the comparison.

import os
import time
from urllib.parse import urlparse

import requests

API = "https://api.answerline.dev"
HEADERS = {"Authorization": f"Bearer {os.environ['ANSWERLINE_API_KEY']}"}
MY_DOMAIN = "acme.com"
DAY = "2026-09-20"

topics = [
    {"keyword": "invoicing software freelancers",
     "prompt": "What is the best invoicing software for freelancers?"},
    {"keyword": "time tracking app agencies",
     "prompt": "Which time tracking app works best for a small agency?"},
]

def host(url):
    h = urlparse(url).hostname or ""
    return h[4:] if h.startswith("www.") else h

tasks = []
for i, t in enumerate(topics):
    tasks += [
        {"taskType": "GOOGLE",
         "payload": {"query": t["keyword"], "country": "US", "include": {"aioverview": {"markdown": False}}},
         "idempotencyKey": f"bridge-google-{i}-US-{DAY}"},
        {"taskType": "GEMINI",
         "payload": {"prompt": t["prompt"], "country": "US"},
         "idempotencyKey": f"bridge-gemini-{i}-US-{DAY}"},
        {"taskType": "CHATGPT",
         "payload": {"prompt": t["prompt"], "country": "US"},
         "idempotencyKey": f"bridge-chatgpt-{i}-US-{DAY}"},
    ]

batch = requests.post(f"{API}/v1/async/task/batch", headers=HEADERS, json=tasks, timeout=360)
batch.raise_for_status()
ids = {r["index"]: r["task"]["id"] for r in batch.json()["results"] if r["success"]}

def wait(task_id):
    while True:
        body = requests.get(f"{API}/v1/async/task/{task_id}", headers=HEADERS, timeout=30).json()
        if body["task"]["status"] in ("COMPLETED", "FAILED"):
            return body
        time.sleep(10)

for i, t in enumerate(topics):
    if any(i * 3 + k not in ids for k in range(3)):
        print(t["keyword"], "has a task that was not created; see the batch results")
        continue
    google, gemini, chatgpt = (wait(ids[i * 3 + k]) for k in range(3))
    if "FAILED" in (google["task"]["status"], gemini["task"]["status"], chatgpt["task"]["status"]):
        print(t["keyword"], "has a failed task; resubmit later")
        continue
    g, a, c = google["response"]["result"], gemini["response"]["result"], chatgpt["response"]["result"]

    organic = {host(r["link"]) for r in g.get("organicResults", [])[:10]}
    overview = g.get("aioverview") or {}
    cited = {
        "ai_overview": {host(s["url"]) for s in overview.get("sources", [])},
        "gemini": {host(s["url"]) for s in a.get("sources", [])},
        "chatgpt": {host(s["url"]) for s in c.get("sources", [])},
    }
    print(t["keyword"])
    print("  ranks top 10:", MY_DOMAIN in organic)
    for engine, domains in cited.items():
        print(f"  cited in {engine}:", MY_DOMAIN in domains, "| cited but not ranking:", sorted(domains - organic)[:5])

The polling loop keeps the example short. For hundreds of keywords, add a webhook to each task instead and let results arrive; see rank tracking pipelines with batches.

Fan-out coverage

Fan-out coverage, the share of an engine’s own searches you rank for, needs those searches. ChatGPT’s searchQueries[] (with include.searchQueries, which is free) comes back empty on the answers served today, so the check cannot be run for ChatGPT. The “cited but not ranking” domains above are the link between the two programs instead. Query fan-out covers the idea.

Worked cost example

Task per keyword Price (Starter)
GOOGLE with include.aioverview (base $0.00103, +$0.00071) $0.00174
GEMINI $0.0006
CHATGPT $0.0006
Total per keyword per run $0.00294

For example, 200 keywords run weekly is $0.588 per run and $2.35 over four runs. The tiers, and how 30-day spend lowers the price, are on the pricing page; cost planning goes further.

What to drop

Pitfalls during the migration

Start with the quickstart, or see rank tracking and AI visibility tracking for the two halves of the hybrid program.

Questions

Can I reuse my SEO keyword list for AI visibility tracking?

Yes, as the starting point. Rewrite each keyword as the question a buyer would ask an assistant, keep the intent grouping, and add comparison and problem prompts that keywords rarely capture.

What replaces rank position in AI answers?

Mention rate (the share of answers that name you) and citation share (your share of all cited sources), computed per engine and market over repeated runs. Where the answer is a list, the order in which brands are first mentioned in the text is a useful secondary signal.

Does technical SEO still matter for AI answers?

Yes. Google says a page must be indexed and eligible to show with a snippet to be a supporting link in AI Overviews or AI Mode, and OpenAI says sites that opt out of OAI-SearchBot are not shown in ChatGPT search answers.

How often should AI answers be tracked compared with rankings?

At least weekly per prompt, engine and market, with every raw response stored. Answers vary between runs, so trends across several runs are more reliable than any single check.

How do I connect SEO and GEO data?

Run the same topics through Google Search and the AI engines, then compare the domains that rank organically with the domains the answers cite. ChatGPT's searchQueries field comes back empty on the answers served today, so the cited domains are the link between the two.

Try it on your own prompts

100 free requests on any engine, no card. One POST returns the answer, sources and citations as JSON.

Keep reading