Research · Schema.org & AI

The Schema.org DebateDoesn’t feed the LLM. Feeds what the LLM calls.

The AEO industry oversold schema as an LLM unlock. The pushback — that transformers don’t read schema as schema, they read tokens — is right for the general case. But it’s wrong by omission for local. Every major AI grounds hotel queries against Google Maps / Places, which sit downstream of schema and the Knowledge Graph. The loop is real. It’s also narrower than the AEO pitch.

Two claims, only one is true

The whole AEO/GEO marketing layer rests on conflating two distinct claims:

Claim 1: Schema is useful in classical search

True

Rich results (prices, ratings, event times, FAQs) on Google SERPs. Knowledge Graph entity disambiguation. Voice assistants pulling structured fields. None of that goes away. If you’re responsible for technical SEO, keep implementing schema where it earns its keep.

Claim 2: Schema feeds the LLM

False

Schema cannot reach into a transformer and improve its comprehension of your prose. The model isn’t architected to read schema as schema — it receives whatever text the search or retrieval layer fetched and chose to include, and processes that text as language tokens. The JSON-LD block on your hotel page doesn’t make the model “understand” you better. That part of the AEO pitch is just wrong.

But for hotels, schema still reaches the LLM — via a loop

For local / POI intent, the conclusion “schema doesn’t matter for AI search” is wrong. Look at where the major AIs actually source their hotel answers:

Gemini — Google. Maps, Places, Knowledge Graph natively.
ChatGPT — per the anatomy capture, the pipeline blends Google Places among 5+ providers.
Claude — per the Claude capture, one direct call to Google Places per hotel query.

The grounding source the LLM calls is fed by schema (entity reconciliation into the KG, amenity markup, sameAs to Wikidata) and by the Knowledge Graph itself. So: schema doesn’t feed the LLM — but it feeds what the LLM calls. Same effect, different mechanism. Different mental model.

Claude.ai rendering a map of Marseille with five hotel pins and a side panel listing ALEX Hôtel & Spa (4.5★), Hôtel Carré Vieux Port (4.3★), and Hôtel Maison Montgrand (4.1★). The data comes from a places_search tool call to Google Places.
The loop, visible. Claude’s answer to “best 3-star hotels in Marseille.” The map and side panel are populated by a single places_search call — star rating, photos, address, review count all sourced from Google Places, which in turn is fed by GBP and by the schema/sameAs signals that reconcile this hotel to its KG entity. The transformer never saw the JSON-LD on the hotel’s site. It saw the Places response.

The careful version

Two refinements before you re-stamp every page with @type: Hotel:

GBP is the API surface — not the whole entity

Look at a Places API response in an LLM tool call and most of what you see — rating, review_count, hours, photos, address — comes from Google Business Profile. That’s what is visible to the model at call time, and it makes schema look redundant. But GBP is a narrow surface: no amenities field, no room categories, limited typed attributes. The fuller hotel entity sitting behind the Knowledge Graph has more on it — and that’s where your Hotel schema does work: amenity / starRating / category markup feeds KG enrichment that GBP can’t express, and sameAs reconciles your hotel to its OTA profiles (Booking, TripAdvisor, niche aggregators) so those profiles route grounding traffic to you, not to a near-duplicate listing. The clean way to say it: schema → entity graph → grounding source → LLM. Not the linear “schema → LLM” the AEO pitch implies — but also not the dismissive “GBP is all that matters” that the API view encourages.

Not the FAQ schema you think you need

Generic AEO advice for any business is “add FAQ schema, add HowTo schema, add Article schema.” For hotels that’s not where the leverage is. The three types that actually move the needle in the grounding loop are unsexy and specific:

  • @type: Hotel — not LocalBusiness, not Organization. The category gate. KG entity reconciliation hinges on classifying you correctly in the first place.
  • sameAs — an array of canonical URLs (Wikidata, your Booking listing, your TripAdvisor profile, your Google Maps URL). This is how your hotel page on your own site gets fused with the OTA profiles LLMs cite. Without it, aggregators get the grounding traffic; with it, you do.
  • starRating — specifically the typed Rating object with ratingValue, not a number in your prose. AI hotel queries are sliced by category bucket (“best 4-star”, “luxury”, “budget”) and if your category is wrong or missing, you don’t appear in the relevant bucket — see the rankings consistency study on category gating.
  • alternateName — the most underused field in hotel schema, and the one that solves a real and growing problem: hotels rebrand all the time. AIs trained on pre-rebrand data still recommend the old name. A specific case: Hôtel de la Paix in Beaune is now Alfred Hotel Beaune. With alternateName: ["Hôtel de la Paix"] on the live page’s schema, the entity reconciliation can route the old query to the new identity. Without it, you’re fighting your own training data forever. sameAs handles cross-platform identity (you = your Booking listing); alternateName handles cross-time identity (you now = you then).

FAQ blocks may earn a rich result on a SERP, but they don’t change how a hotel surfaces in an AI answer. The boring four above do.

What AEO templates ship
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "Hôtel Example",
  "description": "A wonderful hotel in Paris...",
  "address": { "@type": "PostalAddress", ... },
  "telephone": "+33...",
  "openingHours": "Mo-Su 00:00-24:00",
  "priceRange": "$$$",
  // FAQPage — fine if relevant, just not the main lever
  "mainEntity": [{
    "@type": "Question",
    "name": "Do you have free wifi?",
    "acceptedAnswer": { "@type": "Answer", ... }
  }]
  // no sameAs, no starRating, wrong @type
}
Wrong category, no entity reconciliation, no star bucket. Earns nothing in the grounding loop.
What the loop actually consumes
{
  "@context": "https://schema.org",
  "@type": "Hotel",
  "name": "Alfred Hotel Beaune",
  "alternateName": ["Hôtel de la Paix"],
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "5 rue de l'Hôtel-Dieu",
    "addressLocality": "Beaune",
    "postalCode": "21200",
    "addressCountry": "FR"
  },
  "starRating": {
    "@type": "Rating",
    "ratingValue": "4"
  },
  "sameAs": [
    "https://www.wikidata.org/wiki/Q123456",
    "https://www.booking.com/hotel/fr/example.html",
    "https://www.tripadvisor.com/Hotel_Review-g187147-d000000.html",
    "https://maps.google.com/?cid=00000000000000000000"
  ],
  "amenityFeature": [
    { "@type": "LocationFeatureSpecification", "name": "Free WiFi", "value": true },
    { "@type": "LocationFeatureSpecification", "name": "Breakfast",  "value": true }
  ]
}
Right category, OTA profiles reconciled to you, typed star bucket, amenities GBP can’t express.

Amenities and HotelRoom — the part GBP can’t encode

Schema can encode a lot more than GBP exposes. You can ship typed amenities, room subtypes, bed configurations, accessibility flags, room sizes — and you control all of it directly from your CMS:

{
  "@type": "Hotel",
  "amenityFeature": [
    { "@type": "LocationFeatureSpecification", "name": "WiFi", "value": true },
    { "@type": "LocationFeatureSpecification", "name": "Pool", "value": true },
    { "@type": "LocationFeatureSpecification", "name": "Pet-friendly", "value": false }
  ],
  "containsPlace": [{
    "@type": "HotelRoom",
    "name": "Deluxe Suite",
    "bed": { "@type": "BedDetails", "numberOfBeds": 1, "typeOfBed": "King" },
    "occupancy": { "@type": "QuantitativeValue", "maxValue": 2 },
    "floorSize": { "@type": "QuantitativeValue", "value": 35, "unitCode": "MTK" },
    "amenityFeature": [
      { "@type": "LocationFeatureSpecification", "name": "Balcony", "value": true }
    ]
  }]
}

GBP gives you a narrow set of typed amenities (pool, parking, WiFi, breakfast) and no room-level structure at all — no bed types, no floor size, no accessibility per room. Your Hotel schema is the natural place to expose all of that. The markup is one-time, it’s entirely under your control, and it feeds the same entity graph the LLMs ground against. It’s the easiest delta over GBP to ship.

Two surfaces, two strategies

A hotelier’s own schema mostly affects how their own site surfaces — rich results, KG card, voice. What affects how they appear inside an LLM answer is whether the grounding sources (Maps/Places, OTAs, niche aggregators) carry them correctly. So the practical takeaway splits: keep schema on your site for classical SEO + KG hygiene; for AI visibility, also audit how you’re represented in the upstream sources LLMs actually call.

The actual finding

Don’t double down on AEO schema theatre. Don’t throw schema out either. For hotels (and for local intent generally), the right framing is: schema doesn’t feed the LLM, but it feeds what the LLM calls. The same playbook that earned you Knowledge Graph hygiene last decade earns you grounding-source hygiene this one. The optimisation game stays similar; only the target downstream of it has changed.

Frequently Asked Questions

Summarize with AI

ChatGPTPerplexityClaudeGeminiGrok

Related research