How to describe a SaaS product with schema markup
A software-as-a-service product is very different to an ecommerce product. This also means the way you describe it with structured data will differ significantly.
That is, instead of using Product schema, you will use WebApplication and use very different attributes to describe the monthly or annual subscription nature of the product.
Let’s get started!
What schema type should I use for a Saas product?
Many SaaS products are accessed through a web browser.
For this reason, WebApplication is the best schema type to describe a SaaS product.
For example, to use Canva, Clearscope, Semrush, Ahrefs, and Adobe Express, you would navigate to their respective websites in your web browser (e.g., Chrome, Safari, Edge).
What is WebApplication schema and how is it different to SoftwareApplication schema?
WebApplication is a subtype of SoftwareApplication schema which is a subtype of CreativeWork schema.
Examples of WebApplication:
- Clearscope
- Adobe Express
- Canva
- Substack
- Monday.com
- Netflix
- Typeform
- Google Sheets
- Microsoft 365
Examples of SoftwareApplication:
- Screaming Frog SEO Spider
- Final Cut Pro
- Google Chrome
- Adobe Acrobat Reader
- Microsoft Excel
The main difference between SoftwareApplication and WebApplication schema is how they are accessed. Programs such as Final Cut Pro, Google Chrome and Screaming Frog require physical downloads and installation whereas apps such as Google Sheets, Canva, and Substack are accessed via a web browser.
What schema.org properties does WebApplication schema type offer?
When you compare Schema.org documentation between WebApplication and SoftwareApplication you will notice WebApplication has only one unique attribute – the browserRequirements item property.
This makes sense because this is the defining feature of disambiguation between a piece of software you install on your device versus a cloud-based software you access directly through a web browser.
But because WebApplication is a child of SoftwareApplication and CreativeWork schema, you can use all of their attributes to describe your Saas product.
How to describe a SaaS product with schema: real world examples
💡 Skip to the complete JSON-LD
In its most basic form, this is how you would begin to describe a SaaS product with JSON-LD.
{
"@context":"https://schema.org",
"@type":"WebApplication"
}
The above code snippet communicates two basic things:
- The code is based on Schema.org, and
- The schema type being described is WebApplication
Now, let’s use Adobe Express as an example.
{
"@context":"https://schema.org",
"@type":"WebApplication",
"name":"Adobe Express",
"url":"https://express.adobe.com/",
"@id":"https://express.adobe.com/#webapplication"
}
What we’ve added are three important things to help disambiguate Adobe Express from other Adobe SaaS products. That is, we are describing the entity known as Adobe Express which happens to be a WebApplication schema type.
The JSON-LD describes:
- the name of the product (i.e., Adobe Express)
- the URL where the app can be accessed, and
- the unique identifier of the entity (@id).
“But Daniel -“, you being to protest.
“Why have you used app URL instead of the marketing-led URL?”
To answer this, we first have to take a look and compare the two different URLs.
The marketing-led URL is adobe.com/express/. This page describes the features and benefits of the product and moves the audience towards signing up.
Compare this with express.adobe.com which requires an existing account and is a non-indexable URL.
Both URLs serve very different functions and this is why it is important to use the correct URL for the WebApplication.
In this case, the best URL to describe Adobe Express as a SaaS product is express.adobe.com.
Next, we add the unique attribute that is reserved for SaaS products – browserRequirements.
{
"@context":"https://schema.org",
"@type":"WebApplication",
"name":"Adobe Express",
"url":"https://express.adobe.com/",
"@id":"https://express.adobe.com/#webapplication",
"browserRequirements":["requires HTML5 support","requires JavaScript"]
}
You can enter any text as the value for browserRequirements.
In the above example, we’ve simply communicated that Adobe Express requires a web browser that supports HTML5 and JavaScript.
Next, we can use the attributes of SoftwareApplicable and CreativeWork to better describe the SaaS product to search engines, specifically, connecting it to Adobe Inc’s entity (which is a tenet of semantic SEO).
{
"@context":"https://schema.org",
"@type":"WebApplication",
"name":"Adobe Express",
"url":"https://express.adobe.com/",
"@id":"https://express.adobe.com/#webapplication",
"browserRequirements":["requires HTML5 support","requires JavaScript"],
"sameAs":"https://www.adobe.com/express/",
"applicationCategory":"DesignApplication",
"applicationSuite":"Adobe Creative Cloud",
"permissions":"may run only with an active internet connection",
"operatingSystem":["Windows 8.1 or later","macOS 10.13 or later","Chromebook"],
"memoryRequirements":"4-GB",
"releaseNotes":"https://helpx.adobe.com/au/express/release-notes.html",
"copyrightHolder":{
"@type":"corporation",
"name":"Adobe",
"legalName":"Adobe Inc.",
"alternateName":"Adobe Systems Incorporated",
"@id":"https://www.adobe.com#organization",
"tickerSymbol":"ADBE",
"sameAs":[
"https://www.linkedin.com/company/adobe/",
"https://www.instagram.com/adobe/",
"https://twitter.com/Adobe",
"https://en.wikipedia.org/wiki/Adobe_Inc."]
},
"creator":{"@id":"https://www.adobe.com#organization"},
"publisher":{"@id":"https://www.adobe.com#organization"}
}
The above JSON-LD sums up all the necessary information about the SaaS product and a clear relationship has been defined between the Adobe Express and Adobe Inc.
To provide a valid applicationCategory, refer to the table published on this Google documentation page entitled ‘Software App (SoftwareApplication) Schema’.
But what if you want to get the benefits of having product rich results displayed for your SaaS product?
Adobe Express is a free product so it is relatively easy to describe this with schema.
"offers":{
"@type":"offer",
"priceSpecification":{
"@type":"UnitPriceSpecification",
"price":"0.00",
"priceCurrency":"USD"
}
}
But what if your SaaS product has public pricing, has more than one tier of subscription plan and you want to reflect this in your markup?
Read on.
How can I communicate the monthly subscription cost of a Saas product using JSON-LD?
For this example, I’m are going to use Ahrefs because it has a multiple paid subscription tiers and their pricing is accessible to the public.
We are going to mark up the Lite, Standard, Advanced and Enterprise plans with schema.
First, we are going to use the AggregateOffer schema type because there is more than one pricing option available.
"offers":{
"@type":"AggregateOffer",
"highPrice":"999.00",
"lowPrice":"99.00",
"offerCount":"4",
"priceCurrency":"USD"
}
This JSON-LD tells search engines the following:
- Ahrefs has 4 offers (pricing plans)
- The lowest priced subscription starts at $99
- The highest priced subscription starts at $999
- The currency is USD
Next, let’s describe each of the four offers using the UnitPriceSpecification schema type. In particular, we need to specify:
- what the name of each offer is,
- it’s corresponding price, currency, and URL; and
- the frequency of the subscription model (e.g., per month, per year etc).
To do this, we will need to nest an array of four (4) individual offers to the existing offer item property for the WebApplication schema in addition to attributes to communicate the monthly subscription fee for each pricing tier.
"offers":{
"@type":"AggregateOffer",
"highPrice":"999.00",
"lowPrice":"99.00",
"offerCount":"4",
"priceCurrency":"USD",
"offers":[
{
"@type":"Offer",
"priceSpecification":
{
"@type":"UnitPriceSpecification",
"price":"99",
"priceCurrency":"USD",
"name":"Ahrefs Lite monthly subscription",
"url":"https://ahrefs.com/signup?interval=monthly&plan=lite",
"referenceQuantity":{
"@type":"QuantitativeValue",
"value":"1",
"unitCode":"MON"
}
}
},
{
"@type":"Offer",
"priceSpecification":
{
"@type":"UnitPriceSpecification",
"price":"199",
"priceCurrency":"USD",
"name":"Ahrefs Standard monthly subscription",
"url":"https://ahrefs.com/signup?interval=monthly&plan=standard",
"referenceQuantity":{
"@type":"QuantitativeValue",
"value":"1",
"unitCode":"MON"
}
}
},
{
"@type":"Offer",
"priceSpecification":
{
"@type":"UnitPriceSpecification",
"price":"399",
"priceCurrency":"USD",
"name":"Ahrefs Advanced monthly subscription",
"url":"https://ahrefs.com/signup?interval=monthly&plan=advanced",
"referenceQuantity":{
"@type":"QuantitativeValue",
"value":"1",
"unitCode":"MON"
}
}
},
{
"@type":"Offer",
"priceSpecification":
{
"@type":"UnitPriceSpecification",
"price":"999",
"priceCurrency":"USD",
"name":"Ahrefs Enterprise monthly subscription",
"url":"https://ahrefs.com/signup?interval=monthly&plan=enterprise",
"referenceQuantity":{
"@type":"QuantitativeValue",
"value":"1",
"unitCode":"MON"
}
}
}
]
}
📍 Editor’s note: big thank you to Jarno van Driel for helping me correct the above JSON-LD output.
Putting everything together, Ahrefs’ SaaS product schema looks like this:
{
"@context":"https://schema.org",
"@type":"WebApplication",
"name":"Ahrefs",
"url":"https://app.ahrefs.com/",
"@id":"https://app.ahrefs.com/#webapplication",
"browserRequirements":["requires HTML5 support","requires JavaScript"],
"sameAs":"https://ahrefs.com/dashboard",
"applicationCategory":"BusinessApplication",
"permissions":"may run only with an active internet connection",
"copyrightHolder":{
"@type":"Organization",
"name":"Ahrefs Pte. Ltd.",
"alternateName":"Ahrefs",
"@id":"https://ahrefs.com#organization",
"logo":"https://assets-3b70.kxcdn.com/images/mediakit/[email protected]?v=2",
"email":"[email protected]",
"address":{
"@type":"PostalAddress",
"addressCountry":"SG",
"postalCode":"048581",
"streetAddress":"16 Raffles Quay"
},
"founder":{
"@type":"Person",
"name":"Dmitry Gerasimenko",
"alternateName":"Dmytro Gerasymenko",
"jobTitle":"CEO",
"image":"https://static.ahrefs.com/images/team/dmitry-g.jpg",
"sameAs":[
"https://twitter.com/botsbreeder",
"https://www.linkedin.com/in/dmitrygerasimenko/"]
},
"sameAs":[
"https://www.crunchbase.com/organization/ahrefs",
"https://www.linkedin.com/company/ahrefs",
"https://www.zoominfo.com/c/ahrefs-pte-ltd/346986605",
"https://www.wikidata.org/wiki/Q107533769"]
},
"maintainer":{"@id":"https://ahrefs.com#organization"},
"publisher":{"@id":"https://ahrefs.com#organization"},
"offers":{
"@type":"AggregateOffer",
"highPrice":"999.00",
"lowPrice":"99.00",
"offerCount":"4",
"priceCurrency":"USD",
"offers":[
{
"@type":"Offer",
"priceSpecification":
{
"@type":"UnitPriceSpecification",
"price":"99",
"priceCurrency":"USD",
"name":"Ahrefs Lite monthly subscription",
"url":"https://ahrefs.com/signup?interval=monthly&plan=lite",
"referenceQuantity":{
"@type":"QuantitativeValue",
"value":"1",
"unitCode":"MON"
}
}
},
{
"@type":"Offer",
"priceSpecification":
{
"@type":"UnitPriceSpecification",
"price":"199",
"priceCurrency":"USD",
"name":"Ahrefs Standard monthly subscription",
"url":"https://ahrefs.com/signup?interval=monthly&plan=standard",
"referenceQuantity":{
"@type":"QuantitativeValue",
"value":"1",
"unitCode":"MON"
}
}
},
{
"@type":"Offer",
"priceSpecification":
{
"@type":"UnitPriceSpecification",
"price":"399",
"priceCurrency":"USD",
"name":"Ahrefs Advanced monthly subscription",
"url":"https://ahrefs.com/signup?interval=monthly&plan=advanced",
"referenceQuantity":{
"@type":"QuantitativeValue",
"value":"1",
"unitCode":"MON"
}
}
},
{
"@type":"Offer",
"priceSpecification":
{
"@type":"UnitPriceSpecification",
"price":"999",
"priceCurrency":"USD",
"name":"Ahrefs Enterprise monthly subscription",
"url":"https://ahrefs.com/signup?interval=monthly&plan=enterprise",
"referenceQuantity":{
"@type":"QuantitativeValue",
"value":"1",
"unitCode":"MON"
}
}
}
]
}
}
And you can see how Google’s Rich Results Test parses the JSON-LD by clicking on this link and the following screenshot illustrates the entities we’ve described.
However, there is a big issue of what we’ve done so far.
We have been describing a SaaS product from the perspective of injecting the JSON-LD on the app’s URL and for many paid and premium SaaS solutions, these URLs are not public facing.
That is, they require a user to sign up and sign into the app.
Therefore, having schema written for the app’s URL doesn’t make any sense which leads us to the next section – where should we describe the SaaS product on our website and how do we do it?
Where should I use WebApplication schema for the SaaS Product?
We need to nest WebApplication schema on one or more URLs of your website.
For the SaaS product schema I compiled for Adobe Express, the most appropriate way to use this schema would be on the marketing-led URL by connecting the WebApplication schema to WebPage schema using the about item property.
That is, we are going to tell Google that the main focus of adobe.com/express/ is the WebApplication schema which happens to be our SaaS product Adobe Express.
This is what the schema for the webpage adobe.com/express/ could look like.
{
"@context":"https://schema.org",
"@type":"WebPage",
"url":"https://www.adobe.com/express/",
"@id":"https://www.adobe.com/express/#webpage",
"isPartOf":{
"@type":"Website",
"url":"https://www.adobe.com",
"@id":"https://www.adobe.com#website",
"publisher":{
"@type":"Corporation",
"name":"Adobe",
"legalName":"Adobe Inc.",
"alternateName":"Adobe Systems Incorporated",
"@id":"https://www.adobe.com#organization",
"tickerSymbol":"ADBE",
"sameAs":[
"https://www.linkedin.com/company/adobe/",
"https://www.instagram.com/adobe/",
"https://twitter.com/Adobe",
"https://en.wikipedia.org/wiki/Adobe_Inc."]
}
}
}
And this is how we would connect the SaaS product schema to the above.
{
"@context":"https://schema.org",
"@type":"WebPage",
"url":"https://www.adobe.com/express/",
"@id":"https://www.adobe.com/express/#webpage",
"isPartOf":{
"@type":"Website",
"url":"https://www.adobe.com",
"@id":"https://www.adobe.com#website",
"publisher":{
"@type":"Corporation",
"name":"Adobe",
"legalName":"Adobe Inc.",
"alternateName":"Adobe Systems Incorporated",
"@id":"https://www.adobe.com#organization",
"tickerSymbol":"ADBE",
"sameAs":[
"https://www.linkedin.com/company/adobe/",
"https://www.instagram.com/adobe/",
"https://twitter.com/Adobe",
"https://en.wikipedia.org/wiki/Adobe_Inc."]
}
},
"about":{
"@type":"WebApplication",
"name":"Adobe Express",
"url":"https://express.adobe.com/",
"@id":"https://express.adobe.com/#webapplication",
"browserRequirements":["requires HTML5 support","requires JavaScript"],
"sameAs":"https://www.adobe.com/express/",
"applicationCategory":"DesignApplication",
"applicationSuite":"Adobe Creative Cloud",
"permissions":"may run only with an active internet connection",
"operatingSystem":["Windows 8.1 or later","macOS 10.13 or later","Chromebook"],
"memoryRequirements":"4-GB",
"releaseNotes":"https://helpx.adobe.com/au/express/release-notes.html",
"copyrightHolder":{"@id":"https://www.adobe.com#organization"},
"creator":{"@id":"https://www.adobe.com#organization"},
"publisher":{"@id":"https://www.adobe.com#organization"},
"maintainer":{"@id":"https://www.adobe.com#organization"},
"offers":{
"@type":"offer",
"priceSpecification":{
"@type":"UnitPriceSpecification",
"price":"0.00",
"priceCurrency":"USD"
}
}
}
}
We would do the same for Ahrefs where the WebApplication schema for the SEO tool could be described as:
- An entity mentioned on a product-led blog post
- As the main entity of its pricing page
For example, for the blog post entitled ‘SEO for Lead Generation: How to Drive High-Quality Leads Using Product-Led Content’ by Si Quan Ong, the easiest way to integrate the SaaS tool would be to add the mention attribute to the existing WebPage schema.
And the extra JSON-LD would look like this:
"mentions":{
"@type":"WebApplication",
"name":"Ahrefs",
"url":"https://app.ahrefs.com/",
"@id":"https://app.ahrefs.com/#webapplication",
"browserRequirements":[
"requires HTML5 support",
"requires JavaScript"],
"sameAs":"https://ahrefs.com/dashboard",
"applicationCategory":"BusinessApplication",
"permissions":"may run only with an active internet connection",
"offers":{
"@type":"AggregateOffer",
"highPrice":"999.00",
"lowPrice":"99.00",
"offerCount":"4",
"priceCurrency":"USD",
"offers":[
{
"@type":"Offer",
"priceSpecification":
{
"@type":"UnitPriceSpecification",
"price":"99",
"priceCurrency":"USD",
"name":"Ahrefs Lite monthly subscription",
"url":"https://ahrefs.com/signup?interval=monthly&plan=lite",
"referenceQuantity":{
"@type":"QuantitativeValue",
"value":"1",
"unitCode":"MON"
}
}
},
{
"@type":"Offer",
"priceSpecification":
{
"@type":"UnitPriceSpecification",
"price":"199",
"priceCurrency":"USD",
"name":"Ahrefs Standard monthly subscription",
"url":"https://ahrefs.com/signup?interval=monthly&plan=standard",
"referenceQuantity":{
"@type":"QuantitativeValue",
"value":"1",
"unitCode":"MON"
}
}
},
{
"@type":"Offer",
"priceSpecification":
{
"@type":"UnitPriceSpecification",
"price":"399",
"priceCurrency":"USD",
"name":"Ahrefs Advanced monthly subscription",
"url":"https://ahrefs.com/signup?interval=monthly&plan=advanced",
"referenceQuantity":{
"@type":"QuantitativeValue",
"value":"1",
"unitCode":"MON"
}
}
},
{
"@type":"Offer",
"priceSpecification":
{
"@type":"UnitPriceSpecification",
"price":"999",
"priceCurrency":"USD",
"name":"Ahrefs Enterprise monthly subscription",
"url":"https://ahrefs.com/signup?interval=monthly&plan=enterprise",
"referenceQuantity":{
"@type":"QuantitativeValue",
"value":"1",
"unitCode":"MON"
}
}
}
]
}
}
Another possible way to integrate Ahref’s WebApplication schema would be to nest it as part of its Organization schema.
Is there any benefit of marking up a SaaS product with semantic SEO?
If you’re a startup, it is probably not worth the effort because there are other things you should focus on from a business perspective.
However, for an organisation such as Adobe that have many SaaS products in its portfolio, marking up individual SaaS solutions may help Google understand each product better, especially if the product was part of an acquisition and has been rebranded (e.g., from Magento Ecommerce to Adobe Commerce).
In my professional opinion, semantic SEO is the missing piece to most of the web’s SEO strategy. This is because schema markup tells a search engine what it will find when it crawls a webpage.
While search engines will still use NLP to understand the unstructured data, having the same information described in structured data reduces their need to make guesses on your behalf.
Therefore, semantic SEO is quite literally optimisation for search engines.