Structured data is where fitness businesses lose the most machine trust for the least reason. The work is mechanical, the vocabulary already exists, and the difference between doing it and skipping it is the difference between an assistant knowing your hours and guessing them.

We wrote a short piece on the fields studios most often miss: the schema every studio forgets to add is the quick-win companion to this one, and if you have fifteen minutes, start there. This is the complete reference: every decision, one full example, and the validation routine, so you or your web person can do the whole job properly.

Choosing your type

Schema.org gives fitness venues a small family of types, and the choice matters because the type is the first thing you tell a machine about yourself.

ExerciseGym is the natural fit for most gyms, strength clubs, and boxes. If people come to you primarily to train, this is you.

HealthClub suits clubs with broader facilities: pools, spas, courts, saunas alongside the gym floor. It signals a wider offering than a training room.

SportsActivityLocation is the general venue type, right for climbing walls, bouldering centres, and spaces where a specific activity defines the place.

LocalBusiness is the honest fallback for hybrid studios, the yoga-and-physio space, the studio-cafe, businesses none of the specific types describes cleanly. A correct general type beats a wrong specific one, because inaccuracy costs more trust than vagueness.

Pick one. Declaring three types in the hope of covering bases reads as confusion, and machines resolve confusion by trusting you less.

The fields that matter

A fitness venue’s markup earns its keep through a handful of fields.

name, address, and geo. Your name exactly as it appears everywhere else, the full postal address, and the coordinates. The geo pair removes every ambiguity about where you are, which matters enormously for near-me questions.

openingHoursSpecification. Hours as structured day-by-day data rather than a sentence. This is the field that drifts stale fastest, so it is also the one to wire into your quarterly review.

priceRange. A simple indication of what you cost. Machines get asked about price constantly, and even the rough signal helps them include you in budget-shaped answers.

amenityFeature. The practical facts people filter by: showers, parking, changing rooms, women-only hours, wheelchair access. Each one you state is a question you become eligible to win.

hasOfferCatalog. Your memberships, class packs, and day passes as a structured list. This is the machine readable version of your prices page, and it is rare enough in fitness that having it is a genuine edge.

sameAs. Links to your profiles elsewhere, Google Business Profile, the directories that list you, so machines can connect your records into one entity.

A complete example

Here is a full block for a fictional gym. Adapt every value to your reality; a copied example with wrong facts is worse than nothing.

{
  "@context": "https://schema.org",
  "@type": "ExerciseGym",
  "name": "Ironhold Strength Club",
  "description": "Independent strength and conditioning gym in south Leeds for beginners and everyday lifters. Small coached classes and open gym.",
  "url": "https://ironholdclub.example",
  "telephone": "+44-113-000-0000",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "14 Foundry Lane",
    "addressLocality": "Leeds",
    "postalCode": "LS11 0AA",
    "addressCountry": "GB"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 53.7776,
    "longitude": -1.5722
  },
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "06:00",
      "closes": "21:30"
    },
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Saturday", "Sunday"],
      "opens": "08:00",
      "closes": "18:00"
    }
  ],
  "priceRange": "$$",
  "amenityFeature": [
    { "@type": "LocationFeatureSpecification", "name": "Showers", "value": true },
    { "@type": "LocationFeatureSpecification", "name": "Free parking", "value": true },
    { "@type": "LocationFeatureSpecification", "name": "Beginner classes", "value": true }
  ],
  "hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "Memberships and passes",
    "itemListElement": [
      {
        "@type": "Offer",
        "name": "Unlimited monthly membership",
        "url": "https://ironholdclub.example/prices"
      },
      {
        "@type": "Offer",
        "name": "Beginner intro block",
        "url": "https://ironholdclub.example/beginners"
      },
      {
        "@type": "Offer",
        "name": "Day pass",
        "url": "https://ironholdclub.example/prices"
      }
    ]
  },
  "sameAs": [
    "https://maps.google.example/ironhold"
  ]
}

Wrap it in a script tag of type application/ld+json in the head of your homepage, once. If editing JSON is friction, our free schema generator builds a valid block for a gym from a short form, including the optional FAQ markup.

Multiple locations and what lives where

Two situations complicate the single-block picture, and both have clean answers.

More than one site. A gym with two locations is two venues, each deserving its own block on its own location page, each with its own address, geo, and hours. Give each a distinct name, Ironhold Leeds South and Ironhold Headingley, and keep the shared brand consistent across both. One merged block with two addresses reads as confusion, and confusion is the thing this whole exercise exists to remove.

Classes and trainers. The venue block above deliberately stops at the business itself. Your timetable and your coaches deserve markup of their own, on the pages where they live, and that is precisely the territory of the schema every studio forgets to add: class and schedule data, trainer profiles, and the connections that tie them to the venue. Do the venue block first, because everything else attaches to it.

Validate before you celebrate

Two free tools tell you whether machines parse what you meant.

validator.schema.org checks the markup against the vocabulary itself: types, properties, structure.

The Google Rich Results Test shows how Google specifically reads the page, and catches the practical problems, malformed JSON, misplaced blocks, that the pure validator can miss.

Run both after publishing. If the tools show your gym with the right type, address, and hours, assistants can read the same.

The errors we see over and over

The trailing comma. One stray comma makes the whole block invalid JSON, and machines discard invalid blocks silently. This is why the validator step is non-negotiable.

Duplicate blocks. The theme adds LocalBusiness markup, a plugin adds another, then your new block makes three, and they disagree with each other. Audit what already exists before adding anything.

Facts that disagree with the visible page. Schema says open at six, the contact page says seven. Machines cross check, and the contradiction costs more than either fact earns.

Set-and-forget. Markup written once and never revisited quietly rots as hours and prices change. Structured data is a living statement about your business; treat it like the timetable.

Prove it moved the needle

When the block is live and validated, test the outcome rather than the code. The free AI visibility check reads your site the way an AI crawler does, and structured data is one of the ten signals it scores, so you get instant confirmation the markup is visible from outside.

Then, for the question the markup ultimately serves, whether assistants recommend you when your city asks where to train, request a full audit. We ask the real questions across the main assistants and show you what the machines now confidently know about your gym, and what still needs saying.

Reference