XooCode(){

Hotel

Hotel is a LodgingBusiness subtype (which itself extends LocalBusiness) for hotels, motels, and similar overnight-stay businesses. Google uses it for the hotel knowledge panel, Google Hotels integration, and Google Maps listings. The markup feeds hotel search filters for star rating, amenities, check-in times, and pet policies.

Hotel adds hospitality-specific properties to the LocalBusiness base: starRating, checkinTime/checkoutTime, amenityFeature, numberOfRooms, and petsAllowed. These map directly to the filters travelers use when searching for hotels, so including them is the difference between appearing in filtered results or being skipped.

Full example of schema.org/Hotel json-ld markup

The markup is verified as valid with Rich Results Test from Google.

Highlight legend:Required by GoogleRecommendedOptional
schema.org/Hotel
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@id": "https://hoteldunmore.com#hotel",
  "@type": "Hotel",
  "name": "Hotel Dunmore",
  "description": "Boutique hotel in downtown Dunmore, walking distance from The Thunderdome conference center and Xoo Code Shop. 48 rooms, rooftop bar, free parking.",
  "url": "https://hoteldunmore.com",
  "image": [
    "https://hoteldunmore.com/images/facade-1x1.jpg",
    "https://hoteldunmore.com/images/facade-4x3.jpg",
    "https://hoteldunmore.com/images/facade-16x9.jpg"
  ],
  "telephone": "+1-570-555-0200",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "450 Main Street",
    "addressLocality": "Dunmore",
    "addressRegion": "PA",
    "postalCode": "18512",
    "addressCountry": "US"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 41.4195,
    "longitude": -75.6340
  },
  "starRating": {
    "@type": "Rating",
    "ratingValue": "3"
  },
  "numberOfRooms": 48,
  "checkinTime": "15:00:00",
  "checkoutTime": "11:00:00",
  "petsAllowed": "Dogs under 30 lbs welcome, $25 per night pet fee",
  "priceRange": "$$",
  "amenityFeature": [
    { "@type": "LocationFeatureSpecification", "name": "Free WiFi", "value": true },
    { "@type": "LocationFeatureSpecification", "name": "Free Parking", "value": true },
    { "@type": "LocationFeatureSpecification", "name": "Rooftop Bar", "value": true },
    { "@type": "LocationFeatureSpecification", "name": "Fitness Center", "value": true },
    { "@type": "LocationFeatureSpecification", "name": "Swimming Pool", "value": false },
    { "@type": "LocationFeatureSpecification", "name": "Airport Shuttle", "value": false }
  ],
  "openingHoursSpecification": {
    "@type": "OpeningHoursSpecification",
    "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
    "opens": "00:00",
    "closes": "23:59"
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.1",
    "reviewCount": "312",
    "bestRating": "5"
  }
}
</script>

starRating

starRating is a Rating object with ratingValue (the star count, typically 1-5) and optionally an author (the rating authority, like "Forbes Travel Guide" or "AAA"). This is the official star classification, not the guest review average. The guest review average goes in aggregateRating. Google displays both in the hotel knowledge panel but labels them differently.

amenityFeature

amenityFeature takes an array of LocationFeatureSpecification objects, each with a name and a value (true/false). This is how you declare amenities: free WiFi, pool, gym, parking, restaurant. Google reads these for amenity-filtered searches ("hotels with pool near me"). Use plain, searchable names that match how travelers think about amenities.

checkinTime and checkoutTime

Both use ISO 8601 time format: 15:00:00 for 3 PM check-in, 11:00:00 for 11 AM checkout. Google and travel aggregators display these in the hotel listing. Include the timezone offset if your hotel is in a non-obvious timezone, though most consumers assume local time.

petsAllowed

petsAllowed is a Boolean or a text string describing the pet policy. A simple true/false works for Google's filter. If you need to communicate restrictions ("dogs under 25 lbs only"), use a text string. Google filters on the Boolean value, but AI assistants read the text for nuance.

Minimal valid version

The smallest markup that still produces a valid Hotel entity. Use it as the floor. Reach for the advanced example above when you want search engines and AI agents to understand more about your content.

schema.org/Hotel (minimal)
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Hotel",
  "name": "Hotel Dunmore",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "450 Main Street",
    "addressLocality": "Dunmore",
    "addressRegion": "PA"
  }
}
</script>

Google rich results this unlocks

Markup matching this example makes your page eligible for the following Google Search rich results. The primary target drives the required / recommended property classification in the advanced code block above.

Common Hotel mistakes

Mistakes that pass validation but silently fail to earn rich results or mislead consumers walking the graph. Avoid these and your markup will be ahead of most sites in the wild.

  1. 01

    Confusing starRating with aggregateRating

    Wrong
    "starRating": { "@type": "Rating", "ratingValue": "4.1", "reviewCount": "312" } (guest reviews in starRating)
    Right
    "starRating": { "ratingValue": "3" } for official classification; "aggregateRating": { "ratingValue": "4.1", "reviewCount": "312" } for guest reviews

    starRating is the official hotel classification (1-5 stars from a rating authority). aggregateRating is the average guest review score. Putting guest reviews in starRating inflates the star classification and misrepresents the hotel in filtered searches.

  2. 02

    checkinTime as 12-hour format

    Wrong
    "checkinTime": "3:00 PM"
    Right
    "checkinTime": "15:00:00"

    checkinTime and checkoutTime use ISO 8601 24-hour time format. 3 PM is 15:00:00, not 3:00 PM. The 12-hour format with AM/PM is not machine-parseable and will be ignored by Google and travel aggregators.

  3. 03

    amenityFeature as a plain string array

    Wrong
    "amenityFeature": ["WiFi", "Pool", "Gym"]
    Right
    "amenityFeature": [{ "@type": "LocationFeatureSpecification", "name": "WiFi", "value": true }]

    amenityFeature expects LocationFeatureSpecification objects with name and value (Boolean). The value property lets you explicitly state which amenities the hotel has (true) and does not have (false). Listing absent amenities as false can be useful for travelers filtering by specific requirements.

  4. 04

    Missing numberOfRooms

    Wrong
    Hotel with address and star rating but no numberOfRooms
    Right
    "numberOfRooms": 48

    numberOfRooms helps Google and travel platforms categorize the property (boutique vs chain vs resort). It also appears in the hotel knowledge panel. A missing value means Google has to estimate from other sources, which is less reliable.

  5. 05

    petsAllowed as a string "yes"

    Wrong
    "petsAllowed": "yes"
    Right
    "petsAllowed": true or "petsAllowed": "Dogs under 30 lbs, $25/night fee"

    Use a Boolean for simple yes/no (Google reads this for pet-friendly filters) or a descriptive string for policies with restrictions. The string "yes" is not a valid Boolean. Use true (no quotes) if you just want to indicate pets are allowed.

About the example data

Hotel Dunmore is a fictional boutique hotel where XooCon attendees stay when visiting Dunmore for the conference at The Thunderdome. The hotel is walking distance from Xoo Code Shop Dunmore and The Dunmore Grill.

Comments

Loading comments...

Leave a comment