SoftwareApplication schema for a SaaS: an example that validates
You want stars, pricing and platform shown for your app in search. This page shows the fields Google needs, where to get a rating honestly, and a full JSON-LD example for a SaaS that validates.
By Théophile Louvart, founder of Porteur · Updated 14 September 2026 · Markdown
What the software app rich result shows
SoftwareApplication markup makes your app page eligible for a richer result. It is not a ranking factor. It gives Google a clean read of your app’s name, price and rating. On a good day you will see stars, price and platform in the result.
If the markup is valid and the page content matches, Google may show a star rating and price next to your title. For a web app, it may also show “Web” as the platform. This can lift click-through on queries like “yourproduct reviews” or “yourproduct price”.
You still need a solid title and meta description. Rich results help the eye, they do not fix a weak pitch. Keep your title under about 60 characters and write a clear first line for the snippet.
The required fields for SoftwareApplication
For the software app rich result, Google needs these on the page and in the JSON-LD, as of 2026:
- name
- offers.price, use 0 for a free app
- offers.priceCurrency, for example USD or EUR
- A rating, either aggregateRating with ratingValue and ratingCount, or at least one review
Add applicationCategory and operatingSystem too. They are not required, but they help searchers and machines. For a SaaS, use applicationCategory like BusinessApplication. Use operatingSystem "Web" for a browser app.
Recommended fields and choices that matter
- description, a short plain summary
- applicationCategory, for example BusinessApplication, DeveloperApplication or UtilitiesApplication
- operatingSystem, "Web", "Windows", "macOS", "iOS", "Android" as needed
- offers.url, the plan or checkout URL
- offers.availability, use a schema.org value like InStock for available signups
- publisher or author as your Organization, with name and url
- image, a logo or product image that is crawlable
If you offer several plans, mark up the plan shown on the page. If the page lists all plans, you can use an AggregateOffer, but keep it simple on the main product page. For a pricing page, using multiple Offer entries is fine if each offer is visible on that page and has its own url.
Use absolute URLs everywhere, including image and offer URLs. The Rich Results Test often flags relative URLs as errors for some types.
Where your rating can come from, honestly
You have two safe routes: reviews you publish on your page, or an aggregate rating you calculate from those visible reviews. Both must match visible content on the page. Do not mark up ratings that users cannot see on the page.
- User reviews collected on your site: show the quotes and stars on the page, then add Review or AggregateRating in the JSON-LD
- First‑party ratings from your database: print the count and average on the page, then mark up aggregateRating
If you embed a third‑party widget, only add markup if the rating values and count are present on your page and you are allowed to republish them. Avoid scraping ratings from another site. Google treats hidden or mismatched ratings as a policy violation and may ignore your markup sitewide for a time.
Self‑serving reviews are not shown as rich results for LocalBusiness or Organization. SoftwareApplication is a supported type for review snippets. Keep the reviews about the product, not your company in general, and make sure an author name is present for each review you mark up.
A full JSON-LD example for a SaaS that validates
Here is a clean JSON-LD block for a fictional SaaS, “PingFox”, a web uptime monitor with a free plan. Put this on https://yourproduct.com/. Update the values to match your page content exactly.
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://yourproduct.com/#org",
"name": "PingFox Inc.",
"url": "https://yourproduct.com/",
"logo": {
"@type": "ImageObject",
"url": "https://yourproduct.com/static/logo-512.png",
"width": 512,
"height": 512
},
"sameAs": [
"https://twitter.com/pingfox",
"https://www.linkedin.com/company/pingfox"
]
},
{
"@type": "SoftwareApplication",
"@id": "https://yourproduct.com/#app",
"name": "PingFox Uptime Monitor",
"url": "https://yourproduct.com/",
"applicationCategory": "BusinessApplication",
"operatingSystem": "Web",
"image": "https://yourproduct.com/static/app-card.png",
"description": "Simple uptime monitoring and alerts for APIs and websites.",
"publisher": { "@id": "https://yourproduct.com/#org" },
"offers": {
"@type": "Offer",
"url": "https://yourproduct.com/pricing#free",
"price": 0,
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": 4.7,
"ratingCount": 28
}
},
{
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://yourproduct.com/"
},
{
"@type": "ListItem",
"position": 2,
"name": "Pricing",
"item": "https://yourproduct.com/pricing"
}
]
}
]
}A fixed page looks like this: the homepage shows “Rated 4.7 out of 5 from users”, a price badge “Free”, and an obvious path to Pricing. The same numbers appear in the code above. The logo is crawlable at the given URL, at least 112 by 112 pixels. All URLs are absolute. The rating has both ratingValue and ratingCount, both numbers, and in a reasonable range.
Implement it on your site without breaking templates
Choose the page
Add SoftwareApplication to your main product page, for example https://yourproduct.com/. Add it to pricing or download pages only if the same content is visible there.
Collect the values from your CMS
Name, description, logo URL, plan URL, price and currency, rating value and count, category and operating system. Store them in fields so they stay in sync.
Render JSON-LD as a script
Use <script type="application/ld+json"> and dump one JSON object with an @graph. Put it in the head or the body. JSON-LD is Google’s recommended format.
Keep numbers as numbers
price and ratingValue are numbers, not strings. Do not include the currency sign in price. Use priceCurrency for USD, EUR and so on.
Use absolute URLs
For url, image, logo and item in breadcrumbs. Never rely on base tags or relative paths in structured data.
Match the visible content
Show the same rating and price on the page. Update both when the data changes. Avoid lazy-loading the rating without rendering the values server side.
You may inject JSON-LD with JavaScript. Google renders pages and can see injected markup. Many answering AI crawlers do not run scripts. If you want those to read it, render the script in the initial HTML. The Rich Results Test reads the rendered page, so your JSON-LD will appear there even if injected after load, as long as Google can render it for that URL.
Test and debug in the right tools
Use two tools and know the difference. They answer different questions and you need both in practice.
| Tool | URL | What it checks | When to use |
|---|---|---|---|
| Rich Results Test | https://search.google.com/test/rich-results | Eligibility for Google’s rich results. Flags missing required fields, policy issues and some URL problems. | Before shipping, then after deploy. It shows if your page is eligible for the software app rich result. |
| Schema Markup Validator | https://validator.schema.org/ | Syntax and schema.org correctness. Ignores Google’s product rules. | While coding. It tells you if the JSON-LD is valid schema.org even if Google still needs more. |
- Paste the URL into the Rich Results Test. Do not only test code snippets. You need to see render and fetch problems too.
- Fix the errors first. A missing required field blocks eligibility. Warnings are optional fields but still worth adding.
- Common errors: missing name or priceCurrency, price as "$0" instead of 0, relative URLs for images, ratingValue as 6 out of 5, date strings not ISO 8601 in reviews, types nested in ways that break the graph, or marking up content not visible on the page.
- When the test says eligible, release. Then watch Search Console for a Software app enhancement report on your property. It will list errors and warnings over time.
The old Structured Data Testing Tool was retired in 2020. Do not rely on results you find in blog posts that still reference it. Use the two tools above instead and confirm with Search Console after your next crawl.
What to show on the page so markup is trusted
- Print the rating average and count near the fold, for example “4.7 from user reviews”.
- If you mark up individual Review, show the review quotes and the author names.
- Show the price or plan badge on the same page you mark up with Offer. For a free plan use a simple “Free” label.
- Keep your logo image crawlable. A blocked CDN path breaks Organization markup used as a publisher.
- If you use breadcrumbs in JSON-LD, render matching breadcrumb links in HTML.
If your site hides numbers behind tabs or accordions, that is fine. Google can read hidden content that users can reveal. Just keep it visible in the DOM and do not require user login or paywalls to reveal the data you mark up on a public page.
Edge cases: pricing, markets and platforms
- Freemium: set price to 0 for the free plan. If you also sell paid plans, link offers.url to the pricing section that matches the plan you describe.
- Multiple currencies: use one priceCurrency and price per Offer. Do not mix several currencies into one Offer. If you show several, use multiple Offer entries that match the visible table.
- Annual vs monthly: reflect the unit in visible text. Schema.org’s Offer does not carry billing period. Your page copy must explain it. Avoid “$0” if you mean a free plan.
- App with many platforms: if you have platform pages, put a SoftwareApplication on each page with the right operatingSystem. On a single overview page, list them in the copy and pick the primary "operatingSystem" in markup, for example “Web”.
- App store ratings: only mark up ratings that are on your page. Linking to an app store page is fine, but do not mark up the store’s rating unless you publish those numbers on the page and are allowed to do so.
Questions
Google reads JSON-LD, Microdata and RDFa. JSON-LD is recommended. It is cleaner to template, and you can place it in the head or body. For a small team, JSON-LD reduces breakage when you change layout.
Yes, you need a rating or a review. For software apps that means aggregateRating with ratingValue and ratingCount, or at least one Review. Without it, you will not be eligible even if name and offers are present.
Yes. Use offers with price 0 and a priceCurrency like USD. Make sure the page states that the app is free. The Rich Results Test will accept 0 as a valid price.
Render a <script type="application/ld+json"> tag with the data on the server for public pages. Google renders client code, but server rendering avoids flicker and helps other crawlers that do not run scripts.
Eligibility is not a guarantee. Google may choose not to show a rich result for some queries or sites. Give it time after indexing, compare queries, and keep the page consistent. Watch the enhancement report in Search Console for sitewide issues.
It helps. Use Organization for your name, url and logo, and reference it from the SoftwareApplication as the publisher. This supports knowledge panel data and keeps your brand consistent.
Sources
Check my site, free
Paste your homepage URL and get a free check that reads your site and the searches around it, then shows three structured data findings you can ship in about thirty seconds.
- Free check, no card
- Read-only, your own accounts
- Readable by your agent
Read next
- GuideJSON-LD: how to write it, where to put it, how to test it
- GuideThe Rich Results Test: what it checks and what it does not
- GuideOrganization schema: the fields that feed your knowledge panel
- GuideFAQ schema in 2026: valid, readable by assistants, no rich result
- GuideReview schema: what is allowed, what is shown, what is self-serving
- GlossaryStructured data
- GuideHow to add structured data to a site, whatever it is built with
- Free toolSchema markup generator