Stop manually resubmitting sitemaps. Learn how to use the Google Indexing API to automatically notify Google of new or updated URLs. Includes Python and cURL examples, authentication steps, and rate limit handling.
Quick calculator. Put in the expected monthly value of a page or link batch and the natural waiting time.
Manual sitemap resubmission in Search Console is fine for a handful of updates. But for large sites — think 10,000+ pages, job boards, news feeds, or e-commerce product listings — that workflow breaks. You need a programmatic path. That path is the Google Indexing API.
The API lets you push individual URLs to Google's index immediately after creation or update. It's not a replacement for sitemaps; it's a faster trigger. In practice, when you publish a new product page at 10:00 AM, you call the API at 10:01 AM. Google crawls and indexes within hours, not days. Without it, you wait for the next sitemap crawl cycle — which can be 24-48 hours for high-authority sites, or longer for fresher domains.
| Operation | Required Action | Expected Result | Common Failure / Risk |
|---|---|---|---|
| URL_UPDATED Notify new or changed page | POST request with URL and type=URL_UPDATED | Returns 200 OK with URL metadata | Quota exceeded (200/day) Duplicate notification wastes quota |
| URL_DELETED Notify removed or 404 page | POST request with URL and type=URL_DELETED | Removes URL from index within hours | Soft 404s not caught Page returns 200 but content is gone |
| Authentication OAuth 2.0 for service account | Create service account, enable API, grant owner permission | Access token valid for 3600 seconds | Token expiry not handled Wrong scope leads to 403 errors |
| Bulk submission Sending batch of URLs | Loop with 1-2 second delay between calls | Each URL gets individual notification | Rate limit (600/100s) exceeded Batch too fast triggers 429 response |
| Verification Check if URL was indexed | Call URL Inspection API or use bulk URL index checker | Returns indexing status and last crawl date | Stale status until Google reprocesses False negatives if checked too early |
In Google Cloud Console, create a service account. Download the JSON key file. Enable the Indexing API for the project.
Add the service account email as an owner in Search Console for the target property. This is mandatory for API access.
Use the JSON key to request an OAuth 2.0 token. The token expires after 3600 seconds. Refresh automatically in your script.
POST to https://indexing.googleapis.com/v3/urlNotifications:publish with the URL and type (UPDATED or DELETED). Include the Bearer token in headers.
Check for 200 OK. If 429 (rate limit), back off with exponential retry. If 403, verify permissions and token scope.
Use the URL Inspection API or a third-party checker to confirm the URL is indexed. Repeat for DELETED notifications.
Assume you have 50 new product URLs from today's feed. You want to notify Google for each. The script below handles authentication, rate limiting, and error logging.
import requests, json, time, os
from google.oauth2 import service_account
from google.auth.transport.requests import Request
SCOPES = ['https://www.googleapis.com/auth/indexing']
SERVICE_ACCOUNT_FILE = 'service-account.json'
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, scopes=SCOPES)
urls = [
'https://example.com/product/1001',
'https://example.com/product/1002',
... # 48 more
]
for idx, url in enumerate(urls):
credentials.refresh(Request()) if not credentials.valid else None
headers = {'Authorization': f'Bearer {credentials.token}', 'Content-Type': 'application/json'}
body = {'url': url, 'type': 'URL_UPDATED'}
resp = requests.post('https://indexing.googleapis.com/v3/urlNotifications:publish', headers=headers, json=body)
if resp.status_code == 200:
print(f'{idx+1}: {url} notified')
elif resp.status_code == 429:
time.sleep(10)
print('Rate limited, sleeping 10s')
else:
print(f'Error {resp.status_code}: {resp.text}')
time.sleep(1.5) # stay under 600/100sAfter running, verify with a bulk URL index checker to see which URLs got indexed within the hour.
A common situation we see is developers hitting the 200 URLs/day quota before noon. They have 400 URLs to submit but only 200 slots. The fix: prioritize. Only notify truly new or updated URLs, not every page in a sitemap. Use a diff tool to compare your current inventory against yesterday's.
Another failure: the service account is not granted owner permission in Search Console. The API returns a 403 error with 'Permission denied'. Double-check the property in Search Console — it must be verified, and the service account must be listed as an owner, not just a user.
Duplicate URLs also waste quota. If you send the same URL twice in one day, the second call counts against your limit but does nothing. Deduplicate your list before submission. Finally, watch out for pages blocked by noindex tags. The API won't index them. Always check for noindex tags before submitting.
Service account created and key downloaded from Google Cloud Console.
Indexing API enabled for the project.
Service account email added as owner in Search Console for the target property.
OAuth token refresh logic implemented (token expires after 3600 seconds).
URL list deduplicated and filtered to only new/updated URLs.
Rate limit handling: max 600 requests per 100 seconds, 200 URLs per day per project.
Error logging for non-200 responses, especially 403 and 429.
Verification step scheduled 1-2 hours after submission.
The quota is 200 URLs per day per project. This is a hard limit. If you need more, you can request a quota increase via Google Cloud Console, but approval is not guaranteed. For larger volumes, consider using sitemaps for remaining URLs and prioritize only critical pages for the API.
The rate limit is 600 queries per 100 seconds per user or project. If you exceed it, the API returns a 429 status. Implement exponential backoff: wait 10 seconds on first 429, then 20, then 40, up to a maximum. Also, space your requests by at least 1.5 seconds to stay safely under the limit.
No. The Indexing API only works for URLs on sites that you own and have verified in Search Console. You cannot use it to push external backlinks or guest post URLs into Google's index. For those, rely on the site owner to submit their sitemap or use social signals.
1. Go to Google Cloud Console, create a project. 2. Enable the Indexing API. 3. Create a service account and download the JSON key. 4. In Search Console, add the service account email (e.g., my-bot@project.iam.gserviceaccount.com) as a verified owner. 5. Use the JSON key in your code to request an access token with scope 'https://www.googleapis.com/auth/indexing'. The token expires hourly; refresh it automatically.
403: permission denied — the service account is not an owner in Search Console. 429: rate limit exceeded — slow down requests. 400: bad request — check JSON formatting and URL validity. 500: internal server error — retry after a few seconds. Always log the response body for debugging. If you get persistent 403, verify the service account email in Search Console.
Yes. Use the URL Inspection API (https://developers.google.com/webmaster-tools/v1/urlInspection.index). It returns the indexing status, last crawl date, and any coverage issues. This is useful for verifying your notification worked. Alternatively, use a third-party bulk URL index checker for large lists.
The API will accept the notification, but Google will not index the page because the noindex directive takes precedence. The API notification is just a crawl request; it does not override page-level meta tags. Always check for noindex tags before submitting to avoid wasting quota. Use a noindex tag checker tool to scan your URLs first.
Deduplicate your URL list before sending any notifications. Use a simple set data structure in Python or sort and uniq in bash. If you submit the same URL twice in one day, the second call counts against your 200/day limit but produces no additional benefit. Also filter out URLs that haven't changed since last submission.
URL_UPDATED tells Google to crawl and index a new or changed page. URL_DELETED tells Google to remove a page from the index (e.g., a product that is discontinued or a 404 page). Both consume the same daily quota. Use URL_DELETED sparingly — only for pages that are permanently removed, not temporarily unavailable.
The Indexing API is free to use within the quota limits: 200 URLs per day per project. There are no paid tiers or additional pricing. However, if you exceed the quota, you can request an increase through Google Cloud Console, but it is not guaranteed. For high-volume needs, combine the API with XML sitemaps and prioritize the most important pages.