JobPosting Schema for AI Search
schema.org/JobPosting is the canonical JSON-LD type for an open role. Unlike most other schema types, JobPosting markup is the only path into Google for Jobs — a separate vertical search experience that bypasses the standard SERP. AI engines (ChatGPT, Perplexity, Google AI Overviews) reuse the same vocabulary to answer hiring queries ("remote senior platform engineer jobs", "data scientist roles in Boston paying over $200k"). Google requires title, description, datePosted, hiringOrganization, and jobLocation (or jobLocationType: TELECOMMUTE for remote-only). Salary, validThrough, and directApply are strongly recommended.
TL;DR
Mark up each individual job-posting page with JSON-LD @type: JobPosting. Required: title, description (HTML allowed), datePosted, hiringOrganization, jobLocation (or jobLocationType: TELECOMMUTE for remote-only). Strongly recommended: validThrough, baseSalary (MonetaryAmount with QuantitativeValue), employmentType, directApply, applicantLocationRequirements, identifier. Validate with Google Rich Results Test. AI engines reuse the same vocabulary, so a Google-for-Jobs-eligible posting is automatically AI-citation-eligible.
Definition
JobPosting is a Schema.org type for "a listing that describes a job opening in a certain organization." Each posting is one document; do not combine multiple roles into a single JobPosting block. Markup belongs on the individual job detail page, never on category, search, or listing-index pages.
Google for Jobs is unique among Google rich results in that it powers a dedicated job-search vertical (the "three-pack" of jobs that appears at the top of hiring queries). The vertical pulls from JobPosting markup, sitemaps, and (for participating partners) the Indexing API. Without correct JobPosting markup, a posting cannot appear in Google for Jobs at all.
Why JobPosting schema matters for AI search
Three reasons:
- Single-vertical gating. Google for Jobs is the only path to the jobs three-pack. There is no fallback ranking; you are either in the schema-eligible set or invisible.
- AI hiring queries are growing. Job seekers increasingly ask AI engines "what senior backend roles are open in Boston paying over $180k?" rather than typing keywords into Indeed. AI engines reuse JobPosting structured data to answer.
- Salary transparency unlocks specific queries. A 2023 DirectlyApply analysis found 44% of US job postings included salary information, with state-by-state variance from 30% (Louisiana) to 75% (South Dakota). Postings with baseSalary are eligible for salary-filtered AI answers; postings without it are excluded from those queries.
Required and recommended properties
Google's required and recommended property set for the Job posting rich result:
| Property | Type | Status | Description |
|---|---|---|---|
| title | Text | Required | Job title only ("Senior Platform Engineer"). Do NOT include location, salary, or company — those have their own properties. |
| description | Text (HTML) | Required | Full job description. HTML allowed; include responsibilities, qualifications, benefits. |
| datePosted | Date | Required | ISO-8601 publication date. |
| hiringOrganization | Organization | Required | Hiring company. Use @id reference to your canonical Organization entity. |
| jobLocation | Place | Required (effective) | Physical location. Use PostalAddress. Required unless the role is remote-only with jobLocationType: TELECOMMUTE. |
| jobLocationType | Text | Conditionally Required | Set to TELECOMMUTE for fully remote roles (in lieu of jobLocation). |
| applicantLocationRequirements | AdministrativeArea | Required for remote | Where applicants can apply from (countries/regions). Required when jobLocationType: TELECOMMUTE is used. |
| validThrough | DateTime | Recommended | Expiration timestamp. Postings with no validThrough are deindexed faster. |
| baseSalary | MonetaryAmount | Recommended | Salary or salary range as MonetaryAmount with QuantitativeValue. |
| employmentType | Text | Recommended | FULL_TIME, PART_TIME, CONTRACTOR, TEMPORARY, INTERN, VOLUNTEER, PER_DIEM, OTHER. Array allowed. |
| directApply | Boolean | Recommended | true if the URL allows direct application without a third-party redirect. Influences Google for Jobs ranking. |
| identifier | PropertyValue | Recommended | Internal posting ID (name + value). Helps AI engines deduplicate. |
| qualifications | Text | Recommended | Required qualifications and skills. |
| responsibilities | Text | Recommended | Day-to-day duties. |
| educationRequirements | Text or EducationalOccupationalCredential | Recommended | Minimum degree level. |
| experienceRequirements | Text or OccupationalExperienceRequirements | Recommended | Years of experience. |
| industry | Text | Optional | Industry name or NAICS code. |
| occupationalCategory | Text | Optional | ONET-SOC code preferred. |
| workHours | Text | Optional | E.g., "40 hours/week". |
| jobBenefits | Text | Optional | Benefits summary. |
| salaryCurrency | Text | Optional | ISO 4217 — prefer using MonetaryAmount.currency instead. |
Canonical example: in-office role
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "JobPosting",
"@id": "https://example.com/careers/senior-platform-engineer-boston#jobposting",
"title": "Senior Platform Engineer",
"description": "<p>We are hiring a Senior Platform Engineer to lead our Kubernetes platform team.</p><p><strong>Responsibilities:</strong> Design and operate multi-region Kubernetes clusters; mentor 3 mid-level engineers; own SLOs.</p><p><strong>Qualifications:</strong> 6+ years operating production Kubernetes; strong Go or Rust; on-call experience.</p>",
"datePosted": "2026-05-01",
"validThrough": "2026-06-30T23:59:59-04:00",
"employmentType": "FULL_TIME",
"hiringOrganization": {
"@type": "Organization",
"@id": "https://example.com/#organization",
"name": "Example Inc.",
"sameAs": "https://example.com",
"logo": "https://example.com/logo.png"
},
"jobLocation": {
"@type": "Place",
"address": {
"@type": "PostalAddress",
"streetAddress": "100 Innovation Way",
"addressLocality": "Boston",
"addressRegion": "MA",
"postalCode": "02110",
"addressCountry": "US"
}
},
"baseSalary": {
"@type": "MonetaryAmount",
"currency": "USD",
"value": {
"@type": "QuantitativeValue",
"minValue": 180000,
"maxValue": 220000,
"unitText": "YEAR"
}
},
"directApply": true,
"identifier": {
"@type": "PropertyValue",
"name": "Example Inc.",
"value": "req-2026-0185"
}
}
</script>Canonical example: fully remote role
For fully remote work, omit physical jobLocation, set jobLocationType: "TELECOMMUTE", and provide applicantLocationRequirements (the geographic regions where applicants are eligible).
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "JobPosting",
"title": "Staff Software Engineer (Remote)",
"description": "<p>Fully remote staff engineer role on the Search team. Open to candidates in the US and Canada.</p>",
"datePosted": "2026-05-03",
"validThrough": "2026-07-15T23:59:59Z",
"employmentType": "FULL_TIME",
"jobLocationType": "TELECOMMUTE",
"applicantLocationRequirements": [
{
"@type": "Country",
"name": "USA"
},
{
"@type": "Country",
"name": "Canada"
}
],
"hiringOrganization": {
"@type": "Organization",
"@id": "https://example.com/#organization"
},
"baseSalary": {
"@type": "MonetaryAmount",
"currency": "USD",
"value": {
"@type": "QuantitativeValue",
"minValue": 220000,
"maxValue": 280000,
"unitText": "YEAR"
}
},
"directApply": true
}
</script>Canonical example: hybrid role
For hybrid roles where applicants must be reachable from a specific city but work partly remote, use jobLocation (the office) and add applicantLocationRequirements for the broader region. Do NOT use jobLocationType: TELECOMMUTE for hybrid — it triggers the work-from-home filter incorrectly.
{
"@type": "JobPosting",
"title": "Senior Designer (Hybrid — Boston)",
"datePosted": "2026-05-03",
"jobLocation": {
"@type": "Place",
"address": {
"@type": "PostalAddress",
"streetAddress": "100 Innovation Way",
"addressLocality": "Boston",
"addressRegion": "MA",
"addressCountry": "US"
}
},
"applicantLocationRequirements": {
"@type": "State",
"name": "Massachusetts"
}
}baseSalary patterns
Hourly rate
"baseSalary": {
"@type": "MonetaryAmount",
"currency": "USD",
"value": {
"@type": "QuantitativeValue",
"value": 40.00,
"unitText": "HOUR"
}
}Annual range
"baseSalary": {
"@type": "MonetaryAmount",
"currency": "USD",
"value": {
"@type": "QuantitativeValue",
"minValue": 80000,
"maxValue": 120000,
"unitText": "YEAR"
}
}unitText accepts (case-sensitive): HOUR, DAY, WEEK, MONTH, YEAR. Only the employer can provide baseSalary; third parties (job aggregators) must use estimatedSalary instead.
directApply flag
Set directApply: true if the page URL leads to a single-step application form on your domain (no aggregator redirects, no "apply on Indeed" handoffs). Google's stricter 2025 quality bar uses this flag as a positive ranking signal in Google for Jobs. Postings with multi-step third-party redirects should set directApply: false.
validThrough and stale postings
Google deindexes JobPosting markup that lacks validThrough more aggressively than time-bounded postings. When a role is filled or closed:
- Update validThrough to the close date — do not delete schema.
- Return HTTP 410 Gone or 404 on the URL once the posting is fully closed (not 301-redirected).
- Remove from sitemaps within 24 hours of closing.
Leaving expired postings live ("ghost jobs") triggers quality penalties under Google's 2025 standards and reduces AI citation quality across your entire careers site.
Validation pipeline
- Schema.org Validator — syntax check.
- Google Rich Results Test — confirms eligibility for the Job posting rich result.
- Google Search Console > Enhancements > Job postings — surfaces deployment-time errors.
- Indexing API (recommended for high-volume employers) — push new postings to Google within minutes instead of waiting for crawl.
- AI smoke test — query Perplexity, ChatGPT, and Google AI Overviews for representative hiring queries ("[role] in [city] paying over $X"). Track whether your postings are cited.
Common mistakes
- JobPosting markup on category/search pages. Markup must be on individual job detail pages only.
- Missing description. Required. AI engines and Google extract responsibilities and qualifications from this field.
- Salary as a plain number instead of MonetaryAmount. Always use the nested MonetaryAmount + QuantitativeValue structure.
- Stale postings without validThrough. Triggers quality penalties. Always set validThrough.
- jobLocationType: TELECOMMUTE for hybrid roles. Use only for fully remote. Hybrid roles should use jobLocation plus applicantLocationRequirements.
- Missing applicantLocationRequirements on remote roles. Causes the role to be excluded from work-from-home filters.
- Inconsistent hiringOrganization blocks across postings. Use @id reference to a canonical Organization entity.
- Title field including location/salary. Only the role name belongs in title.
- Multiple postings sharing one URL.* Each role needs its own canonical URL.
How to apply
- For each open role, ensure a unique, individual job detail page.
- Draft JSON-LD with the five required properties (title, description, datePosted, hiringOrganization, jobLocation or jobLocationType).
- Add validThrough, baseSalary (MonetaryAmount), employmentType, directApply, identifier, and (for remote) applicantLocationRequirements.
- Validate with Google Rich Results Test.
- Deploy in . Submit sitemap.
- For high-volume employers, integrate the Indexing API.
- Monitor Search Console Enhancements > Job postings; fix errors within 24 hours.
- When a role closes, update validThrough and return 410/404 on the URL within 24 hours.
FAQ
Q: What are the required properties for JobPosting?
title, description, datePosted, hiringOrganization, and jobLocation (or jobLocationType: TELECOMMUTE for fully remote). Without all five, the posting will not appear in Google for Jobs.
Q: How do I mark up a fully remote role?
Omit jobLocation, set jobLocationType to "TELECOMMUTE", and provide applicantLocationRequirements listing the eligible countries or states.
Q: How do I mark up a hybrid role?
Use jobLocation (the office address) and add applicantLocationRequirements for the broader region. Do not use TELECOMMUTE; that signals fully remote.
Q: Should baseSalary be a single value or a range?
A range is preferred for AI citations and salary-filter queries. Use minValue and maxValue inside QuantitativeValue. Single value is acceptable for fixed hourly rates.
Q: Can third-party job aggregators provide baseSalary?
No. Only the employer should provide baseSalary. Aggregators must use estimatedSalary to avoid misrepresenting employer-confirmed numbers.
Q: What happens when a role closes?
Update validThrough to the close date, return HTTP 410 (preferred) or 404 on the URL, and remove from sitemaps. Do not 301-redirect to a different job; that confuses indexers.
Q: Does directApply affect Google for Jobs ranking?
Yes. Google's 2025 quality changes use directApply: true as a positive signal because single-step applications produce higher conversion and lower abandonment than multi-step redirect flows.
: Schema.org, "JobPosting" type — verified 2026-05-03 — supports canonical type definition. https://schema.org/JobPosting
: Google Search Central, "Job posting (JobPosting) structured data for Job Search" — verified 2026-05-03 — supports required-property list, MonetaryAmount unitText values, TELECOMMUTE pattern. https://developers.google.com/search/docs/appearance/structured-data/job-posting
: Cavuno, "Job Posting Schema: How to Get Your Jobs on Google for Jobs" — verified 2026-05-03 — supports five-step deployment process and Google for Jobs gating. https://cavuno.com/blog/job-posting-schema
: Kardow, "Job Posting Schema for Google for Jobs (2026)" — verified 2026-05-03 — supports category-page warning and validThrough deindexing behavior. https://kardow.com/articles/job-posting-schema-google-for-jobs
: Dstribute.io, "Google Jobs Shake-Up 2025: Navigating the New Indexing API Restrictions" — verified 2026-05-03 — supports 2025 quality standard changes and ghost-job penalties. https://dstribute.io/job-boards/google-jobs-shake-up-2025-navigating-the-new-indexing-api-restrictions/
: DirectlyApply, "44% of US job postings have salary information" — verified 2026-05-03 — supports salary-transparency statistic. https://directlyapply.com/blog/an-update-on-salary-transparency-in-job-posts-november-2023
: Happydance, "How to make your careers site visible to AI: GEO vs SEO in 2026" — verified 2026-05-03 — supports schema-as-shared-vocabulary argument for AI engines. https://www.happydance.love/insights/posts/how-to-make-your-careers-site-visible-to-ai-geo-vs-seo-in-2026/
: WitsCode, "AI Search for Recruitment: Job Posting Optimization" — verified 2026-05-03 — supports growth of AI hiring queries. https://witscode.com/blogs/ai-search-recruitment-job-posting-optimization-ai/
Related Articles
Event Schema for AI Search
Schema.org Event JSON-LD spec for AI search: required name/startDate/location, virtual and hybrid events, eventStatus, performer linkage, and AI citation patterns.
LocalBusiness Schema for AI Citations
LocalBusiness JSON-LD spec for AI citations: required NAP fields, openingHoursSpecification, geo, sub-types, sameAs, and AI local-intent citation patterns.
Service Schema for AI Search
Schema.org Service spec for AI search citations: required JSON-LD properties, areaServed, provider, serviceType, hoursAvailable, and entity-linking patterns.