AnswerLine Start free

, GEO · Fundamentals

How AI engines choose which sources to cite

No major AI engine publishes how it chooses which pages to cite. Vendors do document that search-grounded answers are built by running web searches, sometimes several rewritten ones, and linking the pages used. That supports a working model: a page is cited only if one of those searches retrieves it and the model then selects it while writing. Retrieval is partly observable where an engine returns its searches. Selection is not, so any claim about what the model “prefers” is a hypothesis to measure on your own prompts before acting on it.

Definitions

What the platforms document

Google

AI features and your website (Google Search Central, checked 2026-09-17) says AI Overviews and AI Mode may issue multiple related searches across subtopics and data sources, which it calls query fan-out, and that AI Mode and AI Overviews may use different models and techniques, so the responses and links they show vary. To be eligible as a supporting link, a page must be indexed and eligible to be shown in Google Search with a snippet, with no additional technical requirements. Snippet controls (nosnippet, data-nosnippet, max-snippet, noindex) limit what is shown.

OpenAI

The ChatGPT search help article (checked 2026-09-17) says ChatGPT search typically rewrites the prompt into one or more targeted queries sent to search providers, may send more specific follow-up queries after reviewing initial results, and that responses using search may include inline citations and a Sources panel. The Publishers and Developers FAQ (checked 2026-09-17) says any public website can appear in ChatGPT search, and that sites should not block OAI-SearchBot for content to be included in summaries and snippets.

Perplexity

How does Perplexity work? (Perplexity Help Center, checked 2026-09-17) says it searches the internet and that each answer includes numbered citations linking to the original sources.

None of these pages describes ranking signals for citation selection.

The working model: retrieval, then selection

Stage 1: retrieval sets the candidate pool

A page that no fan-out query retrieves can’t be cited. Two consequences follow from the documentation above:

  1. Eligibility is a crawl and index question. For Google AI features, the bar is being indexed and snippet-eligible. For ChatGPT search, it includes not blocking OAI-SearchBot. Check these before anything else.
  2. The queries that matter are the engine’s. When a prompt is rewritten into several searches, a page can be a candidate without ranking for the literal prompt, and miss out despite ranking for it. ChatGPT query fan-out covers what those searches are.

Where the searches appear in responses:

Engine Fan-out field Notes
ChatGPT searchQueries[] Free with include.searchQueries: true; empty on the answers served today
Grok searchQueries[] Its web and X searches
Copilot searchQueries[] Coming; not returned yet
Perplexity none Not returned
Gemini none No search queries field
AI Mode none No search queries field

Grok is the only engine that returns its searches today: ChatGPT’s list comes back empty, and Copilot’s is not returned yet.

ChatGPT decides on its own whether to search; its request’s disableWebSearch changes nothing today. For a citation study, count answers with sources (provenance.webSearchTriggered is true) and report the share without.

Stage 2: selection is where the hypotheses live

From the candidate pool, the answer links a subset. The traits commonly credited for selection are plausible, but the engines have not confirmed any of them. Treat each as a hypothesis with a test:

Hypothesis Why it’s plausible How to test it
Pages with specific, extractable claims (a number, a definition, a named recommendation) get cited more A generated sentence needs a source that supports it directly Code cited vs retrieved-but-not-cited pages for “contains a direct answer sentence”; compare rates
Structured pages (question-shaped headings, tables, lists) get cited more Clean passages are easier to lift Same comparison, coding headings and tables
Topical fit beats domain size The page that answers the fan-out query is the best support Compare cited domains with top-ranking domains for the same fan-out queries
Recent pages win on time-sensitive prompts Freshness matters for prices, releases, news On ChatGPT, compare sources[].datePublished (omitted when unknown) between time-sensitive and evergreen prompt groups
Engines differ in how many sources they cite and how much they overlap with Google Different retrieval providers and models Source counts per engine; domain overlap between engines and with Google organic results

The control group is the main design choice. Google organic results for the engine’s own fan-out queries, where it returns them, give you pages that were plausibly retrieved but not cited. For ChatGPT, whose list is empty today, Google organic results for the prompt itself are a looser control. Cited pages alone show what winners look like; comparing them with that set shows what separates them from the rest.

Measuring it per engine

The script below runs one prompt through ChatGPT, Gemini, Copilot, Perplexity and Grok, collects cited domains and any fan-out queries, then runs the prompt and each fan-out query through Google Search to build the organic comparison set. It uses synchronous calls for readability; for a full study, submit the same payloads as async batches.

import os
from itertools import combinations
from urllib.parse import urlsplit

import requests

API = "https://api.answerline.dev"
HEADERS = {"Authorization": f"Bearer {os.environ['API_KEY']}", "Content-Type": "application/json"}

ENGINES = {
    "chatgpt": ("/v1/monitor/chatgpt", {}),
    "gemini": ("/v1/monitor/gemini", {}),
    "copilot": ("/v1/monitor/copilot", {}),
    "perplexity": ("/v1/monitor/perplexity", {}),
    "grok": ("/v1/monitor/grok", {}),
}


def call(path: str, body: dict) -> dict:
    resp = requests.post(API + path, json=body, headers=HEADERS, timeout=330)
    resp.raise_for_status()  # a 500/502 from a synchronous call is final: record it, don't retry
    return resp.json()["result"]


def domain(url: str) -> str:
    return urlsplit(url).netloc.lower().removeprefix("www.")


def study(prompt: str, country: str = "US") -> dict:
    out = {"engines": {}, "queries": {prompt}, "organic": set()}
    for name, (path, extra) in ENGINES.items():
        r = call(path, {"prompt": prompt, "country": country, **extra})
        sources = [s for s in r.get("sources", []) if s.get("url")]
        out["engines"][name] = {"count": len(sources), "domains": {domain(s["url"]) for s in sources}}
        out["queries"].update(r.get("searchQueries", []))
    for q in out["queries"]:
        g = call("/v1/monitor/google", {"query": q, "country": country})
        out["organic"].update(domain(o["link"]) for o in g.get("organicResults", []) if o.get("link"))
    return out


def report(s: dict) -> None:
    for name, e in s["engines"].items():
        in_organic = len(e["domains"] & s["organic"]) / len(e["domains"]) if e["domains"] else 0.0
        print(f"{name}: {e['count']} sources, {len(e['domains'])} domains, {in_organic:.0%} also in organic")
    for a, b in combinations(s["engines"], 2):
        da, db = s["engines"][a]["domains"], s["engines"][b]["domains"]
        jaccard = len(da & db) / len(da | db) if da | db else 0.0
        print(f"overlap {a}/{b}: {jaccard:.2f}")


report(study("Which password manager is best for a small business?"))

The organic set pools the prompt and every fan-out query from every engine, a deliberately broad control; for a stricter test, keep each engine’s queries and organic results separate. One prompt proves nothing: run a fixed set and look at distributions per engine, not single values. Run your own AI citation study covers study design.

What it costs

At Starter-tier prices: ChatGPT $0.0006, Gemini $0.0006, Copilot $0.00274, Perplexity $0.0015 and Grok $0.00218, so $0.00762 per prompt for the five engines, plus $0.00103 per query through Google.

For an illustrative study of 50 prompts, counting one Google query each (the prompt itself; every fan-out query adds $0.00103): 50 × $0.00762 = $0.381 plus 50 × $0.00103 = $0.0515, so $0.4325. New accounts get 100 free requests (each engine call or Google query is one), enough to validate the pipeline on a handful of prompts first. See /docs/credits and cost planning.

Reading citations correctly

The working loop

  1. Fix eligibility. Confirm OAI-SearchBot and Googlebot can crawl your key pages and that snippet controls aren’t suppressing them.
  2. Collect the candidate pool. Run your prompt set per engine, and Google organic results for the prompts and for any fan-out queries an engine returns.
  3. Label cited vs not cited. For pages in the pool, mark which were cited, per engine.
  4. Test one hypothesis at a time. Code the trait (direct answer sentence, table, date) on both groups and compare rates.
  5. Change pages based on what held up. Update or publish pages where your data shows a gap. Structured data and AI visibility covers one frequently raised trait.
  6. Re-run on the same prompts. Compare citation rates over several runs before concluding a change worked.

Field details for each engine are on /engines/chatgpt/sources and the other engine pages.

Questions

Do AI engines publish how they pick citations?

Not in detail. Google, OpenAI and Perplexity document that their answers are built from web searches and link to sources, and Google and OpenAI describe running several related or rewritten searches, but none publishes a selection algorithm.

What does a page need to be eligible for citation in Google AI Overviews or AI Mode?

Google Search Central says a page must be indexed and eligible to be shown in Google Search with a snippet, and that there are no additional technical requirements. Snippet controls such as nosnippet and max-snippet limit what is shown.

What does a site need to appear in ChatGPT search?

OpenAI's Publishers and Developers FAQ says any public website can appear, and that for content to be included in summaries and snippets the site should not block OAI-SearchBot.

Do ChatGPT, Perplexity and Gemini cite sources differently?

The same prompt can return different numbers and sets of sources on different engines, but claims about each engine's preferences are not publicly established. Measure it for your own prompts by comparing source counts per engine, domain overlap between engines, and overlap with Google organic results for the same prompts.

Which engines expose the searches they ran?

ChatGPT has a searchQueries field (include.searchQueries, free), but it comes back empty on the ChatGPT answers served today. Grok returns searchQueries: its web and X searches. Copilot's searchQueries is coming. Perplexity, Gemini and AI Mode return no search queries.

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