Service schema markup

Published: April 10, 2026 | Author: Aubrey Yung

Table of contents

Service schema markup is one of the most underused tools in SEO. Unlike Product or Article, there is no Google rich result tied directly to Service schema, which makes many SEOs dismiss it. That is a mistake.

When you serve clients, not customers buying physical goods, structured data still does important work. It tells search engines and AI systems exactly what you do, who you do it for, where you do it, and what the outcome looks like. That is precisely the kind of explicit signal that reduces guesswork and misattribution, especially as search becomes more AI-driven.

This guide explains what Service schema markup is, which properties to use, how it connects to the rest of your entity graph, and where people go wrong when implementing it.

What is Service schema markup?

Service schema markup is structured data that uses the Schema.org vocabulary to describe a service offered by a business or individual. It helps search engines and AI systems understand the nature of your offering in a machine-readable way.

According to Schema.org, a Service is "a service provided by an organization, for example delivery service, print services, or installation services." The definition is intentionally broad, which is why it applies to everything from SEO consulting to legal advice, plumbing, and software subscriptions.

Note on ProfessionalService

ProfessionalService was formerly used for professional service businesses such as lawyers, consultants, and accountants. Schema.org has since deprecated it in favour of the more general Service type or its specific subclasses.

However, the deprecation only applies to ProfessionalService itself and not to the more precise subtypes. Types like Dentist, Lawyer, AccountingService, and FinancialService remain valid as LocalBusiness subtypes.

If you are using ProfessionalService as a generic catch-all, replace it with Service or the most specific applicable subtype. Check schema.org carefully before implementing.

Service schema is not tied to a Google rich result the way Product or Article are. That does not mean it is without value. Structured data has two audiences: search engines ranking pages and AI systems synthesising answers. Service schema contributes meaningfully to both, even without a star rating or price tag in the SERP.

What properties should you use in Service schema markup?

Service has no required properties in the Google sense, because there is no rich result spec tied to it. That gives you flexibility, but it also means you have to make deliberate choices about what to include.

The properties I recommend focusing on are:

  • @type: "Service", or a more specific subtype if one applies
  • @id: A stable, unique identifier for this service entity
  • name: The service name as it appears on the page
  • serviceType: A more specific descriptor of the service, e.g. "Schema Markup Consulting"
  • description: A concise, factual summary of the service
  • provider: The entity delivering the service, such as Person or Organisation. Link via @id to your Organisation / Person
  • audience: Who are your target audience.
  • areaServed: Where the service is available, it can be region, country, or "Worldwide"
  • serviceOutput: The tangible outcome of the service, e.g. "SEO Audit Report"
  • hasOfferCatalog: A structured list of all services if used on an overview page
  • offers: Pricing details, if publicly available on the page
  • potentialAction: A callable action, such as QuoteAction
  • hoursAvailable: When the service is available
  • availableChannel: How the service is accessed, such as online, by phone, in person

Service schema markup example (JSON-LD)

Here is a practical example for a legal service. This is the kind of markup you would implement on a dedicated service page, not on the homepage.

A clean pattern is to use hasOfferCatalog to enumerate the specific activities that sit within a broader Service. The Service itself is the top-level offering; hasOfferCatalog lists what is included. serviceType at each level references the parent category one level above.

Service schema markup example
{
  "@context": "https://schema.org",
  "@type": "Service",
  "@id": "https://example-lawfirm.com/services/employment-law/redundancy-claims/#service",
  "name": "Redundancy Claims",
  "serviceType": "Employment Law",
  "description": "Legal advice and representation for employees facing redundancy, including statutory pay entitlements, settlement agreements, and unfair redundancy disputes.",
  "provider": {
    "@id": "https://example-lawfirm.com/#organization",
    "name": "Example Law Firm",
    "url": "https://example-lawfirm.com/"
  },
  "areaServed": {
    "@type": "Place",
    "name": "England and Wales"
  },
  "hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "Redundancy Claims Services",
    "itemListElement": [
      {
        "@type": "Offer",
        "itemOffered": {
          "@type": "Service",
          "name": "Statutory Redundancy Pay Assessment",
          "serviceType": "Redundancy Claims"
        }
      },
      {
        "@type": "Offer",
        "itemOffered": {
          "@type": "Service",
          "name": "Settlement Agreement Review",
          "serviceType": "Redundancy Claims"
        }
      },
      {
        "@type": "Offer",
        "itemOffered": {
          "@type": "Service",
          "name": "Unfair Redundancy Claim",
          "serviceType": "Redundancy Claims"
        }
      },
      {
        "@type": "Offer",
        "itemOffered": {
          "@type": "Service",
          "name": "Collective Redundancy Advice",
          "serviceType": "Redundancy Claims"
        }
      }
    ]
  }
}

If pricing is publicly listed on the page, you can add an offers property. If it is not visible to users, leave it out. Marking up information that is not on the page is a violation of Google's structured data guidelines.

Notice that the provider references the Organisation by @id, name and URL only, rather than repeating all its properties. This is how you build a clean entity graph without duplication. The Organisation schema, with its full properties, lives separately on the homepage.

Visaulize the service schema in the entity graph

Service vs. Product schema markup

Service and Product are not mutually exclusive - instead, they overlap deliberately, and Schema.org's own vocabulary acknowledges this.

As we can see from the Schema.org definition of Product is broad: "any offered product or service, for example a pair of shoes, a concert ticket, the rental of a car, a haircut, or an episode of a TV show streamed online." A haircut is a service. A concert ticket is access to a service.

So the question is not which one is correct. The question is which one is most precise for your use case, and whether there is a case for using both at the same time.

ProductService
What it describesA tangible or intangible item offered for sale or useAn activity or process performed by a provider for a beneficiary
Key Schema.org propertiesname, image, offers, brand, sku, gtin, aggregateRatingname, serviceType, provider, areaServed, serviceOutput, availableChannel
Rich result eligibilityYes, product snippet with price, rating, availabilityNo direct Google rich result
Pricing modelFixed price, typically per unitVariable, quoted, subscription, or retainer
Provider / sellerseller inside Offerprovider at the Service level

When and how to co-type Service and Product

Co-typing means assigning multiple @type values to a single entity. In JSON-LD, this is done by passing an array: "@type": ["Service", "Product"]. The entity inherits the valid properties of both types.

For service businesses, co-typing is a deliberate choice to gain the structured data benefits of both service and product vocabularies. A Product rich result can show a price, star rating, and availability directly in the SERP. For service businesses with a clearly packaged offering or visible customer testimonials, this is a meaningful visibility gain on a competitive query.

Good candidates for co-typing: a fixed-price SEO audit package, a structured onboarding programme with a stated fee, an online course, a defined consultation hour at a listed rate. Poor candidates: bespoke retainers with no listed price, project-based work quoted per engagement. For those, Service alone is more accurate.

Each type contributes a distinct set of properties. Service gives you the semantic layer: provider and areaServed map the offering to an entity and a geography; serviceType and serviceOutput make the nature and outcome of the work explicit. Product gives you the commercial layer: image and offers are required for rich result eligibility; aggregateRating and review attach trust signals directly to the offering; brand is useful if the service is offered under a name distinct from the Organisation.

PropertyComes fromPurpose
serviceTypeServicePrecise service category for search relevance
serviceOutputServiceMakes the deliverable explicit for AI systems
providerServiceLinks the offering to your Organisation entity
areaServedServiceGeographic scope of the service
availableChannelServiceHow the service can be accessed
imageService, ProductImageSEO
offersProductPrice and availability for rich results
aggregateRatingProductStar rating tied to this specific offering
reviewProductIndividual reviews of the offering
brandService, ProductUseful if the service is offered under a distinct brand name

Co-type Service + Product example (JSON-LD)

Here is how you would implement co-typing for a fixed-price SEO audit package. Note the requirements: a visible price, an image on the page, and reviews hosted on the page.

Co-type Service + Product example (JSON-LD)
{
  "@context": "https://schema.org",
  "@type": ["Service", "Product"],
  "@id": "https://aubreyyung.com/services/seo-audit/#service",
  "name": "SEO Audit",
  "description": "A comprehensive audit of your website's SEO performance.
    Covers technical issues, content gaps, and growth opportunities,
    with prioritised recommendations.",
  "image": "https://aubreyyung.com/images/seo-audit-deliverable.jpg",

  // Service-specific properties
  "serviceType": "SEO Audit",
  "serviceOutput": {
    "@type": "Thing",
    "name": "SEO Audit Report"
  },
  "provider": {
    "@id": "https://aubreyyung.com/#organization"
  },
  "areaServed": {
    "@type": "Place",
    "name": "Worldwide"
  },

  // Product-specific properties
  "offers": {
    "@type": "Offer",
    "price": "1500",
    "priceCurrency": "EUR",
    "availability": "https://schema.org/InStock",
    "seller": {
      "@id": "https://aubreyyung.com/#organization"
    }
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.9",
    "reviewCount": "12"
  }
}

A few things to notice in this example. First, the @type array contains both Service and Product, the order does not really matter. Second, the properties are drawn from both types: serviceType, serviceOutput, provider, and areaServed come from Service; image, offers, and aggregateRating come from Product. Third, the aggregateRating is only included if reviews are genuinely displayed on the page.

If your service page does not have a public price listed or hosted reviews, remove them and only include what is visible.

Best practices for Service schema markup

1. Implement at the individual service page level, not just the homepage

I see this regularly: a business adds Organisation schema to the homepage, adds a rough description of services, and considers the job done. That is not enough.

Each service page should carry its own Service schema instance. The homepage is for establishing your entity. Individual service pages are where you describe what each service actually is, what it delivers, and who it is for.

2. Use a stable @id for every service

Assign a permanent, consistent @id to each Service entity. A good convention is the canonical URL of the service page with a fragment identifier, for example https://aubreyyung.com/services/schema-markup/#service.

If a plugin auto-generates these identifiers, or if @id is missing entirely, service entities cannot be reliably referenced by other parts of your schema graph. You also lose the compounding benefit of consistent signals over time.

3. Use serviceType to classify, not describe

serviceType often accepts free text with no controlled vocabulary, which means you have full control and full responsibility for what you put there.

You can go crazy, but I would recommend treating serviceType as a category label. Don’t use serviceType to extend or complement name. That creates redundancy with description and blurs its classification intent. Pick the most precise category label for the service, and let name and description handle the rest.

My approach is using the service’s immediate parent category as serviceType. This gives search engines a traversable classification chain without needing to read the full page hierarchy.

For example, a law firm offering Family Law, Employment Law, and Corporate Law services would use those as the serviceType for each respective Service entity. The name identifies the specific offering on the page; serviceType places it in a recognisable category.

In short, three properties each have a distinct role:

  • name: the specific offering as it appears on the page
  • serviceType: the category or classification of the service
  • description: what the service does and delivers

4. Match markup to visible page content exactly

This is the same rule that applies to Product schema, and it is just as important here. Everything declared in your Service markup must be visible and verifiable on the page.

If you have a description in structured data that does not appear anywhere on the page, that is a mismatch. These inconsistencies are invisible to users but are not invisible to search engines.

The safest implementation generates schema from the same source that renders the visible page content. If a CMS field updates the page description, the same field should update the schema description.

5. Connect services to your Organisation entity

Every Service schema should reference the providing Organisation or Person via the provider property. This is how you build a coherent entity graph. Isolated Service entities, not connected to a known provider, carry less authority and are harder for search engines to attribute correctly.

Also, use a reference to the @id of your Organisation entity rather than embedding the full object. This way, you don’t need to update the 10+ Organisation schema on all your service pages. Instead, you can just update the main Organisation entity once and be done with it.

6. Use areaServed deliberately

For service businesses, areaServed does a lot of quiet work. It tells search engines which markets you serve, which helps with geographic relevance signals, especially for businesses operating remotely or across multiple regions.

If you serve clients globally, use a value like "Worldwide" or a list of specific regions. If you serve specific countries or cities, name them explicitly. Linking to a Wikidata entity adds precision if your tech stack allows for it.

One mistake I see frequently: using areaServed to mark territory you aspire to serve rather than where you actually deliver. Keep it accurate.

7. Add potentialAction if you have a clear call to action

If your service page has a contact form, booking link, or quote request, potentialAction turns that into a structured signal. This is useful for AI systems that look for actionable endpoints when recommending service providers.

Only add potentialAction if the action is genuinely accessible on the page. Do not add it to signal intent you cannot actually support.

jsonld
"potentialAction": {
  "@type": "QuoteAction",
  "name": "Request a Quote",
  "target": {
    "@type": "EntryPoint",
    "urlTemplate": "https://example-lawfirm.com/contact/",
    "actionPlatform": "https://schema.org/DesktopWebPlatform"
  }
}

8. Do not mark up reviews you do not host

Service businesses often have reviews on Google, Trustpilot, or industry directories. You cannot mark up reviews from third-party platforms in your own schema. Only review content that is rendered on your own page is eligible.

If you collect and display client testimonials directly on your site, those can be marked up. If they are embedded from an external platform, they cannot. Violating this rule creates the risk of losing rich result eligibility for other schema types on the same site.

9. Keep service schema updated as offerings change

The most reliable implementations I have seen are ones where schema is generated from shared CMS data rather than hard-coded in templates.

If you hard-code JSON-LD directly into page templates, set a calendar reminder to audit it quarterly at minimum. The mismatch between stale markup and updated content is one of the most common and avoidable errors in service schema implementation.

Aubrey Yung

Aubrey Yung

Aubrey is an SEO Manager and Schema Markup Consultant with years of B2B and B2C marketing experience. Outside of work, she loves traveling and learning languages.

Related Post

Schema

Brand schema markup

This guide explains what brand schema markup is, which properties matter, how to implement it correctly, and why it’s becoming critical for AI-driven search experiences.

Schema

How to use audience in schema markup

This guide explains how to use the audience schema markup correctly, with practical patterns and examples tailored to real-world eCommerce and SaaS implementations.

Schema

Person Schema Markup

A Person Schema markup is a type of structured data that helps search engines understand specific information about a person.

Schema

Organization schema

Many brands overlook Organization schema. Learn how structured data can give your company a competitive edge in Google’s search results and knowledge panels.