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

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

  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.

ToolURLWhat it checksWhen to use
Rich Results Testhttps://search.google.com/test/rich-resultsEligibility 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 Validatorhttps://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

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