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.

First published: Jun 27, 2026 · Last updated: Jul 18, 2026 · Advanced
demand #27 in Structured Data#57 in On-Page#257 in Technical SEO#347 on the site
1 evidence signal on this page

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). (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 — with applicantLocationRequirements/jobLocationType: TELECOMMUTE substituting 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 supply applicantLocationRequirements for a remote role.

A minimal, valid example:

{
  "@context": "https://schema.org/",
  "@type": "JobPosting",
  "title": "Software Engineer",
  "description": "&lt;p>Full job description in HTML…&lt;/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"
    }
  }
}

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 stale validThrough in place is a compliance problem, not a harmless default.
  • employmentTypeFULL_TIME, PART_TIME, CONTRACTOR, TEMPORARY, INTERN, VOLUNTEER, PER_DIEM, or OTHER (an array is allowed).
  • baseSalary (a MonetaryAmount) — the actual base salary provided by the employer, not an estimate; only the employer may supply it. Use unitText of HOUR/DAY/WEEK/MONTH/YEAR, and minValue/maxValue for a range. With pay-transparency laws spreading, this is increasingly not optional in practice.
  • identifier (a PropertyValue) — 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.

The beta-property framing above is paraphrased from Google’s launch statement as relayed in Search Engine Journal’s March 2021 coverage; it isn’t quoted verbatim here because I sourced it secondhand. Confirm the exact wording against the live docs before treating it as a direct quote.

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.

Evidence for this claim Google documents jobLocationType TELECOMMUTE and applicantLocationRequirements for fully remote jobs. Scope: Google Search JobPosting remote-job requirements; hybrid roles should not be marked as fully remote. Confidence: high · Verified: Google: JobPosting structured data

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:

  1. Set validThrough to a date in the past and leave the page up briefly.
  2. Remove the page entirely and return a 404 or 410.
  3. 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:

  1. 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.
  2. 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.
Industry reporting (dstribute.io, alexanderchukovski.com) frames the shift from near-open Indexing API access to an authorized-partner/approval model as rolling out roughly across 2024–2025. I’m treating those phased dates as industry-sourced color, not Google-confirmed line by line — the primary, citable fact is Google’s own quota-pricing/approval page. The rep warnings about API misuse were surfaced through secondary aggregation, so I’ve paraphrased rather than quoted them; verify exact wording and platform against the primary source before quoting directly.

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 validThrough and 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.
Caveat, per my source research: there have been reports of a 2026 Search Console job-listing reporting issue affecting how job 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. surface in the report. I haven’t been able to confirm that against a primary Google source, so treat it as an unverified possibility — if your report looks wrong but the markup validates cleanly in the Rich Results Test, a reporting glitch is worth ruling in, but confirm before concluding it’s a Google-side bug.

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.

I couldn’t confirm a live, canonical Bing Webmaster ToolsMicrosoft's free portal for monitoring and improving how a site appears in Bing search — the peer to Google Search Console, plus IndexNow instant indexing, richer backlink data, and keyword volumes. Because Bing's index also feeds Microsoft Copilot, it doubles as a window into AI-search visibility. help URL specifically titled for JobPosting during my research pass. Rather than guess a URL, I’m stating the gap plainly: Bing’s job-listing documentation is genuinely thin. Re-verify the current Bing help page before adding a direct link.

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.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.