JobPosting Schema
How to implement JobPosting structured data to appear in Google for Jobs — the five required properties, the recommended fields that actually drive clicks, remote-job markup, the content policies that get postings disapproved, and how to remove expired jobs correctly.
1 evidence signal on this page
- Related live toolRich-Result Eligibility Checker
JobPosting schema is the schema.org/JSON-LD markup you put on a single job-listing page to become eligible for Google for Jobs. Five properties are required — title, description, datePosted, hiringOrganization, and jobLocation (with a fully-remote exception) — and the recommended ones (validThrough, employmentType, baseSalary) are where the click-through and filtering value lives. Content-schema parity is non-negotiable: everything in the JSON-LD must be visible on the page. The most common disapproval cause is putting the markup on a listing page instead of one job per page. Expired-job hygiene is an ongoing obligation, not a one-time setup — leave dead jobs live and you risk a manual action. And Google's Indexing API is scoped to JobPosting and BroadcastEvent only; misusing it as a general 'index faster' button can cost you access. Bing supports the same vocabulary but documents it far more lightly — lean Google.
TL;DR — JobPosting schemaJobPosting schema is the schema.org/JSON-LD vocabulary you add to a single job-listing page so Google (and Bing) can read the role, employer, location, salary, and dates — making the page eligible for Google for Jobs. It requires title, description, datePosted, hiringOrganization, and jobLocation (or applicantLocationRequirements for fully remote roles). is code you add to a job-listing page that labels the role — “this is the job title,” “this is the employer,” “this is the salary,” “this is where it’s based” — so Google can put it in Google for Jobs, the job-search box you see at the top of results. You need five details at minimum: the job title, a description, the date you posted it, the employer’s name, and the location. Put it on a page with one job per page — never a page that lists lots of jobs at once.
What JobPosting schema is
When you post a job on your careers page, a person can read the title, the company, the pay, and where it’s based. A search engine sees plain text and has to guess. JobPosting schema spells it out in code, using the shared vocabulary from schema.org, so Google can understand the listing and show it in Google for Jobs — the little job-search widget with company logos that appears at the top of results for searches like “marketing jobs near me.”
Evidence for this claim Schema.org JobPosting describes a job vacancy and properties such as title, datePosted, hiringOrganization, and jobLocation. Scope: Schema.org vocabulary; Google applies additional job-search requirements. Confidence: high · Verified: Schema.org: JobPostingIt’s written in a small block of code called JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. that sits in the page without changing how the page looks.
What Google needs at minimum
To be eligible for Google for Jobs, five things are required:
- title — the job’s title, like “Barista” or “Software Engineer” (not the title of the web page).
- description — the full job description.
- datePosted — the date you posted the job.
- hiringOrganization — the company’s real name.
- jobLocation — where the person will actually work.
There’s one exception to the location rule: if the job is 100% remote, you flag it as remote instead of giving an office address (more on that in Advanced).
Evidence for this claim Google requires JobPosting markup on a single job detail page with required job and organization information. Scope: Google Search JobPosting requirements; listing pages and incomplete postings are not eligible. Confidence: high · Verified: Google: JobPosting structured dataThe details that get you clicked
The five required fields get you in. A few optional ones get you noticed, because Google for Jobs lets people filter by them:
- salary — showing pay makes your listing stand out (and salary-disclosure laws are spreading, so check whether your jurisdiction requires it).
- employment type — full-time, part-time, contract, and so on.
- an expiry date — so Google knows when the job closes.
The thing most people get wrong
One job per page. You can’t put JobPosting markup on a page that lists all your open roles at once — Google only allows it on a page for a single job. This is the number-one reason listings get rejected.
And when a job is filled, take it down or mark it closed. Leaving expired jobs live is against Google’s rules — Google says it may take manual action and pull the posting from the Google for Jobs experience, which is scoped to your job listings, not a blanket penalty on the rest of your site’s search rankings. Setting a fake future expiry date to keep a filled job “alive” doesn’t work — the page has to reflect reality.
Want the full version — the exact required and recommended properties, how to mark up remote and hybrid roles, the content policies that get postings disapproved, how to remove expired jobs the right way, and how Bing differs? Switch to the Advanced tab.
TL;DR — JobPosting schemaJobPosting schema is the schema.org/JSON-LD vocabulary you add to a single job-listing page so Google (and Bing) can read the role, employer, location, salary, and dates — making the page eligible for Google for Jobs. It requires title, description, datePosted, hiringOrganization, and jobLocation (or applicantLocationRequirements for fully remote roles). (
schema.org/JobPosting, in JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal.) makes a single-job page eligible for Google for Jobs. Google requires five properties —title,description,datePosted,hiringOrganization,jobLocation— withapplicantLocationRequirements/jobLocationType: TELECOMMUTEsubstituting for location on fully remote roles. The recommended set (validThrough,employmentType,baseSalary,identifier,directApply) is where the CTR and filtering value lives. Two hard rules: one job per page, and content-schema parity (every JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. value must be visible on the page). Expired-job hygiene is an ongoing compliance task with three sanctioned removal methods; leaving expired jobs live risks a manual action. Google’s Indexing APIThe Google Indexing API lets site owners notify Google directly when a URL is added, updated, or removed. Google officially supports it only for pages with JobPosting or BroadcastEvent (livestream) structured data — not for general content. is scoped to JobPosting and BroadcastEvent only and is now approval-gated — don’t treat it as a general “indexStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. faster” button. Bing supports the same vocabulary but documents it far more thinly; lean Google.
My general stance on schema hasn’t changed for job listings: I’m a fan of markup as long as it earns you a search feature. JobPosting clears that bar cleanly — it’s the gate to Google for Jobs, a genuine SERP surface — so it’s worth doing, and worth doing precisely. The precision is the whole game here, because job listings are one of the more heavily policed structured-data types Google runs.
The five required properties
Google’s job-posting structured-data documentation lists five required properties. Miss any one and the page isn’t eligible:
title— “The title of the job (not the title of the posting). For example, ‘Software Engineer’ or ‘Barista’.” (jump to quote) This trips people up constantly — the value is the role, not your page’s<h1>or SEO titleThe title tag is the HTML title element in a page's head that specifies the document's title. It's the primary source for the SERP title link and a confirmed light ranking factor — but since August 2021 Google doesn't always show it verbatim..description— the full HTML job description. It must not just repeat the title; Google wants the real, complete description.datePosted— the original date the employer posted the job, in ISO 8601 (e.g.,2017-01-24).hiringOrganization— “The organization offering the job position. This must be the name of the company (for example, ‘Starbucks, Inc’).” (jump to quote) For a job board this must be the real employer, not the board.jobLocation— the physical worksite where the employee will report, not the place the job was posted. Not required if you supplyapplicantLocationRequirementsfor a remote role.
A minimal, valid example:
{
"@context": "https://schema.org/",
"@type": "JobPosting",
"title": "Software Engineer",
"description": "<p>Full job description in HTML…</p>",
"datePosted": "2026-06-27",
"hiringOrganization": {
"@type": "Organization",
"name": "Example Co",
"sameAs": "https://www.example.com"
},
"jobLocation": {
"@type": "Place",
"address": {
"@type": "PostalAddress",
"addressLocality": "Raleigh",
"addressRegion": "NC",
"addressCountry": "US"
}
}
} The recommended properties that actually move the needle
Eligibility comes from the required five, but the CTR and filtering value comes almost entirely from the recommended set — these are the fields Google for Jobs lets searchers filter on:
validThrough— the date the posting expires, in ISO 8601. There’s a nuance worth stating plainly: omit it entirely if the job never expires, but if the job does have an end date, include it and keep it accurate. Leaving a stalevalidThroughin place is a compliance problem, not a harmless default.employmentType—FULL_TIME,PART_TIME,CONTRACTOR,TEMPORARY,INTERN,VOLUNTEER,PER_DIEM, orOTHER(an array is allowed).baseSalary(aMonetaryAmount) — the actual base salary provided by the employer, not an estimate; only the employer may supply it. UseunitTextofHOUR/DAY/WEEK/MONTH/YEAR, andminValue/maxValuefor a range. With pay-transparency laws spreading, this is increasingly not optional in practice.identifier(aPropertyValue) — the employer’s unique job/req ID; matters for de-duplication, especially on aggregators.directApply— indicates whether the posting’s URL lets someone apply directly on that site rather than redirecting elsewhere.
Beta properties
Google requested a set of additional properties back in 2021 that are still flagged
beta: educationRequirements.credentialCategory,
experienceRequirements.monthsOfExperience, and experienceInPlaceOfEducation.
These grew out of Google’s Career Certificate push during the pandemic-era job
market. Google’s own framing at launch was that because it was still developing how
it uses the information, you might not see any appearance or effect in Google Search
right away.
My take: add them if they’re cheap to populate from your ATS, but don’t hold up a launch for them — they’re future-proofing, not eligibility.
Remote and hybrid jobs: TELECOMMUTE done right
Remote markup has three distinct patterns, and getting it wrong is a classic content-mismatch flag.
Fully remote. Set jobLocationType to TELECOMMUTE, for jobs in which the
employee may or must work remotely 100% of the time. Google requires every
TELECOMMUTE posting to specify at least one eligible country — via
applicantLocationRequirements (Google’s preferred method) or, failing that, a
default taken from jobLocation. There’s no valid scenario where a remote job
carries zero location information: “unrestricted” in practice means listing every
country you’ll accept applicants from, not omitting the field. The on-page
description must clearly say the role is fully remote too — content-schema parity
applies here as much as anywhere.
{
"@type": "JobPosting",
"jobLocationType": "TELECOMMUTE",
"applicantLocationRequirements": {
"@type": "Country",
"name": "USA"
}
}That example is a US-only remote role. For “remote within the EU” or any
multi-country role, repeat applicantLocationRequirements for each eligible
country — the property name is the same whether you’re naming one country or ten.
Hybrid. A hybrid role is not fully remote. Give it a real office jobLocation,
and only add the TELECOMMUTE flag if the role genuinely qualifies as remote —
Google’s own hybrid example pairs a physical jobLocation with jobLocationType
(plus applicantLocationRequirements when the remote option is itself
geography-restricted). The mistake to avoid: marking an occasional-work-from-home
role as TELECOMMUTE. That’s a content mismatch waiting to happen — TELECOMMUTE
is for 100%-remote work, and the page has to back that up. When in doubt, the
Decision Trees tab has a “should this use TELECOMMUTE?” walkthrough.
Google for Jobs eligibility and regional availability
One surprise for international teams: Google for Jobs isn’t global. It’s live in 50+ countries across North America, Latin America, Europe, the Middle East and North Africa, Sub-Saharan Africa, and Asia — but not everywhere. If your listings are technically perfect and still not showing, check that the experience is available in your target country before you spend a day debugging your JSON-LD.
Content policies that get postings disapproved
Google’s job-posting content policies are stricter than most structured-data rules, and they’re worth knowing by their real names because Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. will cite them. From Google’s documentation:
- Single-job pages only. “The JobPosting markup must only be used on pages that contain a single job posting.” (jump to quote) This is the single most common real-world disapproval — no markup on listing/search-results pages.
- Irrelevant content — the posting’s content must be relevant to the job.
- Incomplete content — Google doesn’t allow job postings with incomplete job descriptions.
- Misrepresentation — no fake jobs, keyword stuffing, false location data, impersonation, or posting someone else’s listing without authorization.
- Profanity — no obscene, profane, or offensive language.
- Disguised ads / promotional content — no affiliate-program listings or other promotional content dressed up as a job.
- Expired postings — Google doesn’t allow expired job postings. “Ideally you should remove expired job postings from your website.” (jump to quote)
- Jobs without a way to apply — every posting needs a way to apply (career-fair invites and login-gated postings are exempted).
- Resume collection — only for open, actively-hiring positions.
- Job requests — the markup is for actual openings, not solicitations from people seeking work.
- Payment required — never require an applicant to pay.
- Editorial content — proper grammar and capitalization; no all-caps spam.
The through-line: content-schema parity is non-negotiable. Every value in the JSON-LD — salary, remote status, employment type — must be visibly present in the human-readable page, or Google can treat the mismatch as misrepresentation.
Handling expiration and removal correctly
This is the part teams under-build. Expired-job hygiene is an ongoing obligation, not a one-time setup task — you need a process (a cron job, an ATS integration, or an IndexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. API call) to pull a role the moment it closes. Google sanctions three removal methods:
- Set
validThroughto a date in the past and leave the page up briefly. - Remove the page entirely and return a
404or410. - Strip the JobPosting markup from the page.
The risk if you don’t: leaving expired postings live violates the content policies,
and Google says the response may include manual action that removes the job
posting(s) from the job search experience on Google — that’s scoped to your job
listings’ eligibility for the Jobs feature, not an automatic penalty against the rest
of your site’s organic rankings. Evidence for this claim Google requires expired job postings to be removed or marked with a past validThrough value and no longer exposed as active jobs. Scope: Google Search JobPosting expiration policy; stale postings can trigger manual actions. Confidence: high · Verified: Google: JobPosting structured data Setting a future
validThrough on a job that’s actually filled does not keep it “safe” — the page
must reflect reality.
For faster removal and updates on job URLs specifically, Google recommends its Indexing API over waiting for a normal re-crawl or a sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. ping — see the next section for the scope and access caveats.
Duplicate and syndicated postings
A very common real-world case: the same req posted to your careers page and three job boards. This is fine. John Mueller has said that having the same job posted on different websites is very common and expected, and that hosting the same listing at different times or on different subdomains should be fine too — Google de-duplicates identical listings rather than penalizing them, and he’s indicated the same applies to Google for Jobs.
Mueller’s remarks above are paraphrased from a February 2022 Google Hangout as recapped by iloveseo.com; I’m summarizing rather than quoting because I sourced it through that secondary recap. What still applies regardless:hiringOrganization
must be the real employer, and no misrepresentation.The Indexing API is scoped — and now gated
Google’s Indexing API is not a general “get indexed faster” tool. Per Google’s
Indexing API quickstart, it can only be used to crawl pages with either JobPosting
or BroadcastEvent embedded in a VideoObject — job postings are one of only two
legitimate use cases. Submitting a URL is a notification, not a guarantee: it
doesn’t guarantee that Google will crawl, index, include, rank, or display the page
on any particular timeline.
Two things have changed the landscape here:
- Access is now approval-gated. The default per-day quota is modest, and getting meaningful volume now requires filling out a Google approval form rather than being auto-enabled. Cite Google’s own Requesting Approval and Quota page as the primary source for this.
- Google is visibly protecting the lane from spam. Google reps have repeatedly warned against misusing the Indexing API to push arbitrary, unsupported page types — the recommendation is to stick to the documented, supported use cases. Because JobPosting is one of only two of those, this matters directly: abuse the API for non-job content and you risk losing access to a channel your job listings actually depend on.
Troubleshooting in Search Console
When a listing doesn’t show, work it in order — the Playbooks tab lays this out as a linear runbook, but the short version:
- Validate the markup with the Rich ResultsRich results (formerly 'rich snippets') are enhanced search listings — stars, images, prices, breadcrumbs, video thumbnails, and more — that Google and Bing build from structured data. They're a display feature, not a ranking factor, and eligibility never guarantees they'll show. Test and confirm all five required properties parse without error.
- Confirm one job per page — the most common disapproval is JobPosting markup on a listing/index page.
- Check content-schema parity — every JSON-LD value (salary, remote status, employment type) must be visible on the page.
- Check
validThroughand expiry — an expired posting still carrying live markup gets disapproved. - Confirm regional availability — Google for Jobs isn’t available everywhere.
- Check Search ConsoleGoogle's free tool for monitoring crawling, indexing, and search performance.’s rich-result report for the specific disapproval reason and fix against that named policy.
Bing and JobPosting
Bing supports structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding. broadly — JSON-LD, Microdata, RDFa — and provides a
Schema MarkupSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor. Validator, and it lists JobPosting among supported types for
careers-page and job-board markup. But Bing does not publish a JobPosting-specific
eligibility spec anywhere near as detailed as Google’s, and its job-search surface has
far lower documented rigor. The honest summary: Bing uses the same schema.orgSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor.
vocabulary and the same single-job-per-page principle, with much lighter validation
and much thinner documentation. Don’t assume Bing/Google parity here — mark up for
Google’s stricter spec and Bing is covered by default.
Where this sits
JobPosting is one type in the broader structured data hub this article lives under, alongside the commerce-focused Product schemaProduct schema (schema.org/Product) is structured data that tells search engines a page's product name, price, availability, and reviews so it can appear in Shopping-style rich results. It's separate from a Google Merchant Center feed, though Google reconciles the two. and ProductGroup schemaProductGroup schema is structured data that groups product variants — like a shirt's sizes and colors — under one parent so Google understands they're options of the same item, not separate products. It wraps individual Product markup via hasVariant/variesBy/productGroupID; it doesn't replace it. markup and the wider Commerce schema\"Commerce schema\" is a practitioner label — not an official Google or schema.org category — for the schema.org listing types that power transactional rich results: Product, ProductGroup, and JobPosting. family. If you’re implementing across a site, treat them the same way: use the type that maps to a confirmed search feature, keep the JSON-LD in parity with visible page content, and validate before you ship.
AI summary
A condensed take on the Advanced version:
- What it is: JobPosting schemaJobPosting schema is the schema.org/JSON-LD vocabulary you add to a single job-listing page so Google (and Bing) can read the role, employer, location, salary, and dates — making the page eligible for Google for Jobs. It requires title, description, datePosted, hiringOrganization, and jobLocation (or applicantLocationRequirements for fully remote roles). (
schema.org/JobPosting, JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal.) on a single-job page makes it eligible for Google for Jobs, the job-search rich result. - Required (5):
title(the role, not the page titleThe title tag is the HTML title element in a page's head that specifies the document's title. It's the primary source for the SERP title link and a confirmed light ranking factor — but since August 2021 Google doesn't always show it verbatim.),description(full HTML, not a repeat of the title),datePosted(ISO 8601),hiringOrganization(the real employer),jobLocation(the worksite). Fully remote roles substitutejobLocationType: TELECOMMUTE— but Google requires naming at least one eligible country viaapplicantLocationRequirements(preferred) or ajobLocationdefault for everyTELECOMMUTEposting, restricted or not. - Recommended (CTR/filter value):
validThrough(omit if never expires; keep accurate if it does),employmentType,baseSalary(employer-supplied, not estimated),identifier(dedup),directApply. - Beta:
educationRequirements,experienceRequirements,experienceInPlaceOfEducation— 2021 Career-Certificate-era additions; nice to have, not eligibility. - Remote patterns:
TELECOMMUTEalways needs at least one eligible country (one for a restricted role, a list for a broader one) viaapplicantLocationRequirementsor ajobLocationdefault; hybrid uses a realjobLocationand skipsTELECOMMUTEunless the role is genuinely 100% remote — don’t over-claim it for occasional WFH. - Two hard rules: one job per page; content-schema parity (every JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. value visible on the page).
- Content policies (named): single-job-page, irrelevant content, incomplete content, misrepresentation, profanity, disguised ads, expired postings, jobs without a way to apply, resume collection, job requests, payment required, editorial content.
- Expiration — 3 sanctioned methods: past
validThrough; remove page (404/410); strip the markup. Leaving expired jobs live risks manual action removing the postings from Google for Jobs (scoped to your listings, not the whole site); a fake futurevalidThroughdoesn’t help. - Region: Google for Jobs is in 50+ countries, not global.
- Syndication: same job on multiple sites/boards is fine (Google de-dups, per
Mueller);
hiringOrganizationaccuracy and no-misrepresentation still apply. - Indexing APIThe Google Indexing API lets site owners notify Google directly when a URL is added, updated, or removed. Google officially supports it only for pages with JobPosting or BroadcastEvent (livestream) structured data — not for general content.: scoped to JobPosting + BroadcastEvent-in-VideoObject only, now approval-gated; a submission is a notification, not a guarantee of crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor., indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed., or ranking; misuse risks losing access. Cite Google’s quota-pricing page.
- Bing: same vocabulary, single-job principle; much thinner docs and lighter validation — lean Google.
Official documentation
Primary-source documentation from the search engines.
- Job posting (JobPosting) structured data for Job Search — the required and recommended properties, remote-job handling, and the full content-policy list.
- Requesting Approval and Quota — Indexing API — the approval-form and quota model for Indexing APIThe Google Indexing API lets site owners notify Google directly when a URL is added, updated, or removed. Google officially supports it only for pages with JobPosting or BroadcastEvent (livestream) structured data — not for general content. access.
- Indexing API Quickstart — states the API is only for
JobPostingorBroadcastEventembedded in aVideoObject. - Rich Results Test — validate a JobPosting page’s eligibility and required-property errors.
- Schema Markup Validator — validate the schema.orgSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor. syntax of any type.
- schema.org — JobPosting — the vocabulary reference: every property the type can carry.
Bing / Microsoft
- Bing Webmaster Tools — Marking Up Your Site with Structured Data — Bing’s general structured-data support (JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal., Microdata, RDFa).
- Bing Webmaster Tools — the Schema MarkupSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor. Validator and URL inspectionA Google Search Console feature that reports how Google sees one specific URL on a property you own. By default it shows the last-indexed snapshot; a separate \"Test live URL\" mode fetches the current version..
Quotes from the source
On-the-record statements from Google’s documentation. Each link is a deep link that jumps to the quoted passage on the source page.
Google docs — required properties
- “The title of the job (not the title of the posting). For example, ‘Software Engineer’ or ‘Barista’.” — on
title. Jump to quote - “The organization offering the job position. This must be the name of the company (for example, ‘Starbucks, Inc’).” — on
hiringOrganization. Jump to quote
Google docs — content policies
- “The JobPosting markup must only be used on pages that contain a single job posting.” Jump to quote
- “Ideally you should remove expired job postings from your website.” Jump to quote
Paraphrased — sourced secondhand, not quoted verbatim
- On syndication (John Mueller, Feb 2022 Hangout, via iloveseo.com): having the same job posted on different websites is very common and fine, and hosting it at different times or on different subdomains should be fine too; Google de-duplicates identical listings, and the same applies to Google for Jobs. (Paraphrase — confirm against the original before quoting.)
- On the beta properties (Google, via Search Engine Journal, March 2021): because Google was still developing how it uses the education/experience information, you might not see any appearance or effect in Google Search right away. (Paraphrase — confirm against the live docs before quoting.)
- On Indexing APIThe Google Indexing API lets site owners notify Google directly when a URL is added, updated, or removed. Google officially supports it only for pages with JobPosting or BroadcastEvent (livestream) structured data — not for general content. misuse (Google reps, ~2025, via secondary aggregation): the recommendation is to stick to the documented, supported use cases rather than pushing arbitrary page types through the IndexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. API. (Paraphrase — re-fetch the primary source for exact wording, date, and platform before quoting directly.)
Interactive decision aids
Two branching questions that come up constantly with job markup. Click through them.
Should this job use jobLocationType: TELECOMMUTE?
A job just closed — how do I remove it correctly?
Runbook: my job posting got disapproved — what to check, in order
Work these top to bottom. Most disapprovals resolve at step 2 or 3.
-
Reproduce it in the Rich ResultsRich results (formerly 'rich snippets') are enhanced search listings — stars, images, prices, breadcrumbs, video thumbnails, and more — that Google and Bing build from structured data. They're a display feature, not a ranking factor, and eligibility never guarantees they'll show. Test. Paste the live URL (or the rendered HTML) into the Rich Results Test. If required properties are missing or malformed, fix those first — a required-property error alone makes the page ineligible.
-
Confirm it’s one job per page. This is the most common disapproval. JobPosting markup on a listing page, category page, or search-results page is not allowed. The markup must live on a page containing a single job.
-
Check content-schema parity. Read the page as a human. Every value in the JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. — salary, employment type, remote status, location — must be visibly present in the page content. A salary or “remote” flag in the markup that isn’t on the page reads as misrepresentation.
-
Check
validThroughand expiry. If the role is filled or closed, an expired posting still carrying live markup gets disapproved. Apply one of the three removal methods (pastvalidThrough, 404/410, or strip the markup). Don’t set a fake future date. -
Confirm there’s a way to apply. Every posting needs an apply method (career-fair invites and login-gated postings are the documented exceptions). No apply path is a named policy violation.
-
Scan the other named policies. Rule out irrelevant/incomplete content, misrepresentation (fake jobs, false location, keyword stuffing), profanity, disguised ads/affiliate content, resume-collection on non-open roles, job requests, payment-required, and all-caps/editorial issues.
-
Confirm regional availability. Google for Jobs is in 50+ countries but isn’t global. Perfect markup in an unsupported country still won’t surface.
-
Read the exact reason in Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. and fix against it. Open the rich-result report, find the specific disapproval reason string, and remediate against that named policy rather than guessing.
Myths and mistakes
The recurring ways job markup goes wrong — and what’s actually true.
-
Myth: “You must include every property or Google won’t show the job.” False. Only five properties are strictly required. Recommended and beta properties improve richness and filtering, but they don’t gate eligibility.
-
Myth: “Posting the same job on multiple sites/subdomains gets you a duplicate-content penalty.” No. Normal syndication across job boards is expected — Google de-duplicates identical listings rather than penalizing them.
hiringOrganizationaccuracy and no-misrepresentation still apply. -
Myth: “Setting
validThroughin the future keeps a filled listing ‘safe.’” False. Google disallows expired-in-practice postings regardless of whatvalidThroughsays. The page must reflect reality. -
Myth: “JobPosting schemaJobPosting schema is the schema.org/JSON-LD vocabulary you add to a single job-listing page so Google (and Bing) can read the role, employer, location, salary, and dates — making the page eligible for Google for Jobs. It requires title, description, datePosted, hiringOrganization, and jobLocation (or applicantLocationRequirements for fully remote roles). guarantees a ranking or traffic boost.” Overstated. It makes you eligible for the Google for Jobs UI — it’s not a ranking factor for organic web results. Any CTR gains come from the richer, filterable UI, not from an algorithmic ranking preference.
-
Myth: “You can put JobPosting markup on your careers/listing page to cover all open roles at once.” Explicitly banned. One job posting per page, full stop.
-
Myth: “The Indexing APIThe Google Indexing API lets site owners notify Google directly when a URL is added, updated, or removed. Google officially supports it only for pages with JobPosting or BroadcastEvent (livestream) structured data — not for general content. is a general ‘get indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. faster’ tool for any page.” False, and reps have warned against it. It’s scoped to JobPosting and BroadcastEvent-in-VideoObject only, and misuse risks losing access.
-
Myth: “Remote jobs don’t need any location field at all.” False.
jobLocationType: TELECOMMUTEreplaces the need for a specific officejobLocation, but Google still requires at least one eligible country — viaapplicantLocationRequirements(preferred) or a default taken fromjobLocation— on everyTELECOMMUTEposting. There’s no valid case where a remote job carries zero location information. -
Mistake: marking occasional-WFH or hybrid roles as
TELECOMMUTE.TELECOMMUTEis for 100%-remote work. Over-claiming it against a page that describes a hybrid role is a content mismatch that risks disapproval.
SOP: expired-job hygiene
The article is explicit that this isn’t a one-time setup: expired-job hygiene is “an ongoing obligation,” and Google runs three sanctioned removal methods you need a repeatable process for — ideally triggered by a cron job, an ATS integration, or an Indexing APIThe Google Indexing API lets site owners notify Google directly when a URL is added, updated, or removed. Google officially supports it only for pages with JobPosting or BroadcastEvent (livestream) structured data — not for general content. call the moment a role closes, not a manual sweep you remember to do occasionally.
-
Trigger: a role closes or fills in your ATS. Action: within the same business day, apply one of the three sanctioned methods — set
validThroughto a past date (and leave the page up only briefly), remove the page and return a404/410, or strip the JobPosting markup while keeping the page live. Done when: the page no longer carries live, current JobPosting markup for a filled role. -
Never set a future
validThroughon a closed role to “keep it safe.” Action: if a role is filled, the fix is one of the three removal methods above — not a fake future date. Done when:validThrough(if present) reflects reality, not a placeholder. -
Run a scheduled reconciliation sweep (weekly is reasonable for moderate posting volume) cross-checking every live JobPosting page against your ATS’s current status. This catches postings that slipped through step 1 — a page that should have been pulled but wasn’t. Done when: the count of “closed in ATS but still live with markup” pages is zero.
-
For high-volume job boards, use the IndexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. API for the removal event itself (it’s one of only two documented use cases, alongside
BroadcastEvent), rather than waiting on a normal re-crawl. Done when: the removal orvalidThroughupdate is reflected in Google’s processing without a multi-day crawl delayCrawl-delay is a non-standard robots.txt directive that asks bots to wait between successive page fetches to ease server load. Google has ignored it since September 1, 2019 and Yandex dropped it on February 22, 2018; Bing and many other crawlers still honor it, but Bing interprets the value differently than the plain reading.. -
Log which removal method was used and when, per posting. This is cheap insurance: if a manual action review ever happens, you want a record showing expired-job hygiene was a functioning process, not an afterthought.
Prompts: content-schema parity audit
The article’s through-line is that content-schema parity is non-negotiable — every value in the JobPosting JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. (salary, remote status, employment type) has to be visibly present on the page, or Google can treat the mismatch as misrepresentation. These prompts turn that check into something you can paste into a chat model rather than eyeball manually.
Prompt 1 — flag parity mismatches between the page and the markup
Paste in: the job page’s visible, human-readable text (copy the rendered page content) and its JobPosting JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. block, labeled separately.
Here is the visible text of a job posting page, followed by its JobPosting
JSON-LD structured data.
VISIBLE PAGE TEXT:
<paste the rendered, human-readable job description and any salary/location/
remote-work text here>
JSON-LD:
<paste the JobPosting JSON-LD block here>
Compare them field by field for baseSalary, employmentType, jobLocation /
jobLocationType, and validThrough. For each field, tell me:
1. Whether the value in the JSON-LD is stated anywhere in the visible text.
2. If it's missing or contradicted on the page, quote the JSON-LD value and
explain what's missing.
Do not flag a mismatch unless you can point to what's absent or contradictory —
don't guess at intent.Expect back: a short field-by-field table (or list) naming each recommended field and whether the page backs it up, plus the exact JSON-LD value that has no visible counterpart if one exists.
Prompt 2 — check for a TELECOMMUTE / remote-work mismatch
Paste in: the job’s visible description (specifically any language about
remote/hybrid/on-site work) and the jobLocationType / applicantLocationRequirements
values from the JSON-LD.
Here is a job posting's description text describing the work arrangement, and
the jobLocationType / applicantLocationRequirements values from its JobPosting
JSON-LD.
DESCRIPTION TEXT (work-arrangement language only):
<paste the sentence(s) describing remote/hybrid/on-site expectations>
JSON-LD VALUES:
jobLocationType: <value, or "not set">
applicantLocationRequirements: <value, or "not set">
TELECOMMUTE is only correct for roles the employee may or must work 100% remotely.
Based on the description text, does the jobLocationType value match how the role
is actually described? Call out specifically if the text describes a hybrid or
occasional-work-from-home role while the markup claims TELECOMMUTE, or vice versa.Expect back: a plain yes/no on whether the markup and the description agree, and if not, which one (the page copy or the JSON-LD) needs to change to restore parity.
Patrick's relevant free tools
- Schema Markup Generator — Free JSON-LD generator with 19 focused forms plus all 921 vendored Schema.org types. Browse inherited properties and expected ranges, use honest Google/Bing/retired badges, compose @graphs, and export six output formats.
Tools for JobPosting validation
Rich-Result Eligibility Checker — this is
the tool to reach for first. Paste a job page’s JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal., its full HTML, or a live
URL, and it checks the JobPosting type specifically as one of its tracked rich-result
features: a per-property breakdown of ✓ eligible, ✗ the exact missing required field
(title, description, datePosted, hiringOrganization, jobLocation), and ⚠
for missing recommended fields (validThrough, employmentType, baseSalary).
Run it before you ship a new posting template, and again any time a disapproval
shows up in Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. — it tells you in seconds whether the problem is a
missing required property or something the tool can’t see (like content-schema
parity, which needs a human read of the page).
Schema Markup Validator — use this for the syntax
layer underneath eligibility: severity-tiered validation of the JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. itself
(malformed JSON, wrong @type nesting, @id graph issues), plus a corrected,
copy-pasteable JSON-LD block. Reach for it when the Rich-Result Eligibility Checker
flags a property as missing but you’re not sure whether the value is actually
absent or just malformed enough that the parser can’t see it.
Between the two: run the Rich-Result Eligibility Checker for the job-posting-specific eligibility question (“will this qualify for Google for Jobs”), and the Schema Markup Validator when you need to debug the raw JSON-LD syntax underneath it.
Standing KPIs for JobPosting health
These are the ongoing numbers worth tracking quarter over quarter — not a one-time launch check, but whether your JobPosting implementation stays healthy as postings come and go.
Google for Jobs impressions and clicks
- What it tells you: whether your postings are actually surfacing in the Google for Jobs rich-result surface and getting clicked, as opposed to just being technically eligible.
- How to pull it: Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results.’s job-posting rich-result report (under Enhancements), which breaks out impressions and clicks specifically for pages carrying valid JobPosting markup.
- Benchmark / realistic range: there’s no universal number here — it depends heavily on your posting volume, vertical, and how competitive “Google for Jobs” is for your roles. Establish your own baseline over your first few reporting cycles rather than comparing to an industry figure.
- Cadence: weekly during active hiring cycles; monthly is enough when posting volume is low.
Rolling disapproval rate
- What it tells you: whether your ongoing hygiene process — content-schema parity, one-job-per-page, expired-job removal — is actually holding up over time, rather than a single point-in-time compliance check.
- How to pull it: the valid/invalid/disapproved breakdown in Search ConsoleGoogle's free tool for monitoring crawling, indexing, and search performance.’s job-posting rich-result report, tracked as a percentage of your total live postings each period.
- Benchmark / realistic range: no industry-published baseline exists for this; the honest target is trending toward zero disapproved postings over time. Track your own trend rather than a borrowed number.
- Cadence: monthly, or aligned to whatever cadence you run the expired-job reconciliation sweep described in the SOPs tab.
Time-to-removal lag
- What it tells you: whether your removal pipeline (cron job, ATS integration, or Indexing APIThe Google Indexing API lets site owners notify Google directly when a URL is added, updated, or removed. Google officially supports it only for pages with JobPosting or BroadcastEvent (livestream) structured data — not for general content. call) is actually keeping pace with real-world job closures — this is the root-cause metric behind both of the KPIs above, since disapprovals and missed impressions both trace back to stale postings staying live too long.
- How to pull it: compare your ATS’s “closed” timestamp for a role against the timestamp one of the three sanctioned removal methods was actually applied to that page — an internal ops log, not a Search Console report.
- Benchmark / realistic range: the article’s own steer is “the moment it closes,” but there’s no universal SLA to cite — set your own target based on how fast your ATS integration or cron cadence can realistically run, and measure against that.
- Cadence: reviewed per closure event where possible, or on a rolling weekly basis if closures are batched.
Test yourself: JobPosting Schema
Five quick questions on JobPosting structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding., Google for Jobs eligibility, and the policies that get listings disapproved. Pick an answer for each, then check.
Resources worth your time
I don’t have a dedicated article on JobPosting schemaJobPosting schema is the schema.org/JSON-LD vocabulary you add to a single job-listing page so Google (and Bing) can read the role, employer, location, salary, and dates — making the page eligible for Google for Jobs. It requires title, description, datePosted, hiringOrganization, and jobLocation (or applicantLocationRequirements for fully remote roles). or Google for Jobs — this is new ground for me rather than a topic I’ve written up before, so I’m not going to manufacture a citation. What carries over is my general schema stance: implement markup when it earns you a real search feature, keep it in parity with what’s visible on the page, and validate before you ship. JobPosting clears that bar, which is why it’s worth doing precisely.
My related schema writing (general, not job-specific)
- Schema Markup for AISchema markup (structured data) is machine-readable code — usually JSON-LD — that labels what your content means using the schema.org vocabulary. For AI search it's infrastructure for entity disambiguation, not a direct citation lever: controlled studies found no meaningful uplift in AI citations from adding it. — the entity-infrastructure angle on schema (a different question from rich-result eligibility).
- The Beginner’s Guide to Technical SEO — where schema fits in the bigger picture.
- Enterprise SEO — my pragmatic take: “I’m a fan of schema markupSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor. as long as it gets you a search feature.”
From around the industry
- John Mueller Discusses What to do With Multiple Job Posting Schema Markup (iloveseo.com) — recap of the February 2022 Hangout on duplicate/syndicated postings and Google-side de-duplication.
- Google Launches Job Postings Schema For Job Search Inclusion (Search Engine Roundtable) — Barry Schwartz’s June 2017 launch coverage.
- New Job Posting Structured Data Requirements (Search Engine Journal) — Roger Montti on the March 2021 beta education/experience properties and their Career-Certificate origin.
- Google Jobs Shake-Up 2025: Navigating the New Indexing API Restrictions (dstribute.io) — industry timeline on the Indexing APIThe Google Indexing API lets site owners notify Google directly when a URL is added, updated, or removed. Google officially supports it only for pages with JobPosting or BroadcastEvent (livestream) structured data — not for general content. access change (treat dates as industry-sourced, not Google-confirmed).
- Major updates to the indexing API — impact on Job Boards and aggregators (alexanderchukovski.com) — job-board-focused analysis of the same shift.
JobPosting Schema
JobPosting schema is the schema.org/JSON-LD vocabulary you add to a single job-listing page so Google (and Bing) can read the role, employer, location, salary, and dates — making the page eligible for Google for Jobs. It requires title, description, datePosted, hiringOrganization, and jobLocation (or applicantLocationRequirements for fully remote roles).
Parent concept: Schema Markup · Related: Schema Markup, Structured Data, Product Page SEO
JobPosting Schema
JobPosting schema is the schema.orgSchema markup is code that uses the schema.org vocabulary to label what your content means so search engines can understand it and show rich results. It's most often written in JSON-LD, and it's not a direct ranking factor. type (https://schema.org/JobPosting), usually written in JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal., that you add to a page containing a single job listing so search engines can parse the role, employer, location, salary, and dates. Its payoff is eligibility for Google for Jobs — the job-search rich-result experience that surfaces a card or carousel of listings inside Google Search. Bing supports the same schema.org vocabulary for job listings but documents it far more lightly than Google.
Google requires five properties as a baseline: title (the job’s title, not the posting’s), description (the full HTML job description), datePosted (ISO 8601), hiringOrganization (the real employer’s name), and jobLocation (the physical worksite). Fully remote roles are the one exception to jobLocation: set jobLocationType to TELECOMMUTE and add applicantLocationRequirements naming at least one eligible country — Google requires this for every TELECOMMUTE posting, not just ones restricted to specific countries or regions.
Recommended properties don’t gate eligibility but drive click-through and filtering: validThrough, employmentType, baseSalary, identifier, and directApply. Two rules matter most in practice: the markup must live on a single-job page (never a listing or search-results page), and every value in the JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. must be visible in the human-readable page content, or Google can treat it as misrepresentation.
Parent concept: Schema Markup · Related: Schema Markup, Structured Data, Product Page SEO
Build-time retrieval analysis plus live signals for this exact article. The automatic chunk report includes a deterministic readiness score and is ready without a model download.
Search Console
sampleGA4 traffic (28d)
sampleCloudflare traffic (7d)
sampledCrUX field data (28d, phone)
sampleGoogle NLP entities
localChangelog
Updated Jul 18, 2026.
Editorial summary and recorded change details.Summary
Corrected two factual overstatements against Google's live JobPosting docs: expired-listing manual action removes the postings from Google for Jobs (not a whole-site penalty), and TELECOMMUTE always requires naming at least one eligible country via applicantLocationRequirements (or a jobLocation default) — there's no unrestricted-remote scenario with zero location fields. Also softened an unqualified salary-disclosure-law claim and added an explicit notification-not-guarantee note to the Indexing API section.
Change details
-
Rewrote the expired-posting manual-action language (beginner TL;DR and Advanced expiration section) to match Google's documented scope: removal from the Google for Jobs experience, not a blanket site-wide ranking penalty.
-
Corrected the remote/hybrid TELECOMMUTE guidance (Advanced section, decision tree, anti-patterns myth, ai-summary) to reflect Google's requirement that every TELECOMMUTE posting name at least one eligible country.
Full comparison unavailable — no prior snapshot was archived for this revision.