— AI Search & SEO

Schema.org for B2B agencies: a 2026 implementation guide

A practical schema.org implementation guide for B2B agencies in 2026. The seven JSON-LD types an agency site needs, two optional ones (ProfessionalService and HowTo), the patterns for services and price tiers, and the validation habits that keep schema accurate as the site grows.

— TL;DR

A B2B agency site needs seven schema.org types: Organization, WebSite, BreadcrumbList, Service, OfferCatalog, FAQPage and Article. ProfessionalService and HowTo are optional: the first expects a business address, and Google no longer shows HowTo rich results. Generate everything from one typed builder and validate every page type.

If you're a B2B agency in 2026, schema.org markup is one of the most practical technical SEO/AEO investments you can make. The cost is about one engineer-week of upfront work plus maintenance on each new content type. The return is a site that states who you are, what you sell and what it costs in a form machines can read. It does not guarantee citations.

This piece is the agency-specific implementation guide. It walks through the seven schema types an agency site needs in 2026, two optional ones, the agency-specific patterns (Service, OfferCatalog, price tiers), the centralization pattern that prevents drift, and the validation discipline that keeps the schema healthy as the site grows.

#Why agencies in particular

B2B agencies have specific schema needs that B2C SaaS doesn't. Three reasons:

Service-shaped queries. Most agency queries are "best [service] agency for [vertical]," "fixed-price [service]," "[service] agency under $X." These map cleanly to Service + OfferCatalog schema. AI engines can draw on these schemas when they answer them.

Tier-based pricing. Fixed-price agencies often sell at set tiers. Tier structure expressed as OfferCatalog.itemListElement with Offer.price states each price explicitly, which makes it easier for an AI assistant to say "Acme Agency offers a $15,000 fixed-price MVP build" instead of "Acme Agency offers MVP builds at various price points."

No PII issue. Agencies that publish founder names, photos and bios can add Person schema, which is widely reported to strengthen E-E-A-T signals. Agencies that don't (SolvSpot publishes under the organization, with no named authors) lean on Organization schema instead. Either way, an agency has more identity to describe than a typical B2C SaaS, and schema is where it gets stated clearly.

#The schema types

Seven are the baseline. Two are optional and marked as such. In implementation order:

PriorityTypeGoes onPurpose
1OrganizationEvery pageThe company entity
2ProfessionalService (optional)Homepage, if you publish a business addressThe service offering layer
3WebSiteHomepage onlyThe site itself + search action
4BreadcrumbListEvery non-home pageNavigation hierarchy
5ServiceEvery service pageWhat you sell, who provides it
6OfferCatalogEvery service page with pricingTiers + prices
7FAQPageEvery page with Q&AConversational extraction surface
8Article (or BlogPosting)Every blog post + case studyEditorial content
9HowTo (optional)Genuine step-by-step guidesStep-by-step content

If you ship the seven core types, you've covered the schema side of AEO. What remains is content quality and external signals (Reddit, HN, citations from other authoritative sites).

#1. Organization

The base schema. Every page should include this in the @graph.

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "@id": "https://yoursite.com#organization",
  "name": "Acme Agency",
  "legalName": "Acme Agency, LLC",
  "url": "https://yoursite.com",
  "description": "B2B software development and AI automation agency.",
  "email": "hello@yoursite.com",
  "foundingDate": "2023",
  "sameAs": [
    "https://twitter.com/acmeagency",
    "https://linkedin.com/company/acmeagency",
    "https://github.com/acmeagency"
  ]
}

For brand-only agencies (no founder identity disclosed), keep sameAs to the agency's own profiles. For named-operator agencies, also include Person schema with full sameAs to LinkedIn, GitHub, X, prior work.

For the underlying schema reference, see Organization on schema.org.

#2. ProfessionalService (optional)

Tells search and AI engines you provide professional services in a defined category. It goes on the homepage in the same @graph as Organization. Use it only if you publish a business address.

{
  "@context": "https://schema.org",
  "@type": "ProfessionalService",
  "@id": "https://yoursite.com#professionalservice",
  "name": "Acme Agency",
  "description": "B2B software development and AI automation.",
  "url": "https://yoursite.com",
  "provider": { "@id": "https://yoursite.com#organization" },
  "areaServed": { "@type": "Place", "name": "Worldwide" },
  "serviceType": ["SaaS development", "AI automation", "AEO/SEO consulting"]
}

The serviceType array states your service categories in plain terms. Be specific ("SaaS MVP development" is better than "software development").

ProfessionalService schema is a subtype of LocalBusiness, so validators and search engines expect an address with it. If you do not publish one, leave this type out and describe the business with Organization and Service. That is what this site does.

#3. WebSite

Goes on the homepage only. Tells AI engines this is a website with a name, optionally with site search.

{
  "@type": "WebSite",
  "@id": "https://yoursite.com#website",
  "url": "https://yoursite.com",
  "name": "Acme Agency",
  "publisher": { "@id": "https://yoursite.com#organization" },
  "potentialAction": {
    "@type": "SearchAction",
    "target": "https://yoursite.com/blog?q={search_term_string}",
    "query-input": "required name=search_term_string"
  }
}

If you don't have site search, omit the entire potentialAction block. Don't fake it; markup for a feature that isn't there is misleading. Google retired its sitelinks search box in late 2024, so the block no longer earns a search feature there either.

#4. BreadcrumbList

Goes on every non-home page. Tells AI engines the navigation path.

{
  "@type": "BreadcrumbList",
  "itemListElement": [
    { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://yoursite.com/" },
    { "@type": "ListItem", "position": 2, "name": "Services", "item": "https://yoursite.com/services" },
    { "@type": "ListItem", "position": 3, "name": "Workflow Automation", "item": "https://yoursite.com/services/workflow-automation" }
  ]
}

Position integers must be 1-indexed and consecutive. URLs must be absolute. The last breadcrumb should match the page you're on.

#5. Service + 6. OfferCatalog

The agency-specific high-leverage pair. Every service page ships these together.

{
  "@type": "Service",
  "@id": "https://yoursite.com/services/saas-mvp#service",
  "name": "SaaS MVP Build",
  "description": "Fixed-price B2B SaaS MVP build. Auth, billing, six core flows, custom design system, admin panel, production deploy.",
  "provider": { "@id": "https://yoursite.com#organization" },
  "serviceType": "SaaS MVP development",
  "areaServed": { "@type": "Place", "name": "Worldwide" },
  "url": "https://yoursite.com/services/saas-mvp",
  "hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "SaaS MVP Pricing",
    "itemListElement": [
      {
        "@type": "Offer",
        "name": "Starter",
        "price": 10000,
        "priceCurrency": "USD",
        "description": "3 core flows, auth, billing, basic admin (4 weeks)",
        "availability": "https://schema.org/InStock"
      },
      {
        "@type": "Offer",
        "name": "Standard",
        "price": 15000,
        "priceCurrency": "USD",
        "description": "6 core flows, custom design, full admin, analytics (6 weeks)",
        "availability": "https://schema.org/InStock"
      },
      {
        "@type": "Offer",
        "name": "Plus",
        "price": 25000,
        "priceCurrency": "USD",
        "description": "Standard + AI feature + extended support (8 weeks)",
        "availability": "https://schema.org/InStock"
      }
    ]
  }
}

Critical fields:

  • provider references Organization @id. Entity graph link.
  • Offer.price must be a number (not a string), with priceCurrency separately.
  • Offer.description is what tells the tiers apart for a reader, human or machine. Be specific.
  • Offer.availability uses schema.org enum URLs (InStock, OutOfStock, LimitedAvailability).

For a deeper dive into the schema mechanics, see The minimum schema markup every SaaS homepage needs in 2026.

#7. FAQPage

Often the most useful schema for AEO. Goes on homepage, every service page, every pillar blog post.

{
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "How much does a fixed-price SaaS MVP cost in 2026?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "At Acme Agency, a fixed-price SaaS MVP costs $10,000 to $25,000 depending on scope. The Standard tier (auth, Stripe billing, six core flows, custom design, admin panel, analytics) is $15,000 for a six-week build."
      }
    }
  ]
}

The Q&A phrasing matters. Write the questions the way real users type them into ChatGPT, not the way SEO keyword tools phrase them. Answer in 2 to 4 complete sentences with concrete facts.

#8. Article (or BlogPosting)

Every blog post and case study. Use BlogPosting for blog content; Article for editorial content (definitive guides, methodology pages, case studies).

{
  "@type": "BlogPosting",
  "@id": "https://yoursite.com/blog/post-slug#article",
  "headline": "How to write llms.txt for a SaaS site",
  "description": "Practical guide to llms.txt and llms-full.txt for B2B SaaS sites...",
  "datePublished": "2026-04-28",
  "dateModified": "2026-04-30",
  "author": { "@id": "https://yoursite.com#organization" },
  "publisher": { "@id": "https://yoursite.com#organization" },
  "wordCount": 2400,
  "articleSection": "AEO",
  "citation": [
    { "@type": "CreativeWork", "url": "https://llmstxt.org/" },
    { "@type": "CreativeWork", "url": "https://schema.org/" }
  ],
  "inLanguage": "en"
}

The citation array borrows from the Princeton GEO study, which found that content citing its sources was more visible in generative engine answers in its tests. That finding is about the visible content, not the markup, so treat the citation array as a tidy way to expose the same links, not a proven lever. You can auto-extract outbound markdown links from the post body and emit them as citation entries.

For brand-only agencies, author references Organization. For named-author agencies, author references a Person schema.

#9. HowTo (optional)

For pages that genuinely teach a procedure, step by step.

{
  "@type": "HowTo",
  "name": "How a 6-Week SaaS MVP Build Runs Week-by-Week",
  "description": "A realistic week-by-week build plan for a fixed-price B2B SaaS MVP.",
  "totalTime": "PT6W",
  "step": [
    {
      "@type": "HowToStep",
      "name": "Week 1: Foundation",
      "text": "Auth working, Stripe sandbox connected, schema deployed, staging URL live."
    },
    {
      "@type": "HowToStep",
      "name": "Week 2: Design system",
      "text": "Component library built, 3 of 6 flows in design, navigation skeleton in code."
    }
  ]
}

HowTo schema describes a procedure step by step. Google stopped showing HowTo rich results in 2023, so the type no longer earns a visual feature in Google Search, and whether any AI engine gives it special weight is not public. It is still valid markup. Add it if you have a page that teaches a real procedure, and skip it otherwise.

#The centralization pattern

Authoring schema by hand on each page is the canonical drift trap. Six months in, your Organization schema on the about page disagrees with the about page on the homepage, your prices in the OfferCatalog disagree with the prices on the pricing page, and your FAQ schema disagrees with the visible FAQ content.

The fix: centralize schema generation in a typed builder. Every page composes from typed builder functions; the underlying data lives in one place.

// src/lib/schema.ts (sketch)
export function organizationSchema() { /* ... */ }
export function professionalServiceSchema() { /* ... */ }
export function websiteSchema() { /* ... */ }
export function serviceSchema(input: ServiceInput) { /* ... */ }
export function articleSchema(input: ArticleInput) { /* ... */ }
export function faqPageSchema(faqs: FAQ[]) { /* ... */ }
export function breadcrumbSchema(crumbs: Crumb[]) { /* ... */ }
export function howToSchema(input: HowToInput) { /* ... */ }

Each function takes typed input, returns the JSON-LD object. The page composes:

// src/app/services/[slug]/page.tsx
const schemaGraph = {
  "@context": "https://schema.org",
  "@graph": [
    organizationSchema(),
    serviceSchema({ ... }),
    faqPageSchema(service.faqs),
    breadcrumbSchema([...]),
  ],
}

When pricing changes or a new sameAs URL is added, you update one constant and every page's schema updates automatically. This is the discipline that makes schema sustainable past the first ship.

#Validation discipline

Before pushing schema to production, validate it. Three tools worth running:

  1. Google Rich Results Test. Tells you which schemas validate and which are eligible for rich results.
  2. Schema.org Validator. Stricter than Google's; catches errors Google may silently ignore.
  3. Manual JSON parse: curl https://yoursite.com/services/x | grep -A 200 'application/ld+json' | jq to verify the JSON parses cleanly.

Run all three on every page type when you ship. Run them again after every schema change. Add validation to CI if you can; some teams ship a custom test that fetches every page and validates the JSON-LD against a Zod schema.

Quarterly: pick 5 random pages, run them through both validators. Catch drift before it compounds.

#What changes the calculus

Two schema-related shifts to watch in 2026:

  • New schema types aimed at AI search. Search engines may introduce or promote types for AI answers. New types could change what's worth marking up.
  • First-party formats from AI providers. If AI providers publish their own declarations for site owners, the multi-vendor schema landscape gets more complex.

For now, the seven core types above are the durable baseline. The marginal types (Speakable, EducationalOccupationalProgram, etc.) are worth adding only when you have a specific reason and the validation infrastructure to maintain them.

#Bottom line

A B2B agency site in 2026 needs seven schema.org types: Organization, WebSite, BreadcrumbList, Service, OfferCatalog, FAQPage and Article. Add ProfessionalService if you publish an address, and HowTo if you have real step-by-step content. Centralize generation in a typed builder. Validate every page type before shipping. Revalidate quarterly.

The implementation is about one engineer-week. Changes are picked up as crawlers revisit the site, which tends to take weeks rather than days, and schema on its own does not guarantee citations. The content-and-distribution layer above it takes months.

For the broader AEO playbook context, see AEO vs SEO: what changed in 2026. If you would like a second pair of eyes on your structured data, our AI search visibility audit reviews it in one week for a fixed $1,800. A free 20-minute call is the place to start.

Common questions.

  • Should I use Organization or ProfessionalService schema for an agency?

    Organization is the one every agency needs. ProfessionalService is a subtype of LocalBusiness, so it expects an address. If you publish a business address, adding it alongside Organization in one @graph, cross-referenced by @id, is a sound pattern. If you do not, Organization plus a Service entry for each offer describes the business without implying a location.

  • Do I need OfferCatalog for fixed-price agency offerings?

    It is worth adding. Agencies with public fixed prices can ship Service + OfferCatalog with each tier as an Offer. That states each tier and price in a machine-readable form, so a search or AI engine does not have to infer them from the page layout. It does not guarantee that your pricing is quoted correctly, but it removes one source of error.

  • Should agency blog posts use Article or BlogPosting schema?

    BlogPosting (a subtype of Article). It is the more specific type for blog content and takes the same fields as Article, such as wordCount and articleSection. Search and AI engines appear to treat BlogPosting and Article much the same, but BlogPosting is the more standard choice for blog content. Use Article for editorial content that isn't strictly blog (case studies, definitive guides, methodology pages).

  • What's the highest-leverage schema for an agency to ship first?

    FAQPage on every service page and pillar blog post. Q&A pairs map directly to conversational queries, which makes them easy for an AI engine to quote. After FAQPage, the priority order is: Organization (every page), Service + OfferCatalog (every service page), BreadcrumbList (every non-home page), and Article or BlogPosting on blog posts.

— Want help with this?

Get found in AI search ↗

The technical groundwork that helps ChatGPT, Perplexity and Google's AI answers understand your site and cite it: structured data, llms.txt, crawler access and content built to be quoted.

— Keep reading