Does structured data help AI engines cite you?
No public source we could find shows that schema.org markup causes AI engines to cite a page. Google says its AI features need no special markup, and Microsoft’s reported statement is only that markup helps its models understand content. Structured data is still worth adding for what it is documented to do, and whether it moves your AI citations can be settled with a controlled test on your own pages. Below: what is documented, what is assumed, and the experiment with code.
Definitions
- Structured data is, in Google’s words, a standardized format for providing information about a page and classifying its content (Introduction to structured data, checked 2026-09-17).
- Schema.org is the shared vocabulary most structured data uses: a collaborative community project to create and maintain schemas for structured data on the internet, founded by Google, Microsoft, Yahoo and Yandex (schema.org about page, checked 2026-09-17).
- JSON-LD is one of three formats Google supports, alongside Microdata and RDFa. Google recommends JSON-LD where your setup allows it, as the easiest to implement and maintain across many pages (same Google page).
- AI citation here means a page URL in an answer’s source list, returned as
result.sources[]by the ChatGPT, Gemini, Perplexity, Copilot, Grok and AI Mode endpoints.
What the primary sources say
Google: no special markup for AI features
Google’s AI features and your website page (checked 2026-09-17) states:
- There are no additional requirements to appear in AI Overviews or AI Mode, and no other special optimizations are necessary.
- You do not need to create new machine-readable files, AI text files or markup to appear in these features, and there is no special schema.org structured data you need to add.
- To be shown as a supporting link, a page must be indexed and eligible to be shown in Google Search with a snippet.
- What these features can show from a page is controlled with the usual
nosnippet,data-nosnippet,max-snippetandnoindexcontrols.
So for Google’s AI features, the documented levers are indexability and snippet eligibility, not markup.
Google: markup has rules and no guarantees
Google’s structured data general guidelines (checked 2026-09-17) say Google does not guarantee that structured data will show up in search results even when a page is marked up correctly, and that you must not mark up content that is not visible to readers of the page. The introduction page adds that all required properties must be present for a page to be eligible for enhanced display.
OpenAI: which crawler matters for ChatGPT search
OpenAI’s crawler documentation (checked 2026-09-17) says OAI-SearchBot is used to surface websites in ChatGPT’s search features, and sites that opt out of it are not shown in ChatGPT search answers. GPTBot crawls content that may be used for training, and disallowing it does not affect ChatGPT search results. ChatGPT-User fetches pages for user-initiated actions. If you want ChatGPT to cite you, check that robots.txt does not block OAI-SearchBot. Markup is not mentioned as a factor.
Microsoft: markup helps understanding, per a conference statement
The closest thing to a vendor endorsement is secondhand. Search Engine Roundtable reported on 20 March 2025 (checked 2026-09-17) that Fabrice Canel of Microsoft Bing said at SMX Munich that schema markup helps Microsoft’s LLMs understand content. As reported, the statement is about understanding, not about which pages Copilot cites, and it is not in Microsoft’s written documentation.
What we could not find
None of the sources above says schema.org markup determines whether an assistant cites a page, and we found no public controlled study establishing that causal effect. Claims that “schema gets you cited by ChatGPT” are, as far as the public record we checked goes, assumptions. The effect may exist; for your pages it is unmeasured.
Why markup might still matter
These are hypotheses, not documented engine behavior:
- Markup restates key facts in machine-readable form. A
Productwithoffers.price, or anArticlewithdatePublishedandauthor, gives any system reading the page an unambiguous version of facts that prose can bury. - Markup that earns rich results may change click and link patterns in classic search, which can indirectly affect which pages get referenced elsewhere.
- Adding markup prompts a content review. Teams that audit a page for accurate
Productdata often also fix vague copy, missing prices and stale dates, which are changes that make a sentence easier to attribute.
The last point is also the main measurement trap: if you change content and markup together, you cannot tell which one moved citations.
What reliably helps a page be citable
Independent of markup, these follow from how cited answers work (an engine searches, reads pages, and attributes claims to sources):
- Be reachable: indexed and snippet-eligible in Google; not blocking the search crawler of the engine you care about.
- Put the answer in the page text. A claim that only exists in an image, a PDF behind a form or an interactive widget is harder to quote.
- Make specific, attributable claims. “Plans start at $12 per user per month” can be cited; “competitive pricing” cannot.
- Use headings that restate the question, and short sections, tables and lists that can be lifted as a unit.
- Date and attribute: visible publish and update dates and a named author or organization.
The GEO research paper by Aggarwal et al. reported that adding quotations, statistics and source citations to content improved visibility in generative engine responses on its benchmark, while keyword stuffing did not (arXiv 2311.09735, checked 2026-09-17). That is about content, not markup, and was measured in the authors’ own setup.
Markup done correctly
If you add markup, mirror the visible page exactly. A Product page example in JSON-LD:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Acme Invoice Pro",
"description": "Invoicing software for freelancers with recurring invoices and online payments.",
"brand": { "@type": "Brand", "name": "Acme" },
"offers": {
"@type": "Offer",
"price": "12.00",
"priceCurrency": "USD",
"url": "https://acme.com/pricing"
}
}
</script>
Every value here must also appear on the page itself. Validate with Google’s Rich Results Test before shipping.
A controlled experiment
Step 1: choose matched page groups
Pick 20 or more comparable pages (for example product or comparison pages in one category) that currently lack the markup type you want to test. Split them randomly into a treatment group that gets markup and a control group that does not. Random assignment matters; hand-picking your best pages for treatment biases the result.
Step 2: write prompts that should cite those pages
For each page, write two or three prompts a buyer would ask where that page is a plausible source. Keep the prompt set fixed for the whole experiment.
Step 3: record a baseline
Run every prompt on the engines you care about, several times over two to four weeks, and store the source lists. Answers vary per run, so one baseline run is not enough. AI answer volatility explains why.
Step 4: change only the markup
Deploy markup to the treatment pages. Leave everything else on both groups unchanged, including copy and internal links. Record the deploy date and confirm the pages were recrawled (for Google, Search Console’s URL inspection shows the last crawl).
Step 5: measure after the change
Run the same prompts on the same schedule for the same length of time.
Step 6: compare changes, not levels
Compute citation rate (runs where the page is cited / runs where it could be) for each group before and after. The effect estimate is the treatment group’s change minus the control group’s change. The control absorbs engine-wide shifts, such as a model update, that would otherwise look like a markup effect.
The measurement code
This Python script (using requests) submits one batch covering each prompt on ChatGPT and Gemini, then collects which of your experiment pages each engine cited. Run it on your schedule and append the output to a table. A GOOGLE task with include.aioverview adds Google’s AI Overview, whose citations are in result.aioverview.sources.
import os
import time
from collections import defaultdict
import requests
API = "https://api.answerline.dev"
HEADERS = {"Authorization": f"Bearer {os.environ['ANSWERLINE_API_KEY']}"}
RUN = "2026-09-21"
# page URL -> group, and prompts that should cite each page
PAGES = {
"https://acme.com/invoice-pro": "treatment",
"https://acme.com/time-tracker": "control",
}
PROMPTS = {
"https://acme.com/invoice-pro": ["What is the best invoicing software for freelancers?"],
"https://acme.com/time-tracker": ["Which time tracking app is best for a small agency?"],
}
def norm(url):
return url.split("#")[0].split("?")[0].rstrip("/").replace("://www.", "://")
tasks, meta = [], []
for page, prompts in PROMPTS.items():
for p_i, prompt in enumerate(prompts):
for task_type, payload in [
("CHATGPT", {"prompt": prompt, "country": "US"}),
("GEMINI", {"prompt": prompt, "country": "US"}),
]:
tasks.append({
"taskType": task_type,
"payload": payload,
"idempotencyKey": f"sd-exp-{norm(page)}-{p_i}-{task_type}-{RUN}",
})
meta.append((page, task_type))
batch = requests.post(f"{API}/v1/async/task/batch", headers=HEADERS, json=tasks, timeout=360)
batch.raise_for_status()
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)
counts = defaultdict(lambda: [0, 0]) # (group, engine) -> [cited, runs]
for item in batch.json()["results"]:
if not item["success"]:
continue
page, engine = meta[item["index"]]
done = wait(item["task"]["id"])
if done["task"]["status"] != "COMPLETED":
continue # failed tasks are not charged; do not count them as "not cited"
sources = done["response"]["result"].get("sources", [])
cited = norm(page) in {norm(s["url"]) for s in sources}
key = (PAGES[page], engine)
counts[key][0] += cited
counts[key][1] += 1
for (group, engine), (cited, runs) in sorted(counts.items()):
print(RUN, group, engine, f"{cited}/{runs}")
For larger page sets, replace the polling with webhooks.
Worked example
Suppose, over four weeks before and four weeks after, ChatGPT citation rates came out as follows (invented numbers):
| Group | Before | After | Change |
|---|---|---|---|
| Treatment (markup added) | 18% | 27% | +9 points |
| Control (no change) | 20% | 26% | +6 points |
Read naively, markup added 9 points. Against the control it added 3 points (9 minus 6), because the control group rose by 6 points without any change, probably from something engine-wide. With a small number of pages and runs, a 3-point difference may be noise; repeat the comparison over more runs before acting on it.
What the experiment costs
Price per prompt per run, at the Starter tier:
| Task | Price |
|---|---|
CHATGPT |
$0.0006 |
GEMINI |
$0.0006 |
| Total | $0.0012 |
For example, 40 prompts run weekly for eight weeks (four baseline, four after) is 40 × $0.0012 × 8 = $0.384. A GOOGLE task with include.aioverview adds $0.00174 per prompt per run, for $0.9408 in total. See pricing and cost planning.
Pitfalls
- Changing content with markup. Any copy edit in the treatment group confounds the result.
- Markup that does not match the page. It breaks Google’s guidelines and invalidates the test.
- Too few runs. Single runs swing widely. Use several runs per period per prompt.
- URL mismatches. Cited URLs may carry tracking parameters, trailing slashes or
www. Normalize before matching, as the script does. - Counting failed tasks as misses. A
FAILEDtask says nothing about citation. - Measuring one engine and generalizing. Report per engine; an effect on ChatGPT says nothing about Gemini.
Further reading
How AI engines choose citations covers the selection side, and running your own AI citation study extends this design to other page changes.
To run the prompts, start with the quickstart or the ChatGPT engine page.
Questions
Do I need schema.org markup to appear in Google's AI Overviews or AI Mode?
No. Google's AI features documentation says there is no special schema.org structured data you need to add, and no new machine-readable files or AI text files are required. A page must be indexed and eligible to show in Search with a snippet.
Does structured data make ChatGPT or Perplexity cite a page?
We found no public documentation from those engines that says so. The effect is unproven, so measure it with a controlled before-and-after test on your own pages.
Has Microsoft said schema markup matters for Copilot?
Search Engine Roundtable reported in March 2025 that Microsoft Bing's Fabrice Canel said at SMX Munich that schema markup helps Microsoft's LLMs understand content. The reported statement concerns understanding, not which pages get cited.
Which structured data format should I use?
Google supports JSON-LD, Microdata and RDFa, and recommends JSON-LD where your setup allows, because it is the easiest to implement and maintain across many pages.
Does blocking GPTBot remove my site from ChatGPT answers?
According to OpenAI's crawler documentation, GPTBot is used for training data and blocking it does not affect ChatGPT search results. Opting out of OAI-SearchBot is what keeps a site from being shown in ChatGPT search answers.
How do I test whether markup changes AI citations?
Pick matched groups of pages, add markup to one group only, and run the same prompts on each engine repeatedly before and after the change. Compare the change in citation rate for the treated group with the change in the control group.