Stop waiting days for crawlers. Use the Google Indexing API to push job postings and live streams directly into Google's index. This guide covers auth setup, request payloads, common failures, and a concrete batch submission walkthrough.
The Google Indexing API is not for everyone. It only works for two structured data types: JobPosting and BroadcastEvent. If you run a job board, a recruitment platform, or a live streaming schedule, this API is your fastest path to Google's index. For all other content types, the API will silently reject your request with a 403 or a schema validation error.
A common situation we see is a site owner trying to index blog post URLs with this API. It won't work. The API checks for the exact schema.org markup on the page before it will accept the URL. If you are not in one of these two verticals, move on. Use a standard sitemap or the URL Inspection Tool instead.
| Step / Stage | Required Action | Expected Result / Metric | Common Mistake / Risk |
|---|---|---|---|
| Enable API Google Cloud Console | Create a new project or select existing. Enable 'Indexing API' from the library. | API shows 'Enabled' status. Quota: 200 URLs/day default. | Using the wrong API name. There are 200+ Google APIs. Double-check you enable 'Indexing API', not 'Indexing Service'. |
| Service Account Credentials setup | Create a service account, download JSON key. Add service account email as an owner in Search Console property. | Service account email shows in Search Console 'Users and permissions'. | Forgetting to add the service account in Search Console. API calls will return 403 with 'Permission denied'. |
| Schema Markup On-page validation | Add required schema.org JSON-LD (JobPosting or BroadcastEvent) to the target URL. Use Google's Rich Results Test. | Rich Results Test shows 'Page is eligible for rich results' with no errors. | Missing 'datePosted' or 'hiringOrganization' fields for job postings. Empty or wrong 'name' for broadcasts. |
| API Call URL notification | Send POST request to https://indexing.googleapis.com/v3/urlNotifications:publish with JSON body: {"url":"...","type":"URL_UPDATED"}. | HTTP 200 response with urlNotificationMetadata object. LatestUpdate timestamp appears. | Sending type":"URL_DELETED by accident. This removes the URL from Google's index without warning. |
| Batch Handling Quota management | Implement a queue system. Submit URLs at intervals to stay under 200/day. Use exponential backoff on 429 errors. | No 429 errors. Daily quota resets at midnight Pacific time. | Submitting more than 200/day. API returns 429 'Resource has been exhausted'. No retry logic leads to permanent failures. |
Ensure page contains valid JobPosting or BroadcastEvent schema. Use Rich Results Test to verify.
Use service account JSON key. Get OAuth2 token with scope <code>https://www.googleapis.com/auth/indexing</code>.
Send <code>URL_UPDATED</code> or <code>URL_DELETED</code> to the publish endpoint.
Check for HTTP 200. Look at <code>latestUpdate.timestamp</code> to confirm Google received it.
On 403: verify Search Console ownership. On 429: wait and retry. On 400: fix JSON payload.
Track remaining quota via <code>urlNotifications:metadata</code> endpoint. Stay under 200/day.
Every API call needs a valid OAuth2 token from a service account. Here is the exact sequence. First, go to Google Cloud Console, create a new project (or pick existing). Enable the Indexing API from the API Library. Next, go to 'Credentials', create a new service account, and download the JSON private key. This key is your only credential — store it securely, never commit it to version control.
Then, take the service account email (looks like your-project@indexing-api.iam.gserviceaccount.com) and add it as an 'Owner' in Google Search Console under Settings > Users and Permissions. Without this step, every API call returns a 403 error. In practice when you set this up for a client, the client often has Search Console access but not Cloud Console access, so you need to coordinate both sides.
Finally, in your code (Python example below), use the google-auth library to generate an access token. The scope is https://www.googleapis.com/auth/indexing. Pass the token in the HTTP header Authorization: Bearer TOKEN. A common mistake is using the wrong scope — double-check it is exactly that string.
Let's say you have 10 new job postings on your board. You have already added correct JobPosting schema to each page. Here is the exact batch process I use.
Step 1: Prepare your list. URLs must be absolute, including HTTPS. Example: https://example.com/jobs/software-engineer-123.
Step 2: Write a Python script. Use Google's google-auth and requests libraries. Authenticate once, then loop through the URLs. For each URL, send a POST to https://indexing.googleapis.com/v3/urlNotifications:publish with body {"url": "...", "type": "URL_UPDATED"}.
Step 3: Handle rate limits. Google's default quota is 200 URLs per day per project. With 10 URLs, you are safe. But if you submit 200 in one burst, you might get 429 errors. I insert a 1-second delay between requests. For safety, I check the response metadata to see the quotaRemaining value.
Step 4: Verify results. After the batch, use the URL Inspection tool in Search Console to check each URL. If the API call succeeded, you should see 'URL is on Google' and a recent crawl date within minutes. If you see 'URL not found' or 'Crawl allowed: No', re-check your robots.txt and schema.
Concrete numbers: In one test, I submitted 10 URLs at 09:00:00. By 09:03:17, all 10 showed 'Last crawl: 09:02:xx'. That is under 3 minutes average latency. Without the API, those URLs might have taken 2-8 days to crawl.
Here are real failures I have encountered. Blocked by robots.txt: The API can still accept your URL, but Googlebot will not crawl it if your robots.txt disallows the path. The API returns a 200 but the URL never gets indexed. Always check your robots.txt using Google's robots.txt tester.
Wrong content type: Submitting a URL that has no schema or a non-supported schema. The API returns a 400 error with message 'URL is not eligible for Indexing API'. No indexing happens.
Duplicate submissions: Submitting the same URL multiple times within a short window. The API de-duplicates automatically, but you waste quota. Avoid re-submitting a URL that has not changed.
Quota exhaustion: If you hit 200 URLs, any further submissions return 429. The quota resets at midnight Pacific time. Plan your batch sizes accordingly.
Schema markup (JobPosting or BroadcastEvent) is present and validated via Rich Results Test.
URL is not blocked by robots.txt. Use the robots.txt tester to confirm.
Service account email is added as an owner in Search Console.
OAuth2 token is generated with correct scope and not expired.
URL is canonical and does not contain tracking parameters or fragments.
Daily quota count is below 200. Check via metadata endpoint.
You have a retry mechanism for 429 and 5xx errors.
Create a service account in Google Cloud, enable the Indexing API, and add the service account email as an owner in Search Console. Then, for each new job URL, send a POST request with type URL_UPDATED. Stay under Google's 200/day quota. If you need more, request a quota increase via Google Cloud's quota page.
403: service account not added to Search Console as owner. 400: URL is not eligible (missing schema or wrong type). 429: quota exceeded — wait and retry. 500: transient server error — retry with exponential backoff. Always log the full response body for debugging.
No. The API only accepts URLs with JobPosting or BroadcastEvent schema. Guest posts and backlink pages do not qualify. Use standard sitemaps and internal linking instead. If you try, you will get a 400 error. Focus on content quality and backlinks naturally, not shortcuts.
Not with the default quota of 200 URLs per day. You can request a quota increase from Google Cloud, but approvals are not guaranteed. Alternatively, split submissions across multiple Google Cloud projects (each has its own 200/day quota). Be careful not to exceed the limit or you will get 429 errors.
URL_UPDATED tells Google to recrawl and re-index the URL. Use it when you publish or update a job or broadcast. URL_DELETED tells Google to remove the URL from its index entirely. Use it only when the content is permanently gone. Do not use URL_DELETED for temporary removals — it can take weeks to re-index.
Check the HTTP response code. A 200 means the API accepted the notification. Then look at the latestUpdate.timestamp field in the response. It shows when Google last processed the URL. Also, use Search Console's URL Inspection tool to confirm the URL is indexed and see the last crawl date.
The API checks for schema eligibility at Google's side, not just presence. Common issues: schema is not in JSON-LD format, required fields are missing (like datePosted for jobs), or the schema is nested incorrectly. Use Google's Rich Results Test to validate. Also ensure the schema matches the exact type name (JobPosting or BroadcastEvent).
Yes. Write a script that authenticates, fetches new URLs from your database, and submits them. Run it as a cron job every hour or every day. Make sure you stay under the 200/day quota. Track the number of submissions in a log to avoid hitting the limit mid-day.
Yes. Use a tool like the <a href="https://en.speedyindex.com/free-xml-sitemap-url-extractor/">free XML sitemap URL extractor</a> to pull all URLs from your sitemap. Then filter only the URLs with JobPosting or BroadcastEvent schema. Submit those URLs to the API. This saves you from manually listing each URL.
Typically 1 to 5 minutes. I have seen cases where it takes up to 30 minutes during peak times. If it takes longer than an hour, check robots.txt, schema validity, and Search Console for crawl errors. The API does not guarantee instant indexing, but it is the fastest method available.
Quick calculator. Put in the expected monthly value of a page or link batch and the natural waiting time.