Structured data has a property most people learn the hard way: Google validates it against its own required-field lists, not against schema.org. A block that is perfectly valid schema.org can be rejected for a rich result because one required property is missing. On one of our sites that single missing property was repeated on 44 pages, because it lived in the shared layout.
What does this check detect?
Answer. Every JSON-LD block on every page, parsed and checked against Google's required properties for the types Google actually renders as rich results.
Moonleap extracts the application/ld+json blocks from each page in the inventory, parses them, and for the types with a rich result (Product, Article, FAQPage, SoftwareApplication, Organization, BreadcrumbList and a few more) checks the properties Google lists as required. The finding names the type, the missing property and the pages carrying the block. A block in a shared layout is counted once per page, which is why one mistake reads as 44.
What is the SoftwareApplication rule that catches SaaS sites?
Answer. Google requires name, offers.price and either aggregateRating or review. A new product with no reviews cannot satisfy it honestly.
Almost every SaaS landing page copies a SoftwareApplication block from a template, fills in the name and a price, and ships. Google's documentation for the Software App rich result lists aggregateRating (or review) among the required properties alongside offers.price. Without a real rating the block fails validation; with an invented one it is a policy violation.
The first fix on our site removed offers, on the theory that a free tier has no price. That made it worse: now two required properties were missing instead of one. The check reported 2 pages (the layout block had been narrowed to the home page and one info page by then).
What are the two honest ways out?
Answer. Change the type to one whose required set you can meet, or keep SoftwareApplication only when you have a real rating.
- schema.org/Service has no rating requirement
- provider becomes your Organization
- offers with a price can stay for AI readers
- no rich result, no rejection
- only when a real aggregateRating exists
- rating must come from a source you can show
- eligible for the app rich result
- revisit when the first reviews arrive
We chose Service with provider, serviceType, areaServed, audience and offers. The block still tells an AI reader what the product is, who it is for and what it costs; it just does not claim a rich result it cannot earn. When the product has a public review source, the block can become SoftwareApplication again with a rating that points at it.
What is the fix, concretely?
Answer. One JSON-LD block in the layout, generated from data, typed to what you can support, validated in the build.
{
"@context": "https://schema.org",
"@type": "Service",
"name": "<Product>",
"serviceType": "<what it does, in five words>",
"provider": { "@type": "Organization", "name": "<Company>", "url": "https://<your-domain>" },
"areaServed": "Worldwide",
"audience": { "@type": "Audience", "audienceType": "<who it is for>" },
"offers": { "@type": "Offer", "price": "29", "priceCurrency": "USD" }
}
Keep Organization on the home page, Article or TechArticle on posts (with datePublished and author), FAQPage only where questions and answers are visible on the page, and BreadcrumbList where the breadcrumb exists. Do not add Product to a page that does not sell a product.
How do you verify it?
Answer. Paste the URL into the Rich Results Test; then re-run the audit after deploy and expect zero rejected pages.
The Rich Results Test shows exactly which property Google considers missing. Moonleap's re-analysis re-parses every page; on the site in this case the count went 44, 2, 0 across two deploys in three days, each step visible in the finding's history.
FAQ
Is invalid structured data a penalty?
No. Google ignores blocks it cannot use. The cost is the rich result you do not get, and the confusion for AI readers who parse the same block.
Can I use both Service and SoftwareApplication?
You can, but two types describing the same thing invite inconsistency. Pick the one whose required properties you meet.
Do AI assistants read JSON-LD?
They read the page; a clean block is one more unambiguous statement of what the product is, who makes it and what it costs. Treat it as documentation, not as a ranking switch.
Sources
- Google, "Software App (SoftwareApplication) structured data" https://developers.google.com/search/docs/appearance/structured-data/software-app
- Google, Rich Results Test https://search.google.com/test/rich-results
- Schema.org, Service https://schema.org/Service
- Case, omniroom.ai, 63 pages audited on 4 and 7 September 2026 (Moonleap inventory audit)