If you post jobs on your own website and want them to reach candidates through Google's job experience and AI assistants, JobPosting schema is what makes it possible. Without it, your careers page is just prose that search engines have to guess at. With it, each opening becomes a structured object — title, location, salary, employment type, posting date — that can appear in the Google job search box and be surfaced when someone asks an assistant "who's hiring remote React developers?" This guide covers the required fields, the ones that decide whether you actually show up, and the rules that get postings removed.
Why JobPosting schema is worth the effort
Job seekers increasingly start their search inside a search engine or an AI assistant rather than on a job board. Google's dedicated job experience pulls listings directly from company sites that mark up their openings — no job-board middleman required. AI assistants that answer employment questions lean on the same structured signals. If your postings are plain HTML, you are invisible to both; if they carry clean JobPosting markup, your role can appear with its title, location, and salary right where candidates are looking.
Like all JSON-LD structured data, JobPosting works by converting things a machine would otherwise have to infer into explicit fields. "Competitive salary" tells an engine nothing; a baseSalary object with a currency and a range tells it everything.
The fields you actually need
Several fields are effectively mandatory to be eligible for the job experience, and skipping them is the most common reason a posting never appears:
- title — the role only, like "Senior Backend Engineer." Do not stuff location or company into the title.
- description — the full HTML job description: responsibilities, qualifications, benefits. This should match the visible posting.
- datePosted — when it went live, in ISO 8601 format. Freshness matters; stale dates hurt.
- hiringOrganization — name, and ideally a logo and site URL.
- jobLocation — a full postal address for on-site roles.
- applicantLocationRequirements and jobLocationType — required for remote roles; set the type to TELECOMMUTE and specify which countries or regions are eligible.
Strongly recommended: baseSalary (a range with currency and unit — per year, per hour), employmentType (FULL_TIME, PART_TIME, CONTRACTOR), and validThrough, the date the posting expires. Salary transparency in particular is now expected by candidates and increasingly required by law in many regions, so include it whenever you can.
Expiry is not optional — it's the rule most sites break
The single biggest failure with JobPosting schema is leaving expired jobs marked up and live. When a role is filled or closed, you must remove it from the experience, and there are only two correct ways to do it: set the validThrough date in the past, or take the page down and return a 404 or 410. What you must not do is leave a filled role sitting on the site with valid markup and no expiry — that pollutes results with dead listings and erodes trust in your entire careers section.
If you remove the page entirely, return a proper gone signal rather than a soft redirect to your homepage, following the logic in our guide to 410 Gone vs 404 Not Found. Handling expiry cleanly is what separates a careers page that keeps appearing from one that gets demoted for surfacing jobs that no longer exist.
Common mistakes and how to avoid them
Beyond expiry, a few errors recur. Marking up a listing index page — your "all open roles" page — with a single JobPosting instead of putting the markup on each individual job's own URL. Mismatching the schema and the visible content, for example a salary in the markup that isn't shown on the page. Omitting location fields for remote roles, which makes the posting ineligible even though remote is exactly what many candidates search for. And forgetting to validate before publishing, which our guide to validating structured data walks through — a missing required field is a silent disqualification, not a warning you'll notice in traffic.
If you also run a physical business, pair JobPosting with LocalBusiness schema so engines connect the hiring organisation to a known entity — a small consistency signal that helps AI understand who is doing the hiring.
JobPosting schema is one of the clearest wins in structured data because it plugs your openings straight into where candidates now search — search engines and assistants — without paying a job board. Mark up each role on its own URL, fill the required and salary fields, keep the markup matched to the visible posting, and retire jobs the moment they close. To check that your careers pages expose valid JobPosting data and that crawlers can read them, run the CheckMy.site scanner and fix what it flags.