Get Your Loxo Jobs into Google for Jobs: JobPosting Schema for Recruiting Agencies

Search for a job title and a city — “warehouse supervisor jobs Leeds” — and Google puts a box of job listings above the organic results. That is Google for Jobs. It costs nothing to appear in, and it is one of the few places left where a small agency site can sit level with Indeed and LinkedIn on a search that matters.

The catch is that you cannot write your way in. Google fills that box from structured data it reads while crawling job pages, and most recruiting agency websites publish nothing it can read. If your jobs live in Loxo, you also have the option of doing nothing at all: Loxo hosts a careers page for every agency at app.loxo.co/your-agency, and plenty of agencies simply point their menu there and never revisit the decision. That is a defensible choice, but be clear what it means here: any Google for Jobs placement those listings earn is earned on Loxo’s domain, and the candidate lands there rather than on your site. This article is about the other case: what has to be true for your own domain to qualify.

How Google for Jobs picks up a posting

Three things have to be in place. None of them is optional, and they fail independently, which is why a site can look fine and still be invisible.

  • A crawlable page for each job, on your domain. One URL, one role, returning a normal 200 response, not blocked in robots.txt, not behind a login, with the job text present in the HTML Google receives. A single “Current Vacancies” page listing twenty roles is not twenty postings — it is one page.
  • Valid JobPosting structured data on that page. A block of JSON-LD describing the role in the vocabulary Google reads: what the job is, who is hiring, where, and when it was posted.
  • Google knowing the page exists, quickly. A sitemap that includes job URLs is the baseline. For roles that fill in ten days, the Indexing API is better — Google recommends it specifically for job postings, because a listing indexed two weeks after it went live has already missed most of its candidates.

One expectation to set now: correct structured data makes a posting eligible. It does not guarantee inclusion. Google decides what to show, and it can decline. What you control is whether you are in the running at all.

What JobPosting schema requires

Google’s JobPosting documentation splits the properties into required and recommended. A missing required property is an error and the posting is not eligible. A missing recommended property is a warning: the listing can still appear, but with less to show and fewer filters it can match.

Required:

  • title — the role title on its own. “Registered Nurse”, not “URGENT! Registered Nurse — great rates, apply today”.
  • description — the body of the posting: responsibilities, requirements, and qualifications.
  • datePosted — the date the role went live.
  • hiringOrganization — the employer’s name, with a URL and logo alongside it where you have them.
  • jobLocation — a real postal address for the work location. Fully remote roles use jobLocationType: TELECOMMUTE together with applicantLocationRequirements instead.

Recommended: validThrough, employmentType (FULL_TIME, CONTRACTOR, and so on), baseSalary, and identifier. Salary is worth supplying: where baseSalary is absent, Google may show an estimated figure sourced from elsewhere instead, which can be wrong for your market and is not yours to correct.

validThrough deserves its own paragraph, because it is the property that catches people out. It is listed as recommended, and any posting with a closing date is expected to carry it — but the moment you emit one, it is binding. A validThrough in the past means Google treats the role as closed and the listing comes out of the results. Search Console reports it as “The value provided for validThrough is in the past”, and that is the only sign you get. Your job page still loads, still looks correct, and is simply no longer in the box. Postings that have genuinely closed should come down, so the behavior is right; the problem is roles that are still open sitting behind a date that expired three weeks ago.

Why an iframe embed never qualifies

Pasting Loxo’s embed snippet into a careers page is the fastest way to get jobs visible on your site, and for some agencies it is the right trade. It cannot produce a Google for Jobs listing on your domain, though, and no amount of configuration changes that.

An iframe loads a separate document from another origin. Your page’s HTML contains a frame element; the jobs are inside the frame, served by someone else. Line that up against the three requirements above and every one of them fails:

  • There is no per-job URL on your domain. There is one careers page and a frame on it — nothing for Google to treat as an individual posting.
  • There is no JobPosting JSON-LD in your page’s HTML. Structured data describes the document it sits in, and the framed content is a different document.
  • There is nothing to put in your sitemap or submit to the Indexing API, because there are no job URLs on your host to submit.

The same reasoning applies to linking your menu straight at the hosted Loxo careers page. Neither approach is broken; both simply put the crawlable job pages on a domain that is not yours.

Doing it from WordPress

If your marketing site runs on WordPress, the way to satisfy all three requirements is to make each Loxo job a real piece of content on your site. That is what LoxoWP does: it syncs jobs out of the ATS and stores them as native WordPress posts, so every role gets its own URL on your domain, rendered by your theme, indexable like any other page. Once the jobs are ordinary content, the rest is plumbing rather than a project.

  • JobPosting JSON-LD on every job page, built from the Loxo record — title, datePosted, validThrough, employmentType, jobLocation, baseSalary, and the remote properties where they apply. The employer details come from your plugin settings and are empty on a fresh install, which is the most common reason a brand-new site emits an error rather than a warning: an empty hiringOrganization.name is a missing required field. Fill in company name, URL, and logo first. The job schema and SEO documentation shows the complete output field by field.
  • A job sitemap, so new roles are discoverable through the normal crawl without you touching anything.
  • Google Indexing API integration, which notifies Google directly when a job is published, updated, unpublished, or deleted, instead of waiting for a recrawl. You connect your own Google Cloud service account, so the quota — 200 URL submissions a day by default — is yours. Setup is a one-time job and is walked through in the Google Indexing API documentation.

That last piece matters more for recruiting than for most content. A blog post indexed a week late loses nothing; a contract role that closes in twelve days and is indexed on day nine has lost most of its value.

Keeping postings valid

Getting a posting accepted once is the easy half. Keeping a board of thirty roles valid, month after month, is where sites quietly decay — and because an expired validThrough produces no visible symptom on your own site, nobody notices until someone opens Search Console.

validThrough comes from the expiry date on the Loxo job. Where a job has no expiry date at all, a default validity setting supplies one, counted from the publication date. So there are two honest ways to keep the dates truthful: maintain expiry dates in Loxo as roles open and close, or let something roll them forward for you.

The second is what the free Auto-Extend Expiry add-on is for. It keeps active jobs on a rolling window — 90 days by default — pushing each one’s expiry forward on import and through a daily background task, so validThrough stays near-term and realistic instead of drifting into the past or off into 2031. When the Google Indexing API is enabled it re-pings the changed pages too. Two things to know before you switch it on: it ships disabled and does nothing until you enable it, and once enabled it overrides the expiry date coming from Loxo on every sync. Pick one approach or the other — dates managed in Loxo, or dates managed by the add-on — not both.

The other half of hygiene is taking filled roles down. Job expiration management handles the schedule, and it is worth doing properly: a board full of closed vacancies wastes candidates’ time, and search engines read a pile of expired job pages as a quality problem.

Test it

Do not assume any of this is working. Open Google’s Rich Results Test, paste the URL of a published job, and read what comes back: a pass is a “Job postings” item detected with zero errors. Warnings are acceptable — they usually point at recommended properties you have chosen not to supply. Errors are not: each one is a required property missing or malformed, and the listing is ineligible until it is fixed. Which jobs are worth testing, how to see the exact markup Google received, and what causes each error message are all covered in the job schema documentation linked above, so there is no need to repeat it here.

Once Google has crawled the site for a few days, Search Console’s Enhancements → Job postings report gives you the site-wide view, grouped by issue type — checked once a month, that is the whole maintenance routine.

None of this is exotic work — a crawlable page per job, honest structured data on it, and Google told promptly when things change. The reason so few agency sites appear in Google for Jobs is not difficulty; it is that an embedded job board cannot do any of it. If your site is on WordPress and your jobs are in Loxo, see what LoxoWP includes.