The Google Search Console Indexing API is powerful but unforgiving. Quota limits, OAuth complexity, and opaque error responses make building production-grade pipelines harder than the documentation suggests. This is a practical guide through the real challenges.
Authentication: service accounts vs. OAuth
There are two authentication paths for the GSC APIs: delegated OAuth (user-consented access) and service accounts (server-to-server). For production indexing pipelines, service accounts are almost always the right choice.
- βService accounts don't require user re-consent and work without human interaction
- βOAuth tokens expire and need refresh logic; service accounts use JWT-based auth that's easier to manage at scale
- βService accounts require being added as an owner or full user to each GSC property β this is a one-time setup step
import { google } from 'googleapis';
// Load service account credentials
const auth = new google.auth.GoogleAuth({
credentials: JSON.parse(process.env.GSC_SERVICE_ACCOUNT_JSON!),
scopes: [
'https://www.googleapis.com/auth/indexing',
'https://www.googleapis.com/auth/webmasters',
],
});
const indexing = google.indexing({ version: 'v3', auth });
// Submit a URL for indexing
async function submitUrl(url: string) {
const res = await indexing.urlNotifications.publish({
requestBody: {
url,
type: 'URL_UPDATED', // or URL_DELETED
},
});
return res.data;
}The quota reality
The Indexing API has a default quota of 200 URL submissions per day per project. This is separate from the Search Console API quota. For sites with large content volumes, this is the single biggest operational constraint.
If you're managing multiple GSC properties with one service account project, all properties share the same 200/day quota. Structure your projects accordingly β or request a quota increase via Google Cloud console.
Queue management and retry logic
The naive approach β submit all URLs immediately when content changes β breaks down quickly under quota limits. Production pipelines need a queue with:
- 01Priority scoring (new content > updated content > re-validation requests)
- 02Exponential backoff on rate limit errors (HTTP 429)
- 03Status tracking per URL with last submission timestamp
- 04Dead letter handling for URLs that fail repeatedly
- 05Quota awareness β distribute submissions across the 24-hour reset window
Monitoring indexing status
The GSC URL Inspection API lets you programmatically check the index status of any URL. Combining submission tracking with status checks gives you a complete picture of your indexing pipeline health.
async function checkIndexStatus(siteUrl: string, inspectUrl: string) {
const webmasters = google.webmasters({ version: 'v3', auth });
const res = await webmasters.urlInspection.index.inspect({
requestBody: {
inspectionUrl: inspectUrl,
siteUrl: siteUrl,
},
});
const result = res.data.inspectionResult;
return {
coverageState: result?.indexStatusResult?.coverageState,
indexingState: result?.indexStatusResult?.indexingState,
lastCrawlTime: result?.indexStatusResult?.lastCrawlTime,
robotsTxtState: result?.indexStatusResult?.robotsTxtState,
};
}Error categories and how to handle them
| Error | HTTP Status | Meaning | Action |
|---|---|---|---|
| INVALID_ARGUMENT | 400 | Malformed URL or request body | Fix URL format, retry |
| QUOTA_EXCEEDED | 429 | Daily quota consumed | Queue for next reset window |
| FORBIDDEN | 403 | Service account not authorised | Re-add account to GSC property |
| NOT_FOUND | 404 | URL not accessible to Google | Check robots.txt / noindex tags |
| INTERNAL | 500 | Google-side error | Retry with exponential backoff |
Production checklist
- βService account JSON stored as a secure secret (not committed to version control)
- βService account added as Search Console property owner
- βQueue processor with priority scoring and quota tracking
- βExponential backoff with jitter on 429 responses
- βDaily quota monitoring with alert at 80% utilisation
- βStatus check reconciliation β verify submitted URLs reach "Submitted and indexed" state
- βLogging per submission with URL, timestamp, HTTP status, and response body
visibility score
See how discoverable your content is to AI search engines β free, no card required.
Start free β