---
title: "Google Indexing API for job postings"
description: "Use the Google Indexing API for job postings in WordPress: connect a service account, and Google hears about new, changed and closed Greenhouse jobs."
source: https://greenhouse.w4dev.com/docs/google-indexing-api/
---

Greenhouse Jobs for WordPress can tell Google, through its Indexing API, when a job is published,
changed or closed. Each notification asks Google to crawl the page sooner than a sitemap would,
and goes from your site through a Google Cloud service account you create.

## What the Indexing API does, and what it doesn't

Google [allows the Indexing API](https://developers.google.com/search/apis/indexing-api/v3/quickstart)
only for pages with `JobPosting` data or livestream videos. Every job page carries `JobPosting`
data while **JSON-LD schema** is on under **Greenhouse → Settings → Features**. Turn it off and the
Google Indexing screen warns you.

- A notification is a request to crawl, not a guarantee of indexing or a place in Google for
  Jobs.
- The API is free. Each project gets a
  [default quota](https://developers.google.com/search/apis/indexing-api/v3/quota-pricing) of
  200 notifications a day, which Google describes as for onboarding and testing. For wider use,
  Google asks you to [request approval and quota](https://developers.google.com/search/apis/indexing-api/v3/quota-pricing#request-quota).
- Google checks submissions for spam and can revoke access if the API is abused.
- Keep **Jobs sitemap** on under **Greenhouse → Settings → Features** (see
  [settings](/docs/settings/)): Google still recommends a sitemap for coverage of the whole site.

## 1. Create a service account key in Google Cloud

1. In the [Google Cloud console](https://console.cloud.google.com/), create a project or pick
   one.
2. Under **APIs & Services → Library**, enable the **Web Search Indexing API**.
3. Under **IAM & Admin → Service Accounts**, create a service account. It needs no project role.
4. Open the service account, go to **Keys → Add key → Create new key**, choose **JSON** and click
   **Create**. A `.json` file downloads.

## 2. Make the service account an owner in Search Console

Your site must be a verified property in [Search Console](https://search.google.com/search-console).
A verified owner opens it, goes to **Settings → Users and permissions → Add user**, enters the
service account's email (from the JSON file, `client_email`) and picks **Owner**.

Google rejects notifications from a service account that is not an owner of the property.

## 3. Connect the key in WordPress

1. Go to **Greenhouse → Google Indexing**.
2. Tick **Automatic notifications**.
3. Paste the whole JSON file into **Service account key** and click **Save**.

The screen then shows the service account's email and project. The key is checked before it
is saved, stored in your database without autoloading, and never shown again. To remove it,
tick **Remove the stored key** and save.

## 4. Test, then submit your jobs

- **Test connection** signs in with the key and asks Google about your home page. It uses no
  notification quota and works while notifications are off.
- **Submit all published jobs** queues every open job, which is worth doing once after
  connecting. Each job uses one notification.

If you later change the jobs slug or the site's permalink structure, a notice on the Greenhouse
screens asks you to submit all jobs again, because Google still has the old addresses.

## What is sent to Google, and when

Each notification holds only a job page's URL and whether it was updated or removed. Nothing
about applicants is sent.

| When | Sent |
|---|---|
| A job is published, or reopens | Updated |
| A job changes in Greenhouse and the next import picks it up | Updated |
| A job closes in Greenhouse, or is trashed or deleted | Removed, for the URL Google was last told about |

Only the latest change per URL is sent, and an identical automatic notification is queued at
most once every ten minutes.

## Queue, daily quota and retries

Notifications wait in a queue. WP-Cron sends it in batches of 25, starting seconds after a change.

- **Quota:** 200 a day, counted from midnight Pacific time, when Google resets it. Past the
  limit, the queue waits for the reset.
- **Retries:** when Google or the network fails, a notification is retried after 5, 10, 20 and
  40 minutes, then dropped and logged. A notification Google rejects for its URL is dropped at
  once.
- **Setup errors:** if Google rejects the key, the service account is not an owner, or the API
  is not enabled, sending pauses. A notice appears on the Greenhouse screens and the queue is
  kept. Fix the problem, then click **Save** on the Google Indexing screen, or run
  `wp ghjb indexing run`, to resume.

The **Status** table shows today's quota, the queue and the next run. **Activity** lists the
last 50 results; **Clear log** empties it.

## WP-CLI commands for Google Indexing

| Command | What it does |
|---|---|
| `wp ghjb indexing status` | On or off, the connected account, the queue, today's quota and the latest log entries. Takes `--format`, `--field` and `--last=<number>`. |
| `wp ghjb indexing log` | The activity log, newest first. Takes `--limit` (default 20) and `--format`. |
| `wp ghjb indexing run` | Sends the next batch now. Lifts a pause and tries again. Takes `--format` and `--field`. |
| `wp ghjb indexing notify <job>` | Sends one notification for a job, by post ID or URL. `--type=deleted` sends a removal. Works while automatic notifications are off. |
| `wp ghjb indexing test` | Checks the key and the Search Console permission. |

`run` exits with an error when notifications are off, no key is saved, another run is sending,
or the setup error is still there. The other commands: [WP-CLI](/docs/wp-cli/).

## Developer hooks

| Hook | Type | Use it to |
|---|---|---|
| `ghjb_google_indexing_daily_limit` | filter | Raise the daily limit after Google grants more quota. Default 200. |
| `ghjb_google_indexing_batch_size` | filter | Change how many notifications one run sends. Default 25. |
| `ghjb_google_indexing_max_attempts` | filter | Change how many times a failed notification is tried. Default 5. |