The Founder's Guide to Schema for SaaS Pricing Pages
Add pricing schema to rank in AI Overviews and Google rich results. Step-by-step guide with templates for SaaS founders. No agency needed.
Why Your Pricing Page Needs Schema (And Why You're Probably Missing It)
Your pricing page is invisible to AI. Not metaphorically. Literally.
When ChatGPT, Perplexity, or Google's AI Overview tries to answer "how much does [your product] cost?" it reads your HTML like a human reads a blurry PDF. It sees text. It doesn't understand structure. It doesn't know which number is the actual price, which is a discount, or which is the annual commitment.
Schema markup fixes that. It's structured data—JSON-LD code you paste into your page head—that tells AI engines and search engines exactly what your pricing means.
The payoff? Your pricing appears in Google Shopping-style rich results, AI Overviews, and LLM responses. Competitors without schema don't get that real estate. You do.
This isn't theoretical. Schema markup implementation has become critical for AI search visibility, and pricing pages are one of the highest-ROI places to start. We'll walk through exactly how to do it—no developer required, though the code is simple enough that even non-technical founders can paste it.
Prerequisites: What You Need Before You Start
Before you add a single line of code, get these in place:
Technical requirements:
- Access to your site's HTML or page builder (Webflow, Framer, WordPress, Next.js—we'll cover all of them)
- A text editor (VS Code, Sublime, or even Notepad)
- Five minutes of uninterrupted focus
Information you'll need to gather:
- Your product name (exactly as it appears on your pricing page)
- All pricing tiers: name, price, currency, billing interval (monthly, annual, one-time)
- Which features are included in each tier
- Whether you offer a free trial or free plan
- Your company name and website URL
- Any discounts or promotional pricing (optional but valuable)
Tools to have open:
- Google's Rich Results Test — validates your schema in real time
- Schema.org's Live Tester — catches errors Google's tool misses
- Your site's code editor or page builder dashboard
If you haven't set up Google Search Console yet, verify your domain in Google Search Console first so you can monitor rich results performance after launch.
Understanding Pricing Schema: The Three Key Types
Schema markup isn't one thing. It's a language with dialects. For pricing pages, you need to understand three schema types that work together:
Product Schema
This is the container. It tells Google and AI engines "this page describes a product." It holds your product name, description, image, and rating (if you have one).
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Seoable",
"description": "All-in-one SEO and AI Engine Optimization platform",
"image": "https://yoursite.com/product-image.jpg",
"brand": {
"@type": "Brand",
"name": "Seoable"
}
}
Product schema is the foundation. Everything else—offers, ratings, availability—nests inside it.
Offer Schema
This is where pricing lives. One Offer object per pricing tier. It includes the price, currency, availability, and any terms (like "billed annually").
{
"@type": "Offer",
"name": "Pro Plan",
"price": "99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"priceValidUntil": "2025-12-31"
}
Each tier gets its own Offer. If you have three pricing tiers, you'll have three Offer objects nested inside your Product schema.
AggregateOffer Schema
If you want to show a price range ("from $29 to $299"), use AggregateOffer. It wraps multiple Offer objects and displays the low and high price.
{
"@type": "AggregateOffer",
"lowPrice": "29",
"highPrice": "299",
"priceCurrency": "USD",
"offerCount": "3"
}
For most SaaS pricing pages, you'll use Product + multiple Offer objects. If you want to show a range, wrap them in AggregateOffer.
Step 1: Write Your Product Schema
Start with the container. This is the outer structure that holds everything.
What you're doing: Creating a JSON-LD block that describes your product at a high level.
The template:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Your Product Name",
"description": "One-sentence description of what it does",
"image": "https://yoursite.com/product-hero.jpg",
"url": "https://yoursite.com/pricing",
"brand": {
"@type": "Brand",
"name": "Your Company Name"
},
"offers": [
// Offer objects go here
]
}
What each field means:
@context: Alwayshttps://schema.org. This tells the parser what vocabulary you're using.@type: AlwaysProductfor pricing pages.name: Your product name. Keep it short and exact.description: One sentence. What problem does it solve?image: A product image URL. Must be HTTPS. Recommended size: 1200x630px.url: The URL of your pricing page (or homepage if pricing is there).brand: Your company name and type.offers: An array (list) of Offer objects. We'll fill this next.
Pro tip: If you have customer reviews or ratings, add this inside Product:
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"ratingCount": "150"
}
Google uses ratings in rich results. If you don't have reviews yet, skip this—don't make it up.
Step 2: Create Offer Objects for Each Pricing Tier
Now fill the offers array. One object per tier.
The template for a single offer:
{
"@type": "Offer",
"name": "Starter Plan",
"description": "For solo founders and indie hackers",
"price": "29",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"billingDuration": "P1M",
"url": "https://yoursite.com/pricing#starter"
}
Field breakdown:
name: The tier name ("Starter", "Pro", "Enterprise").description: What's included or who it's for. Optional but helpful.price: The numeric price. No currency symbol. "29", not "$29".priceCurrency: ISO 4217 code. USD, EUR, GBP, etc.availability: For SaaS, almost alwayshttps://schema.org/InStock.billingDuration: ISO 8601 duration.P1M= monthly,P1Y= annual,P0D= one-time.url: Direct link to that tier's signup or section. Optional but recommended.
For a one-time payment (like Seoable's $99 offer):
{
"@type": "Offer",
"name": "One-Time Audit & Content Package",
"price": "99",
"priceCurrency": "USD",
"billingDuration": "P0D"
}
For an annual plan with monthly billing:
{
"@type": "Offer",
"name": "Annual Plan",
"price": "299",
"priceCurrency": "USD",
"billingDuration": "P1Y"
}
If you have three tiers, your offers array will have three of these objects, separated by commas.
Step 3: Add the Full Schema to Your Page
Now you have the complete structure. Here's a real-world example for a three-tier SaaS:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Seoable",
"description": "All-in-one SEO and AI Engine Optimization platform with domain audit, brand positioning, and AI-generated content in under 60 seconds",
"image": "https://seoable.dev/og-image.jpg",
"url": "https://seoable.dev/pricing",
"brand": {
"@type": "Brand",
"name": "Seoable"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.9",
"ratingCount": "42"
},
"offers": [
{
"@type": "Offer",
"name": "One-Time Audit & Content",
"description": "Domain audit, brand positioning, keyword roadmap, 100 AI-generated blog posts",
"price": "99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"billingDuration": "P0D",
"url": "https://seoable.dev/pricing"
}
]
}
This is valid, complete schema. You'll wrap it in <script> tags and paste it into your page <head>.
Where to paste it depends on your stack:
For WordPress
Use the Yoast SEO plugin or All in One SEO:
- Go to your pricing page in the editor
- Scroll to the SEO section
- Find "Schema" or "Structured Data"
- Paste the JSON-LD code
- Save
If you're coding manually, paste this in your theme's functions.php or directly in the page template:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
// ... rest of your schema
}
</script>
For Webflow
- Go to your pricing page
- Click the page settings (gear icon)
- Scroll to "Custom Code" → "Head Code"
- Paste:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
// ... rest of your schema
}
</script>
- Publish
For Next.js / React
Use the next/head component or next-seo:
import Head from 'next/head';
export default function PricingPage() {
const schema = {
"@context": "https://schema.org",
"@type": "Product",
// ... rest of your schema
};
return (
<>
<Head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
</Head>
{/* Your pricing page JSX */}
</>
);
}
For Framer
- Add a custom code component
- Paste the full
<script>block above - Place it in the page layout (usually in a hidden section)
For Shopify
Shopify handles product schema automatically for product pages. For custom pricing pages, use a custom liquid tag in your theme:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
// ... rest of your schema
}
</script>
Step 4: Validate Your Schema
Don't ship unvalidated schema. Errors are silent—Google just ignores them.
Use two validators:
Google's Rich Results Test
- Go to Google's Rich Results Test
- Enter your pricing page URL (or paste the HTML if it's not live yet)
- Click "Test URL"
- Look for green checkmarks next to "Product" and "Offer"
- If there are errors, Google will list them. Fix them.
Google's validator is strict but incomplete. It misses some valid schema. That's why you need the second tool.
Schema.org's Live Tester
- Go to Schema.org's Live Tester
- Paste your full page HTML or just the
<script>block - Click "Validate"
- Look for warnings (yellow) and errors (red)
- Warnings are usually safe to ignore. Errors must be fixed.
Common errors:
- Missing required fields (e.g.,
pricewithoutpriceCurrency) - Invalid ISO 8601 durations (e.g.,
P1Monthinstead ofP1M) - Malformed JSON (missing quotes, trailing commas)
Pro tip: If you're using Google Tag Manager to implement schema, validate the HTML output in GTM preview mode, not the template code itself.
Step 5: Test Rich Results and Monitor Performance
Once your schema is live and validated, Google needs time to crawl and process it. This usually takes 2–4 weeks.
Monitor in Google Search Console:
- Go to Google Search Console
- Click your property
- Go to "Enhancements" → "Rich Results"
- Look for "Product" in the list
- You should see impressions and clicks for your pricing page in rich results
If you see errors here, fix the schema and resubmit.
Check AI Overviews:
- Go to Google Search
- Search for "[your product] pricing" or "how much does [product] cost"
- Look at the AI Overview (the gray box at the top)
- If your schema is correct, your pricing should appear there
AI Overviews pull from rich results. Better schema = better visibility in AI Overviews.
Advanced: Adding Features and Inclusions to Offers
If you want to be more specific—list what's included in each tier—add an includes array to each Offer:
{
"@type": "Offer",
"name": "Pro Plan",
"price": "199",
"priceCurrency": "USD",
"includes": [
{
"@type": "Thing",
"name": "Domain audit"
},
{
"@type": "Thing",
"name": "50 AI-generated blog posts"
},
{
"@type": "Thing",
"name": "Priority support"
}
]
}
This is more granular but also more work. Schema markup for AI search benefits significantly from this level of detail, especially for LLM understanding. If you have time, do it. If you're shipping fast, basic Offer schema is enough.
Advanced: Handling Discounts and Promotional Pricing
If you're running a launch discount or seasonal offer, use priceValidUntil:
{
"@type": "Offer",
"name": "Starter Plan (Launch Discount)",
"price": "19",
"priceCurrency": "USD",
"priceValidUntil": "2025-03-31"
}
This tells Google the price is only valid until that date. After the date, Google will ignore this offer and look for the regular price.
For permanent discounts (like annual plans that cost less per month), don't use priceValidUntil. Just list the actual price.
Common Mistakes Founders Make (And How to Avoid Them)
Mistake 1: Forgetting priceCurrency
You can't have a price without a currency. Always include it.
// ❌ Wrong
"price": "99"
// ✅ Right
"price": "99",
"priceCurrency": "USD"
Mistake 2: Including Currency Symbols in the Price Field
Schema expects just the number.
// ❌ Wrong
"price": "$99"
// ✅ Right
"price": "99"
Mistake 3: Mismatching Your Page Content and Schema
If your page says "$99/month" but your schema says P0D (one-time), you'll confuse Google and users.
Always match schema to what's actually on the page.
Mistake 4: Only Adding Schema to One Pricing Tier
If you have three tiers, add schema for all three. Partial schema is worse than no schema—it looks like you're hiding information.
Mistake 5: Not Updating Schema When You Change Pricing
Schema is code. It doesn't auto-sync with your page copy. If you change a price, update the schema too.
Set a reminder. Or better yet, use a tool that auto-generates schema from your pricing data.
Why This Matters for Founders (Beyond Rich Results)
Schema isn't just about Google. It's about how AI engines understand your business.
When Perplexity, Claude, or ChatGPT answer a question about your product, they're reading your HTML. Without schema, they see a wall of text. With schema, they see structure. They know your product name, price, and features instantly.
This is critical for founders because:
AI Overviews are becoming traffic drivers. Google's AI Overview is now shown for 64% of searches. If your pricing appears there, you get clicks without traditional SEO rankings.
LLMs cite sources. When Claude or ChatGPT references your pricing, they link to your page. Schema makes that reference more likely and more accurate.
Competitive advantage. Most founders don't add schema to pricing pages. You will. Your pricing will appear in places competitors' won't.
Trust signal. Schema tells Google you're a legitimate business with real pricing. It's a small trust signal, but it compounds with other signals like Organization schema and Open Graph tags.
Quick Setup Checklist
Use this to make sure you haven't missed anything:
- Gathered all pricing tier names, prices, and billing intervals
- Wrote your Product schema with name, description, and image
- Created Offer objects for each tier
- Added
priceCurrencyandbillingDurationto each Offer - Tested schema in Google's Rich Results Test
- Tested schema in Schema.org's Live Tester
- Pasted the
<script>block into your page<head>(or page builder equivalent) - Published the page
- Waited 2–4 weeks for Google to crawl and process
- Checked Google Search Console for rich results impressions
- Tested a branded search to see if pricing appears in AI Overviews
Next Steps: Layering Schema for Maximum Impact
Pricing schema is one layer. For maximum visibility, add:
Organization schema on your homepage. This tells Google who you are, where you're based, and how to contact you. It's a trust signal that compounds with Offer schema.
FAQ schema if you have a pricing FAQ. This helps both Google and AI engines answer common questions about your pricing.
Open Graph tags for better click-through from AI search. When your pricing page is cited, a good preview matters.
If you're building a complete SEO foundation, start with the free SEO tool stack every founder should set up. GSC, GA4, and a schema validator should be live before you ship pricing schema.
For more advanced schema work, learn how to validate schema with multiple tools and master Google's Rich Results Test so you can catch errors before they cost you visibility.
The Reality
Schema markup is unsexy. It's code that users never see. But it's one of the few technical SEO moves that directly impacts visibility in AI Overviews and rich results—the places where buying intent is highest.
For founders, this is a high-ROI 30-minute task. You write the schema once. It works for months. You get visibility in places competitors don't bother to show up.
Ship it. Validate it. Monitor it. Move on to the next thing.
Your pricing page is too important to be invisible.
Get the next one on Sunday.
One short email a week. What is working in SEO right now. Unsubscribe in one click.
Subscribe on Substack →