Schema.org is a shared vocabulary of types and properties for describing things on the web, launched in June 2011 by Bing, Google and Yahoo, joined shortly after by Yandex, and now developed in the open through the W3C Schema.org Community Group. It supplies the words: Person, Product, Recipe, author, startDate, address. It does not supply the syntax those words are written in, which is why the same vocabulary appears inside JSON-LD, Microdata and RDFa markup. When practitioners say “schema markup”, they mean web page markup that uses this vocabulary.
Vocabulary and syntax are two different layers
The single most useful distinction on this page is between what is being said and how it is written down. Schema.org is a vocabulary: a list of classes, a list of properties, and rules about which properties apply to which classes. JSON-LD, Microdata and RDFa are syntaxes: three ways of encoding statements inside an HTML document.
The three syntaxes are interchangeable at the level of meaning. All three expand to the same set of subject-predicate-object statements, so Person with a name of “Marie Curie” carries identical information whether it arrives as a script block, a set of itemprop attributes, or a set of property attributes. Which syntax to choose is a maintenance question, worked through in JSON-LD vs Microdata vs RDFa.
Because the vocabulary is defined with schema.org URLs (https://schema.org/Person, https://schema.org/birthDate), markup that uses it is also linked data and can be loaded into a graph store without translation. See triples: subject, predicate, object for the model underneath.
The type hierarchy starts at Thing
Every class in schema.org descends from a single root type called Thing. Thing defines the handful of properties that make sense for absolutely anything: name, description, url, image, alternateName, identifier, sameAs, disambiguatingDescription, mainEntityOfPage, subjectOf, potentialAction and additionalType.
Directly below Thing sit the broad top-level branches, among them CreativeWork, Event, Organization, Person, Place, Product, Action and Intangible. Everything else hangs off one of those. Recipe is a kind of HowTo, which is a kind of CreativeWork. Hotel is a kind of LodgingBusiness, which is a kind of LocalBusiness. SoftwareApplication is a kind of CreativeWork, not a kind of Product, which surprises people the first time they look.
Intangible is where the abstractions live: Service, Offer, Rating, Occupation and helper types such as PostalAddress that hold a cluster of related values rather than naming a real-world object.
Unlike a strict single-parent taxonomy, schema.org permits a type to have more than one supertype. LocalBusiness is both an Organization and a Place, which is why a restaurant can carry founder (from the organization branch) and geo (from the place branch) in the same block without contradiction.
How inheritance works, with a worked example
A type has access to every property defined at or above its own level. Nothing needs to be redeclared, and no property list is repeated in the specification.
Take a university page. The relevant chain is Thing to Organization to EducationalOrganization to CollegeOrUniversity. Each level contributes:
| Level | Contributes properties such as |
|---|---|
Thing | name, url, description, image, sameAs, identifier |
Organization | legalName, address, telephone, email, logo, founder, foundingDate, parentOrganization, department, numberOfEmployees, knowsAbout |
EducationalOrganization | alumni |
CollegeOrUniversity | the label itself, and the specificity it carries |
Marking up the University of Florida therefore uses properties drawn from three levels at once:
{
"@context": "https://schema.org",
"@type": "CollegeOrUniversity",
"@id": "https://www.ufl.edu/#organization",
"name": "University of Florida",
"url": "https://www.ufl.edu/",
"sameAs": "https://www.wikidata.org/wiki/Q501758",
"foundingDate": "1853",
"address": {
"@type": "PostalAddress",
"addressLocality": "Gainesville",
"addressRegion": "FL",
"addressCountry": "US"
},
"department": {
"@type": "CollegeOrUniversity",
"name": "UF College of Engineering"
}
}
Only @type names CollegeOrUniversity. name, url and sameAs come from Thing; foundingDate, address and department come from Organization. A consumer that has never heard of CollegeOrUniversity can still process the block as an Organization, because the hierarchy guarantees that every subtype is a valid instance of its supertypes. That property is what makes the vocabulary safe to extend: adding a narrow new type never breaks a consumer that only understands the broad ones.
The same logic runs the other way. Choosing Organization where CollegeOrUniversity is true is not wrong, it is merely vague. Choosing CollegeOrUniversity for a tutoring company is wrong, because the statement is false. Pick the most specific type that is accurate, and no more specific than that.
Expected types, and why they are not constraints
Each property in schema.org carries two pieces of metadata: which types it is expected to be used on, and which types its value is expected to be. The vocabulary records these as domainIncludes and rangeIncludes rather than as the strict rdfs:domain and rdfs:range used elsewhere in RDF vocabularies, and the wording is deliberate. They are expectations, not rules that a validator must enforce or that a reasoner may use to infer new types.
That has practical consequences. author expects a Person or an Organization, so a bare string in author is tolerated by most consumers but tells them nothing they can resolve to an entity. image expects an ImageObject or a URL. address expects a PostalAddress or plain text. Many properties accept a union of several types, and several accept both a structured object and a literal, which is why the same property can look different across two valid examples.
Where actual enforcement is wanted, it comes from outside the vocabulary: a shape language such as SHACL for graph data, or a search engine’s own documented requirements for a given rich result.
Core, pending, extensions and the attic
Not every term on schema.org has the same standing.
Core is the main vocabulary at schema.org, the terms that have been through discussion and release. This is where nearly all published markup lives.
Pending is a staging area at pending.schema.org for terms that have been proposed and provisionally added. Pending terms are real and resolvable, and they are explicitly marked as subject to change or removal. Using them in production is a bet that the proposal will survive.
Hosted extensions carry domain-specific vocabulary that would clutter the core, published on subdomains: health-lifesci.schema.org, auto.schema.org, bib.schema.org and meta.schema.org among them.
External extensions are vocabularies maintained by other organizations that align with schema.org rather than living inside it, the GS1 Web Vocabulary for retail product data being the standard example.
The attic at attic.schema.org holds retired terms. Nothing is deleted outright, because markup on the open web outlives editorial decisions, so a term that has been withdrawn still resolves and still documents what it used to mean.
Versioning and releases
Schema.org ships numbered releases rather than continuous changes. Each release gets a version number, a release note listing what was added, changed, or moved to the attic, and a permanent snapshot under schema.org/version/, so markup written against an older release can be checked against the vocabulary as it stood at the time. The full history is at schema.org/docs/releases.html.
Releases are additive in practice. New terms appear, and unused ones move to the attic, but existing core terms are not repurposed to mean something else, which is why a Product block written years ago still parses correctly. The whole vocabulary is also published as downloadable files in JSON-LD, Turtle, and other RDF formats, which is how validators and code generators stay in step with a release.
What “Google supports a subset” actually means
Schema.org has hundreds of types. Google documents rich result support for a much smaller list. The distinction matters, and it is frequently misread.
Google’s structured data documentation defines a set of features, each with its own eligible type and its own required and recommended properties: Article, BreadcrumbList, Product with Offer, Recipe, Event, JobPosting, VideoObject, LocalBusiness, Organization and others. For those features, and only for those, valid markup makes a page eligible for a specific search appearance. Eligibility is not a guarantee; Google states plainly that it decides whether to show a rich result.
Three things follow.
First, a type absent from Google’s feature list is neither invalid nor ignored. Google reads the whole block, and properties outside the documented features are still available to it as statements about an entity. They simply won’t produce a visual change on the results page, which is the source of most disappointment with schema markup.
Second, the subset moves. Google has withdrawn features it once supported, narrowing FAQ rich results to well-known authoritative government and health sites and retiring HowTo rich results entirely. Markup written for a feature that is later withdrawn does not become an error; it stops producing the appearance it was written for.
Third, Google’s requirements are stricter than schema.org’s. The vocabulary says Offer expects a price; Google’s product documentation says which properties must be present for a merchant listing, and a block that satisfies schema.org can still fail the Rich Results Test. Validate against both, using the tools covered in structured data testing tools.
Other consumers make their own choices. Bing, Yandex, Pinterest and a range of applications read schema.org markup, each supporting a different slice, none obliged to match Google’s.
For developers
Consume the vocabulary as data rather than as documentation. The full definition is available as a downloadable RDF file per release, so type hierarchies, domainIncludes and rangeIncludes can be loaded into a graph and queried with SPARQL to answer questions such as which properties are legal on a given type, or which types accept a given property. That is a more reliable basis for a markup generator than a hand-maintained list.
Generate markup from the same objects that render the page, so the two cannot drift apart. Where a domain model is richer than schema.org, map it at the boundary instead of inventing terms: additionalType accepts a URL, which lets a node carry a pointer to a class in a private ontology while keeping its schema.org type intact.
For SEOs
Two decisions carry most of the value. The first is type selection: the most specific accurate type, chosen once per entity and used consistently across the site. The second is identity: one stable @id per entity and sameAs pointing at identifiers other systems already hold, so a search engine has a route from the markup to an entity in its own graph. Those tactics are worked through in organization schema, person schema, and sameAs schema.
Everything else is a question of coverage, not cleverness. Adding more properties of the same entity strengthens a description; adding types the page does not actually contain does not. The relationship between this markup layer and a search engine’s own knowledge base is covered in structured data and Google Knowledge Graph.
Common mistakes
Treating schema.org as Google’s product. It is an independent vocabulary with multiple consumers. Google documents a subset for rich results, and that subset is not the boundary of what is valid.
Inventing properties. A misspelled or made-up property name is not an extension; it is a statement no consumer can resolve. Check the type’s page on schema.org before shipping.
Putting properties on the wrong type. price belongs on Offer, not Product. streetAddress belongs on PostalAddress, not Organization. Inheritance runs downward only, so a property defined on a subtype is not available on its parent.
Choosing a narrow type to look through. CollegeOrUniversity on a training provider, or NewsArticle on a product page, is a false statement about the page, and false statements are worse than vague ones.
Related pages
- JSON-LD: the complete guide
- JSON-LD vs Microdata vs RDFa
- Structured data for SEO
- Organization schema markup
- Person schema markup
- Ontologies
FAQ
What is schema markup in simple terms?
Schema markup is code added to a web page that labels its content using the schema.org vocabulary, so a machine can tell that a string is a person’s name, a price, or an event date rather than ordinary text. The labels come from schema.org and are usually written in JSON-LD inside a script tag.
Is schema.org the same as JSON-LD?
No. Schema.org is the vocabulary of types and properties, and JSON-LD is one of three syntaxes for writing that vocabulary into a page, alongside Microdata and RDFa. All three express the same statements, so the choice between them affects maintenance, not meaning. Google recommends JSON-LD.
How do schema.org types inherit properties?
Every type descends from the root type Thing, and a type can use every property defined at its own level or any level above it. A CollegeOrUniversity can use address from Organization and name from Thing without redeclaring those properties. A type may also have more than one parent, as LocalBusiness does.
Does Google support all schema.org types?
No. Google documents rich result support for a limited set of features, each with its own required and recommended properties, and that list changes over time. Types outside the list are still read as statements about an entity but will not produce a special search appearance, and eligibility is never guaranteed.
Sources and further reading
- schema.org home: https://schema.org/
- schema.org, full type hierarchy: https://schema.org/docs/full.html
- schema.org, Getting started: https://schema.org/docs/gs.html
- schema.org, releases and version history: https://schema.org/docs/releases.html
- schema.org, extensions: https://schema.org/docs/extension.html
- W3C Schema.org Community Group: https://www.w3.org/community/schemaorg/
- Google Search Central, structured data general guidelines: https://developers.google.com/search/docs/appearance/structured-data/sd-policies
- Google Search Central, search gallery of structured data features: https://developers.google.com/search/docs/appearance/structured-data/search-gallery
