# 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.

Updated 2026-09-14 · Source: https://porteur.ai/guides/softwareapplication-schema

## 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.

> Keep prices as numbers, not strings with a currency sign. Use priceCurrency for the ISO 4217 code, like USD.

## 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.

```json
{
  "@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

1. **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.
2. **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.
3. **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.
4. **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.
5. **Use absolute URLs** For url, image, logo and item in breadcrumbs. Never rely on base tags or relative paths in structured data.
6. **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

### Is JSON-LD required for SoftwareApplication, or can I use Microdata?

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.

### Do I need reviews to get a software app rich result?

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.

### Can I mark up a free SaaS with no paid plan?

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.

### Where do I put the JSON-LD on a Next.js or React app?

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.

### Why does the Rich Results Test say eligible, but I do not see stars in search?

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.

### Should I add Organization schema with the SoftwareApplication?

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.

## Read next

- [JSON-LD: how to write it, where to put it, how to test it](https://porteur.ai/guides/json-ld): See why Google recommends JSON-LD, where to place it, how to use one @graph, how to test with Google and schema.org, and what to fix.
- [The Rich Results Test: what it checks and what it does not](https://porteur.ai/guides/rich-results-test): Run Google’s Rich Results Test, read eligibility, warnings and errors, know its limits, and when to use schema.org’s validator and Search Console.
- [Organization schema: the fields that feed your knowledge panel](https://porteur.ai/guides/organization-schema): Set up Organization schema to feed your logo, social profiles and knowledge panel. See the fields, a JSON-LD example, where to place it, and how to test.
- [FAQ schema in 2026: valid, readable by assistants, no rich result](https://porteur.ai/guides/faq-schema): FAQ rich results are gone for most sites, but valid FAQ schema still helps assistants read your answers. Here is the shape, rules and tests.
- [Review schema: what is allowed, what is shown, what is self-serving](https://porteur.ai/guides/review-schema): What review schema is, when you can show stars, the self-serving rule, and how to mark up Product or SoftwareApplication reviews that validate.
- [Structured data](https://porteur.ai/glossary/structured-data): Structured data is schema markup that names your page type. See why it changes results, how to add JSON-LD, and how to validate it.

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: https://porteur.ai/
