Structured data does not get a page quoted by AI answer engines on its own — but the entity types you declare, the way you nest them, and where the JSON-LD is delivered decide whether a retrieval system can resolve your page to a real-world entity it is willing to attribute. The short answer: ship one server-rendered @graph block that links Organization, Person (the author), Article and the page's specific entity type together with stable @id values and sameAs links to external identifiers. That pattern is what correlates with citations in ChatGPT, Perplexity and Google AI Overviews, not the number of schema types you stack on a page.
How AI answer engines actually consume your markup
An AI answer engine does roughly four things: retrieves candidate passages, chunks them, works out who is making the claim, then decides whether to attribute that claim to a named source. JSON-LD helps at steps three and four. It does very little at step one, which is why marking up a thin page perfectly still produces no citations.
What markup buys you is disambiguation. When a model encounters the string "Rankora" or "Jane Doe", structured data tells it whether that string maps to an organisation with a Wikipedia entry, a person with a LinkedIn profile, or nothing at all. Entities that resolve to external identifiers get attributed; entities that resolve to nothing get summarised without credit. This is why sameAs is the single most under-used property in technical SEO.
Two practical consequences follow. First, consistent @id values across every page of the site matter more than any individual property. Second, the markup must be present in the initial HTML response, because many retrieval crawlers do not execute JavaScript or do so inconsistently.
Which entity types correlate with being quoted
Most generic advice stops at "add Article schema". In practice, the types that influence attribution fall into three groups.
- Identity types —
OrganizationandPerson. Includename,url,logo,jobTitle,worksFor,knowsAboutandsameAspointing at Wikipedia/Wikidata, LinkedIn, Crunchbase, GitHub or an ORCID where relevant. - Container types —
Article,BlogPosting,TechArticle, plusWebSiteandBreadcrumbList. These carrydatePublished,dateModified,authorandpublisheras references, not inline duplicates. - Topic types — the type that describes what the page is actually about:
SoftwareApplicationfor a tool page,Productfor commerce,DefinedTermfor glossary entries,ItemListfor comparisons and roundups,HowTowhere a genuine procedure exists.
FAQPage sits in its own category and needs a caveat — see below. Note that Google deprecated HowTo rich results in 2023 and restricted FAQ rich results to a small set of authoritative government and health sites. Do not remove these types solely because the visual feature disappeared: the Q&A pairs remain useful as clean, self-contained chunks that models can lift and attribute.
Nesting patterns that survive entity resolution
Inline nesting (author as a full object inside BlogPosting) works, but it forces you to repeat the author's details on every article, which drifts out of sync the moment someone changes job title. Reference nesting via @graph and @id keeps a single canonical description of each entity.
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://example.com/#organization",
"name": "Example Ltd",
"url": "https://example.com/",
"sameAs": [
"https://en.wikipedia.org/wiki/Example",
"https://www.linkedin.com/company/example"
]
},
{
"@type": "Person",
"@id": "https://example.com/authors/jane-doe/#person",
"name": "Jane Doe",
"jobTitle": "Head of SEO",
"worksFor": { "@id": "https://example.com/#organization" },
"sameAs": ["https://www.linkedin.com/in/janedoe"]
},
{
"@type": "BlogPosting",
"@id": "https://example.com/blog/post/#article",
"headline": "Post title",
"datePublished": "2025-02-11",
"dateModified": "2025-02-11",
"author": { "@id": "https://example.com/authors/jane-doe/#person" },
"publisher": { "@id": "https://example.com/#organization" },
"isPartOf": { "@id": "https://example.com/#website" },
"about": { "@id": "https://example.com/#topic" }
}
]
}
Three rules keep this pattern clean. Use absolute URLs for every @id, because relative identifiers break when the graph is copied. Never emit two nodes with the same @id and contradictory properties. And link the topic node (about, mentions) to something external where a stable identifier exists — a Wikidata Q-ID, a product SKU, an ISO standard — rather than to your own tag page.
Placement and delivery
Where the script tag goes is less important than how it arrives. Put the JSON-LD in the <head> or at the end of <body>, rendered server-side with the rest of the document. Client-side injection via tag managers or React hydration is the most common reason markup that validates in the Rich Results Test never influences retrieval — the crawler fetched the page before the script ran.
- One
@graphblock per page. Multiple competing blocks invite conflicting values. - Site-wide entities (
Organization,WebSite) can be repeated on every page as long as properties match exactly. - Keep total inline JSON-LD under roughly 100KB; oversized graphs slow parsing for no benefit.
- Validate with the Schema Markup Validator as well as Google's Rich Results Test — the latter only checks types that produce rich results.
- Confirm GPTBot, OAI-SearchBot, PerplexityBot and Googlebot are not blocked in
robots.txtor by a WAF rule before you blame the markup.
A site audit that flags missing author nodes, orphaned @id references and duplicate entities across templates will catch most of this quickly; Rankora's technical audit surfaces schema errors alongside the crawl issues that usually suppress indexing in the first place.
FAQ schema and answer-shaped content
Keep FAQPage even without the rich result. Models retrieve passages, and a question–answer pair with a concise answer of 40 to 60 words is close to the ideal retrieval unit. Mark up the page's real Q&A content, not a set of questions invented for markup, and make sure the visible answer text matches the acceptedAnswer text — mismatches between markup and rendered copy are treated as spam signals rather than neutral errors.
The same logic applies to mainEntity on article pages: declare the primary question the page answers, then answer it in the first paragraph. Answer engines reward pages whose opening sentence is a complete, extractable claim.
An implementation checklist
- Define canonical
@idURLs for the organisation, each author and each core topic, and document them so templates stay consistent. - Emit one
@graphper page, server-rendered, referencing those identifiers. - Populate
sameAswith every verified external profile you control. - Add the correct topic type —
SoftwareApplication,Product,DefinedTerm,ItemList— not justArticle. - Keep
dateModifiedgenuinely accurate; stale timestamps are visible to every crawler. - Verify the rendered HTML, not the source template, contains the script tag.
- Re-validate after every template change — schema breaks silently.
Structured data will not rescue thin content, but it removes the ambiguity that stops a model attributing good content to you. Treat entity identity as infrastructure and the citations follow.
Tagged



