Most schema types are harmless when you get them wrong. A malformed BreadcrumbList gets ignored and nothing else happens. AggregateRating is different, because it is the one type where getting it wrong is indistinguishable from lying, and Google treats it that way.
This is also the type with the widest gap between what tutorials show you and what is actually permitted. Half the review schema on the web is inert, a meaningful share of it is against guidelines, and the people who added it have no idea because nothing visibly broke. Here is the whole picture: the properties, the rule that catches people, and the correct implementation.
What AggregateRating is
AggregateRating describes the average of multiple ratings for a single item, plus how many ratings produced that average. It is the summary. Its sibling, Review, describes one specific review from one specific person.
Almost nobody wants AggregateRating for its own sake. They want the review snippet: the row of gold stars and the count that appears under a search result. The stars are the output. The markup is only the request, and Google decides whether to honor it.
That distinction matters because every rule below exists on the Google side, not the schema.org side. Your markup can be perfectly valid schema and completely ineligible for the visual result you added it for. Validators check the first thing and say nothing about the second.
The properties, and which are required
The type has a small surface area. Six properties cover essentially every real implementation.
| Property | Status | Notes |
|---|---|---|
| ratingValueNumber or Text | Required | The computed average. Report it exactly, including a decimal. |
| ratingCountInteger | One of two | Total scores submitted, written or not. Required unless reviewCount is present. |
| reviewCountInteger | One of two | Written reviews only. Required unless ratingCount is present. |
| bestRatingNumber | Optional | Top of the scale. Defaults to 5. Mandatory if your scale is not out of 5. |
| worstRatingNumber | Optional | Bottom of the scale. Defaults to 1. |
| itemReviewedThing | Conditional | Required when the block is standalone rather than nested inside the item. |
Two of these cause more trouble than the rest combined. bestRating defaults to 5, so a rating of 8 on a 10-point scale with no bestRating declared is read as 8 out of 5, which is nonsense and gets dropped. And ratingCount versus reviewCount get used interchangeably by people who want the larger of the two numbers, which is a small misrepresentation that sits inside a type already under scrutiny.
The self-serving review rule
This is the rule the article is named after, and it is the single most misunderstood thing about review markup.
In September 2019 Google changed how review rich results work for two types. Google guidance states that reviews about an entity, placed on that entity own website, are considered self-serving and are not eligible for review rich results when the type is LocalBusiness or Organization.
Read that carefully, because the trap is in the word self-serving. It does not mean fake. It does not mean dishonest. Testimonials you collected from genuinely delighted clients, every word of them true, published on your own testimonials page, are self-serving under this definition. The reasoning is straightforward: you chose which ones to publish, so the average is not independent.
Put plainly: you cannot put a rating for your own business on your own website and expect stars in search results. Not because your reviews are fake, but because you are both the subject and the publisher.
What is still allowed is marking up ratings for things that are not you. An ecommerce store marking up customer ratings for the products it sells is fine, because the product is the entity being rated and the customers are independent of it. A publisher marking up a critic review of a film is fine. A recipe site marking up user ratings on a recipe is fine.
The line is whether the entity being rated is the same entity that controls the page.
Which types can carry a rating
AggregateRating can be attached to anything in the vocabulary, because schema.org is permissive. Google review snippets are a much shorter list. The types that can produce stars include Product, Recipe, Book, Course, Event, Movie, SoftwareApplication, MusicRecording, and the media and series types, plus LocalBusiness and Organization subject to the self-serving restriction above.
Notice what is missing. Service is not on the list. WebPage is not on the list. Article is not on the list. Yet ratings get attached to all three constantly, usually by a plugin that offers a star rating widget and helpfully adds markup for it.
A rating on an ineligible type does not hurt you. It simply does nothing, forever, while the person who added it believes review markup is in place. This is the most common state of review schema on service business websites, and the sort of thing that only surfaces in a proper SEO audit because nothing anywhere reports it as a problem.
The visibility rule
Google structured data guidelines require that marked-up content be visible to users on the page carrying the markup. For review data this is enforced more seriously than for most types.
A page whose JSON-LD announces a 4.8 average across 214 reviews, with nothing resembling a rating anywhere in the visible content, is exactly the fingerprint of fabricated markup. It does not matter whether the number is real. From the outside, real data with no visible source and invented data look identical, and Google resolves that ambiguity against you.
Two versions of this catch honest sites. The first is a review carousel that loads through a third-party widget after the page renders, where the schema is server-rendered and the visible reviews are not. The second is a rating displayed only in a footer badge image, where the number exists as pixels rather than text.
In both cases the fix is the same. Put the rating and the count in the rendered HTML as actual text, near the markup that describes it.
The LocalBusiness trap
Local businesses run into this harder than anyone, because the advice to add LocalBusiness schema is correct and the advice to include your rating inside it is not.
A typical local SEO checklist tells you to mark up your business with name, address, phone, hours, and geo coordinates. All of that is right, and it is genuinely useful. Then it tells you to add your Google rating to the same block, and now you have a block that is partly infrastructure and partly a request that will never be granted.
Your reviews are already doing work. They do it in the map pack, where Google reads them from your Business Profile directly, and where review volume and recency feed the prominence signal that decides local ranking. That is a separate system from organic review snippets, and it needs nothing from your website markup. We go through how that ranking actually resolves in the piece on proximity and map pack visibility.
So the LocalBusiness block should carry your identity, location, hours, and the sameAs links that resolve who you are. It should not carry a rating you gave yourself.
What a manual action looks like
Most SEO problems are algorithmic and silent. This one is a human at Google looking at your site and deciding it violates guidelines, and it arrives with a notification.
It shows up in Search Console under Manual actions, typically described as spammy structured markup. The consequence is losing rich result eligibility, which can be scoped to a set of pages or applied across the whole site depending on how widespread the issue is.
The recovery is not automatic. You correct the markup, then submit a reconsideration request describing what was wrong and what you changed. A person reads it. Turnaround runs from a few days to several weeks, and a vague request explaining nothing tends to come back rejected.
Three patterns account for most of these: ratings with no visible source on the page, ratings invented outright because a page needed stars, and ratings that describe something other than what the page is about. All three are avoidable in the time it takes to read the guidelines once.
How to do it correctly
Here is a product page implementation that satisfies every rule. The rating is nested inside the item it describes, so no itemReviewed is needed. The counts are distinct and honest. One example review is included, because a rating with at least one visible review behind it is a much stronger implementation than a bare average.
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Example Product",
"sku": "EX-1024",
"image": "https://example.com/product.jpg",
"offers": {
"@type": "Offer",
"price": "49.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.6",
"bestRating": "5",
"worstRating": "1",
"ratingCount": "312",
"reviewCount": "88"
},
"review": [{
"@type": "Review",
"author": { "@type": "Person", "name": "Example Reviewer" },
"datePublished": "2026-07-14",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5",
"bestRating": "5"
},
"reviewBody": "Arrived early and works exactly as described."
}]
}Four things make this correct, and all four have to be true together.
- The entity is eligible. It is a Product, which appears on Google list of types that can produce review snippets.
- The rating is independent. Customers rated the product. The store is not rating itself.
- The numbers are real and distinct. 312 scores, 88 of which have text. Both reported, neither inflated.
- It is visible on the page. The 4.6, the 312, and that review are rendered in the HTML a user sees.
Drop any one of those and the block moves from eligible to inert, or from inert to risk.
What to do when you have no reviews
The honest answer is: leave the property out. An absent AggregateRating costs you nothing. An invented one is the fastest route to a manual action available in structured data.
There is a real temptation here, especially on a new site that watches competitors show stars in the results. Two things are worth knowing. First, many of those competitors are showing stars from third-party aggregator pages rather than their own markup. Second, a meaningful share of the rest are non-compliant and simply have not been looked at yet.
What actually works instead, in order of effort:
- Build reviews where they count. For a local business that is your Google Business Profile, which feeds the map pack directly. Volume and recency both matter, and this is core to any local SEO program.
- Use an independent review platform. Ratings collected and hosted by a genuine third party sidestep the self-serving problem, because the platform controls the data rather than you.
- Publish testimonials anyway. Just do not mark them up as an aggregate rating. They convert visitors regardless of whether Google renders a star. Ours live on our testimonials page for exactly that reason.
- Compete on the markup that is available to you. FAQ, breadcrumb, article, and a clean organization entity are all fully available and fully compliant. That set is covered in the schema types guide.
Testing and monitoring
Three checks, and they answer different questions.
The Schema Markup Validator confirms your JSON parses and the properties belong to the type. It has no opinion about eligibility. The Rich Results Test is the one that matters here, because it tells you whether Google recognizes a review snippet as available for that page. If your block does not appear as a detected item there, the stars are not coming.
Then Search Console, which is the only one of the three that reports on your live site over time rather than a single URL on demand. Check the Merchant listings and Review snippets reports for errors, and check Manual actions periodically even when nothing seems wrong.
One habit worth building: re-run the Rich Results Test after any template change that touches how reviews render. The markup surviving a redesign while the visible reviews quietly disappear is a common way a compliant page becomes a non-compliant one without anyone touching the JSON.
The one-line test: can a visitor see, in text on the page, the exact rating and count your markup claims, for a thing that is not your own business? If yes, you are fine. If no, take it out.
Questions people actually ask
Can I add AggregateRating to my own homepage for my own business?
expand_more
Not for the purpose of getting stars in search results. Google treats reviews about an entity that are placed on that entity own website as self-serving, and self-serving reviews are excluded from review rich results for LocalBusiness and Organization. You can still display testimonials on your site, and you can still mark up genuinely third-party sourced ratings where the guidelines allow, but marking up reviews you collected about yourself will not produce stars and can invite a manual action if the data is not real.
What counts as a self-serving review?
expand_more
A review about a business, collected by that business, and published on that business own website. The distinction Google draws is about independence, not honesty. Even completely genuine testimonials you gathered from real happy clients and put on your own testimonials page are self-serving under this definition, because you control which ones appear.
What is the difference between reviewCount and ratingCount?
expand_more
ratingCount is the number of scores submitted, including ones where somebody clicked four stars and wrote nothing. reviewCount is the number of written reviews. A product with 300 star ratings of which 90 have text has a ratingCount of 300 and a reviewCount of 90. You need at least one of the two, and if you have both numbers, include both. Never use them interchangeably to inflate a figure.
Do the reviews have to be visible on the page?
expand_more
Yes. Google structured data guidelines require that marked-up content be visible to users on the page carrying the markup. A rating in the JSON-LD with no corresponding rating anywhere in the visible content is exactly the pattern that gets flagged as spammy structured markup. If the number is in your schema, the number has to be on the page.
Can I put my Google reviews in AggregateRating schema?
expand_more
Reproducing your Google Business Profile rating in your own site markup to earn stars in organic results runs into the same self-serving restriction, because the entity being rated is you and the page is yours. It also duplicates data Google already holds. Your Google reviews do real work in the map pack, where they belong. Copying them into JSON-LD on your homepage is not the way to get value from them.
What happens if I get a manual action for structured data?
expand_more
It appears in Search Console under Manual actions, usually described as spammy structured markup. The practical effect is losing rich result eligibility, sometimes for the affected pages and sometimes sitewide. You fix the markup, then submit a reconsideration request explaining what you changed. Review takes anywhere from a few days to several weeks, and eligibility does not return automatically when you fix it.
Does AggregateRating work on service pages?
expand_more
Service is not on the list of types eligible for review rich results, so a rating attached to a Service entity will not produce stars. This is one of the more common wasted implementations, because agencies add it to every service page expecting a visual result that was never available for that type.
Is a perfect 5.0 rating suspicious to Google?
expand_more
There is no published rule against it and plenty of legitimate businesses with a small number of genuinely perfect reviews. The risk is not the number itself, it is that a 5.0 across hundreds of reviews with no visible reviews on the page is a recognizable pattern for fabricated data. If your rating is real and the reviews backing it are on the page, report it accurately and do not round anything.
Joshua Rouillard
Founder, RouillardMedia
Joshua has spent over a decade in performance marketing and search. He founded RouillardMedia, where the team ships structured data across local, ecommerce, and lead generation sites, and writes about what actually moves the needle rather than what sounds impressive.
