XooCode(){

Occupation

Occupation describes a profession or job category, not a specific job listing. It has 8 properties of its own: estimatedSalary (salary range data), occupationalCategory (standardized job codes), skills, qualifications, responsibilities, educationRequirements, experienceRequirements, and occupationLocation (where the data applies). Google reads Occupation for the salary estimate card in job-related searches.

The type hierarchy is Thing → Intangible → Occupation. Occupation is for career information pages ("What does a data engineer earn?"), not for job listings. A JobPosting advertises a specific open position. An Occupation describes the profession in general. JobPosting can reference an Occupation via relevantOccupation.

Full example of schema.org/Occupation json-ld markup

The markup is verified as valid with Rich Results Test from Google.

Highlight legend:Required by GoogleRecommendedOptional
schema.org/Occupation
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Occupation",
  "name": "Structured Data Engineer",
  "description": "Designs, implements, and maintains schema.org structured data across web properties. Works with SEO, engineering, and product teams to maximize search visibility through JSON-LD markup, rich result eligibility, and knowledge graph optimization.",
  "occupationalCategory": "15-1252.00",
  "estimatedSalary": {
    "@type": "MonetaryAmountDistribution",
    "name": "Estimated salary for Structured Data Engineer in Pennsylvania",
    "currency": "USD",
    "duration": "P1Y",
    "median": "95000",
    "percentile10": "72000",
    "percentile25": "82000",
    "percentile75": "115000",
    "percentile90": "140000"
  },
  "occupationLocation": {
    "@type": "AdministrativeArea",
    "name": "Pennsylvania, US"
  },
  "skills": [
    "JSON-LD structured data",
    "Schema.org vocabulary",
    "Google Search Console",
    "Technical SEO",
    "JavaScript/TypeScript"
  ],
  "qualifications": {
    "@type": "Credential",
    "name": "Certified Schema Implementer (CSI)",
    "@id": "https://xoocode.com/credentials/certified-schema-implementer#credential"
  },
  "educationRequirements": "Bachelor's degree in Computer Science, Information Science, or related field",
  "experienceRequirements": "2+ years implementing structured data on production websites",
  "responsibilities": "Audit existing markup, implement JSON-LD for new page types, monitor rich result eligibility, maintain validator rules, train content teams on schema.org usage"
}
</script>

estimatedSalary

estimatedSalary takes a MonetaryAmountDistribution (preferred) or MonetaryAmount. MonetaryAmountDistribution lets you express a range with percentiles: median, percentile10, percentile25, percentile75, percentile90. Google displays this as a salary range card in search results. Include currency and duration (P1Y for annual, P1M for monthly).

occupationalCategory

occupationalCategory takes a standardized job classification code. In the US, use BLS O*NET-SOC codes (e.g. "15-1299.08" for Computer Science Teachers). In Europe, use ISCO-08 codes. Google uses these to match the occupation to its salary and employment data. Plain text ("Software Engineer") works but is less precise.

occupationLocation

occupationLocation is an AdministrativeArea defining where the salary and requirements data applies. Salary data for "Software Engineer" differs between San Francisco and Dunmore, PA. Always scope the data geographically. Google shows the location alongside the salary estimate.

Occupation vs JobPosting

JobPosting is a specific open position with an employer, application URL, and closing date. Occupation is the profession. A career advice site describing "What does a pediatrician earn?" uses Occupation. A hospital hiring a pediatrician uses JobPosting. Both can coexist on the same site, linked via relevantOccupation.

Minimal valid version

The smallest markup that still produces a valid Occupation entity. Use it as the floor. Reach for the advanced example above when you want search engines and AI agents to understand more about your content.

schema.org/Occupation (minimal)
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Occupation",
  "name": "Structured Data Engineer",
  "estimatedSalary": {
    "@type": "MonetaryAmountDistribution",
    "currency": "USD",
    "duration": "P1Y",
    "median": "95000"
  },
  "occupationLocation": { "@type": "AdministrativeArea", "name": "Pennsylvania, US" },
  "description": "Implements schema.org structured data for search visibility."
}
</script>

Google rich results this unlocks

Markup matching this example makes your page eligible for the following Google Search rich results. The primary target drives the required / recommended property classification in the advanced code block above.

Common Occupation mistakes

Mistakes that pass validation but silently fail to earn rich results or mislead consumers walking the graph. Avoid these and your markup will be ahead of most sites in the wild.

  1. 01

    Using Occupation for a job listing

    Wrong
    "@type": "Occupation" for a specific open position at your company
    Right
    "@type": "JobPosting" for listings; Occupation for career information

    Occupation describes a profession in general (salary ranges, typical skills, education). JobPosting advertises a specific open position. Google shows different rich results for each: salary estimate cards for Occupation, job listing snippets for JobPosting.

  2. 02

    estimatedSalary without occupationLocation

    Wrong
    Occupation with salary data but no geographic scope
    Right
    "occupationLocation": { "@type": "AdministrativeArea", "name": "Pennsylvania, US" }

    Salary varies dramatically by location. Without occupationLocation, Google does not know where the salary data applies. A $95K median in Pennsylvania means something different than in San Francisco. Google requires location to show the salary card.

  3. 03

    estimatedSalary as a single number

    Wrong
    "estimatedSalary": "95000"
    Right
    "estimatedSalary": { "@type": "MonetaryAmountDistribution", "currency": "USD", "duration": "P1Y", "median": "95000" }

    estimatedSalary should be a MonetaryAmountDistribution with currency, duration (P1Y for annual), and ideally percentiles. A plain number has no currency, no time period, and no range context.

About the example data

A "Structured Data Engineer" occupation profile, the kind of role that Xoo Code Inc. hires for. The salary data is scoped to Pennsylvania. The qualifications references the Certified Schema Implementer credential.

Comments

Loading comments...

Leave a comment