Indexer by DependsiT

URL_UPDATED vs. URL_DELETED: Understanding Indexing API Notification Types

indexing api notification types compared for URL UPDATED and URL DELETED

This guide explains the two notification types accepted by the Google Indexing API, URL_UPDATED and URL_DELETED, and when to send each one. You will learn the official scope for JobPosting and BroadcastEvent pages, the exact JSON shapes for publish calls, how getMetadata reflects latestUpdate and latestRemove, and how to avoid the common error of sending the wrong type for drafts, redirects, and soft 404s. The focus keyword is indexing api notification types. Copy paste Python, Node, PHP, and cURL samples are included for both types.

Key takeaways

  • URL_UPDATED signals new or materially changed content that should be crawled, while URL_DELETED signals removed content that returns 404 or 410.
  • Google officially supports JobPosting and BroadcastEvent pages only, so other types are off label hints with no promised crawl.
  • Send canonical public URLs only, with correct host, protocol, and trailing slash behavior matching the live page.
  • Check getMetadata after sends to confirm notifyTime, and keep sitemaps and internal links aligned with the type you sent.
  • Handle 403 as config fix, 429 as pause with backoff, and 400 as list fix, with separate handling for update and delete batches.

indexing api notification types compared for URL UPDATED and URL DELETED <!-- IMAGE-PROMPT cover: 1200x630, DependsIt brand, deep charcoal #121212 or clean white background, vibrant mint #22E3B0 accent glow, thin node-network line art, Clash Display style bold heading space on left, General Sans clean labels, subject: two notification paths updated versus deleted comparison, flat vector, high contrast, accessible, no photorealistic faces, no text smaller than 24px, no em dash in rendered text, export PNG then cwebp -q 82 to WEBP -->

indexing api notification types in one view

The Indexing API publish endpoint accepts a JSON body with url and type, where type is either URL_UPDATED or URL_DELETED. URL_UPDATED tells Google that the content at the URL is new or has changed in a meaningful way and may warrant a fresh crawl. URL_DELETED tells Google that the URL has been removed and that the server now returns 404 or 410. Both types require that you own the URL through Search Console verification and that your service account holds Owner permission on the matching property. Both return urlNotificationMetadata with notifyTime on success, which confirms receipt rather than indexing.

Think of the two types as opposite signals in a content lifecycle. A job post moves from draft to published, so you send URL_UPDATED for the canonical job URL. The same job expires after the closing date and the page is removed with a 404, so you send URL_DELETED for the same URL. A livestream page is scheduled, so you send URL_UPDATED when the BroadcastEvent markup gains a start date. The stream ends and the page is taken down, so you send URL_DELETED. A standard blog post follows the same lifecycle shape, but it sits outside official support, so treat its signals as hints with uncertain effect while keeping the same type discipline.

Type discipline keeps logs and coverage clean. Mixing types in one batch without labels makes review harder, since update and delete rows need different follow up checks. Keep separate queues or at least separate batch IDs for updates and deletes. Many tutorials shorten the pair to url_updated url_deleted when they describe lifecycle handling in code comments. Every urlnotifications publish call uses the same endpoint path, with only the type field changing between update and delete. Validate status codes before sending: live 200 pages belong in update batches, gone 404 or 410 pages belong in delete batches. Redirecting URLs belong in neither until the redirect target and canonical are resolved, since notifying the old URL while users and bots land on the new one splits signals. Among common indexing api actions, the two you will use most are send update for live pages and delete url from google for gone pages, and both notify google of changes through the same publish path. For broader context on manual submission limits that these types replace, see the comparison of Indexing API versus Request Indexing. The full set of indexing api types is small by design, so keep this mapping in your runbook.

TypeMeaningServer stateFollow up
URL_UPDATEDNew or changed, please recrawl200 with indexable contentCheck notifyTime, then coverage
URL_DELETEDRemoved, please drop404 or 410Check notifyTime, then removal

Teams new to the API often ask whether resending the same type repeatedly speeds up crawling. It does not. A second URL_UPDATED for an unchanged URL adds no new information and consumes quota. A URL_DELETED for a live URL creates a conflicting signal that can delay correct handling. Send each type once per meaningful state change, record the result, and move effort to sitemaps and internal links until the next real change occurs at that URL. Keep a per URL history with last type and notifyTime so editors can see at a glance whether a new send adds information or merely repeats the prior signal.

Official scope and why it matters

Google documents the Indexing API for JobPosting pages and for BroadcastEvent pages inside VideoObject markup, typically livestreams. Those are the only types with official support. The endpoint accepts the same two notification types for those pages, and Google may schedule a fresh crawl after URL_UPDATED or process removals after URL_DELETED. Normal blog posts, product pages, category pages, and portfolio items are outside that scope. Many owners still send both types for those URLs and often receive 200 responses, but 200 means the hint was received, not that Google will act on it. Scope shapes policy, reporting, and stakeholder expectations for every bulk plan.

Google does not support IndexNow. IndexNow is a separate open protocol for Bing, Yandex, Naver, Seznam, and other participating engines, using a plain text key file at the site root. It never sends signals to Google. If you need removal or update coverage on Bing, use IndexNow or Bing Webmaster submission in parallel with separate lists and logs. For Google, the supported inputs are the Indexing API for the two documented page types, plus sitemaps and Search Console inspection requests. The reference that settles scope questions is the Indexing API prerequisites, which tracks current docs better than older tutorials.

Scope also affects structured data requirements. JobPosting pages should carry valid JobPosting markup with title, hiring organization, job location, date posted, and validThrough or expiry handling. BroadcastEvent pages should carry valid BroadcastEvent markup with start dates and stream references inside VideoObject. Invalid or missing markup weakens the value of correct notification types, since Google evaluates page eligibility alongside the hint. Validate markup before bulk sends, keep expiry logic consistent so expired jobs actually leave the index, and keep livestream schedules accurate so update pings match visible changes.

For teams submitting normal pages off label, document the choice plainly. Note that updates and deletes are hints, that effect is measured through coverage and server logs rather than tool counters, and that sitemaps and links carry most of the weight. Share the honest answer on normal pages with content owners so type decisions stay consistent across posts, jobs, and video pages. A one page policy that lists allowed types per content kind prevents ad hoc deletes for redirected URLs and ad hoc updates for unchanged archives.

ContentOfficial supportType policy
JobPosting with markupYesURL_UPDATED on publish, URL_DELETED on expiry with 404
BroadcastEvent livestreamYesURL_UPDATED on schedule change, URL_DELETED on takedown
Standard post or pageNot documentedOptional hint, same type rules, monitor coverage
Redirected URLNeeds resolutionNotify the canonical target, not the old hop

When URL_UPDATED is the correct choice

Send URL_UPDATED when a public canonical URL is new or has changed in a way that affects what Google should crawl and evaluate. New publish is the clearest case: a job post goes live with a 200 status, self referencing canonical, and valid markup, so notify once. Material update is the second case: title, slug, main content, structured data, availability, salary, location, or stream schedule changed enough to matter for searchers. In both cases, the URL must be live, crawlable by robots.txt, free of noindex, and returning 200 with the updated content already deployed. Notify after deploy, not before, so a crawl that follows the hint sees the new state.

Do not send URL_UPDATED for non changes. Template tweaks, sidebar swaps, ad slot moves, analytics tag updates, and typo fixes that do not alter meaning rarely justify quota spend. Autosaves, previews, and revision saves should never trigger, since they do not change the canonical public URL. Bulk imports should trigger only for rows that are actually new or materially changed, not for every row touched by the import job. A simple rule helps editors: if the change would matter to someone deciding to click the result, it qualifies. If only the site team would notice, skip the ping and rely on sitemap lastmod.

WordPress and CMS wiring should reflect this rule. Hook into publish transitions rather than save actions, filter to allowed post types, skip password protected and private content, and require that permalinks match the canonical host. For updates, compare a content hash or require an editor checkbox for major update before notifying. These guards turn URL_UPDATED from a noisy firehose into a quiet signal that fires a few times per day on typical blogs and more often on active job boards.

EventSend URL_UPDATEDSkip
New publish, 200 liveYes, onceNo duplicate next day
Major content or markup changeYes, once after deployNo for typo only
Template or tag changeNoUse sitemap lastmod
Preview or autosaveNeverNot a public state

After sending URL_UPDATED, record notifyTime and check coverage over the following days rather than resending. If coverage shows crawled but not indexed, the limit is content evaluation or duplication, not delivery. Improve depth, uniqueness, canonical clarity, and internal linking before considering another ping. Repeated updates without page improvement rarely change outcomes and consume budget needed for genuinely new URLs. Keep notes on what changed between pings so future reviews can distinguish a fresh material update from a repeat send with no new information.

When URL_DELETED is the correct choice

Send URL_DELETED when a previously notified URL has been permanently removed and the server now returns 404 or 410 for that exact URL. Expired job posts that are taken down, deleted livestream pages after takedown, and removed blog posts with no successor all fit. The sequence matters: remove the page or serve the correct gone status first, update sitemaps to drop the URL, remove or update internal links that pointed to it, then notify. This order ensures that a crawl following the hint observes the gone state rather than a live page that contradicts the delete signal.

Do not send URL_DELETED for redirects, drafts that still render, or noindex pages that still return 200. A 301 redirect means the content moved, so notify URL_UPDATED for the new canonical target if it qualifies, and let the redirect consolidate signals. A trashed post that still renders a preview or a soft 404 that returns 200 with thin content is not a valid delete case. Fix server handling first so the URL truly returns 404 or 410, then notify once. Sending deletes for live URLs creates conflicting signals and complicates removal reporting.

Handle expiry with care on job boards. Many boards keep expired jobs live with an expired banner for user experience. That page returns 200, so URL_DELETED does not fit even though the job is closed. Either take the page down with a proper 404 or 410 before notifying delete, or keep it live with accurate expired markup and send URL_UPDATED to reflect the status change. Choose one path per site and apply it consistently, since mixed handling across jobs makes coverage reports hard to read. Document the chosen path in your indexing runbook with status code expectations.

StateCorrect typePrecondition
Page removed, 404 liveURL_DELETEDSitemap dropped, links updated
Page removed, 410 liveURL_DELETEDGone handling confirmed
Page redirected 301URL_UPDATED on targetOld URL not notified as deleted
Page live with noindexNeitherFix indexing directives first

After URL_DELETED, verify with getMetadata for latestRemove and monitor coverage for the URL dropping from indexed state over days. Removals take time and depend on recrawl, so a recent notifyTime with continued index presence the next hour is normal. Avoid resending deletes daily. One clean delete with correct server handling outperforms repeated pings with mismatched status codes. If the URL must return temporarily for legal or archival reasons, update your lifecycle sheet to reflect the live state and pause further delete sends until a final takedown decision is recorded.

Request shapes and endpoint behavior

Publish calls share one endpoint path for both types, with the type distinguished in the JSON body. The body holds url as a fully qualified canonical string and type as URL_UPDATED or URL_DELETED. Headers include Content Type application/json and Authorization Bearer with a short lived access token from your service account flow. The token carries the indexing OAuth scope and typically lasts 3600 seconds. Reuse the token across a batch and refresh on invalid token errors rather than fetching per URL. Send one POST per URL, paced with sleeps, and parse the JSON response for urlNotificationMetadata.

Success returns HTTP 200 with metadata containing the echoed URL, the latestUpdate or latestRemove block, and notifyTime in RFC 3339 format. Record the full notifyTime per URL and batch ID. A 200 confirms receipt, not crawl or index. Client errors return 400 for malformed URLs or unknown types, 401 or 403 for auth and permission problems, 404 on metadata reads for no history, and 429 for quota throttles. Server errors return 5xx for transient issues. Treat each family differently: fix lists for 400, fix access for 403, pause for 429, backoff once for 5xx. The urlnotificationtype field accepts only two values, and any other string returns 400. A minimal indexing api json body holds url and type, plus headers for content type and bearer auth.

The quickstart with exact fields is shown in official docs at Indexing API quickstart.

{
  "url": "https://example.com/jobs/software-engineer-123/",
  "type": "URL_UPDATED"
}
{
  "url": "https://example.com/jobs/expired-role-456/",
  "type": "URL_DELETED"
}

Keep batches homogeneous by type for clarity. An update batch holds only URL_UPDATED rows with live 200 URLs. A delete batch holds only URL_DELETED rows with 404 or 410 URLs. This separation simplifies logging, retry rules, and follow up checks, since updates need coverage review for indexing while deletes need coverage review for removal. Mixed batches are technically allowed but operationally noisy, especially when 429 requires a pause that affects both kinds at once.

indexing api notification types diagram for update and delete paths <!-- IMAGE-PROMPT diagram-01: 1600px max, DependsIt brand mint #22E3B0 on charcoal #121212 or white, node-network line art, subject: updated versus deleted notification paths diagram, flat vector, accessible, no em dash, Clash Display style headings, General Sans clean labels -->

Read status with getMetadata

getMetadata reads notification history for one URL without sending a new hint. Post to the metadata path with a JSON body containing url, using the same Bearer token. The response includes the URL and, when history exists, latestUpdate with notifyTime and type, or latestRemove with notifyTime and type. A recent notifyTime after your send confirms receipt. Absence of history with a 404 means no notification has been recorded for that URL, which is normal before first submit. Use this read once per URL after sending rather than polling in a loop.

Interpret fields by type. After URL_UPDATED, expect latestUpdate to reflect your send time. After URL_DELETED, expect latestRemove to reflect your send time. If you sent an update but latestRemove is newer, a prior delete is still the latest event, so review lifecycle order. If timestamps lag your send by hours, allow for processing delay before concluding failure. If the echoed URL differs in trailing slash or host case from your canonical, normalize your list to avoid split history across URL variants that Google treats as distinct strings.

Use metadata checks to debug type errors. A live page with only latestRemove history suggests a prior delete was sent by mistake or by an old job. A gone page with only latestUpdate history suggests the delete was never sent or used the wrong URL string. A URL with no history after a reported 200 suggests the send used a different property, a different URL string, or a tool that did not actually transmit. These reads take seconds and prevent repeat sends based on guesses.

# Metadata check for one URL. Replace TOKEN and URL. Inspect latestUpdate and latestRemove.
curl -s -X POST "https://indexing.googleapis.com/v3/urlNotifications/metadata" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TOKEN" \
  -d '{"url":"https://example.com/jobs/software-engineer-123/"}'

Record metadata results with your batch logs. Store url, latestUpdate notifyTime, latestRemove notifyTime, and check date in your sheet or queue table. This small history helps during audits when stakeholders ask whether a specific URL was notified as updated or deleted and when. Avoid automating metadata polling every few minutes, since that adds load without new information. Check once after send, then rely on coverage and server logs for effect. Keep metadata snapshots with batch IDs so update and delete histories remain easy to compare during quarterly reviews.

Common mistakes that waste quota

The most common mistake is notifying the wrong URL string. Preview links with query parameters, staging hosts, uppercase hosts, http variants when canonical is https, and missing or extra trailing slashes all create 400 errors or split history. Normalize every list to canonical form before queueing, resolve redirects to final targets, and drop parameter variants that canonicalize elsewhere. A 10 minute cleaning pass with host lowercasing and redirect resolution often saves more quota than any pacing tweak.

The second mistake is wrong type for the server state. Updates sent for 404 pages, deletes sent for live 200 pages, and deletes sent for 301 redirects all create conflicting signals. Validate status codes for the batch before sending: 200 for updates, 404 or 410 for deletes, resolved target for redirects. Fix soft 404s where the server returns 200 with empty results content, since those look live to the API but read as gone to evaluation. Use indexing api remove url handling only for genuinely gone pages that return 404 or 410, never for redirects. A clean indexing api update notification belongs to live 200 pages after deploy, with canonical and markup already correct. Keep update and delete lists in separate files so validation rules stay simple.

The third mistake is resubmitting unchanged URLs on a schedule. Daily URL_UPDATED for the same 100 URLs without content changes adds no information and burns daily budget needed for fresh pages. Similarly, daily URL_DELETED for already removed URLs adds noise after the first clean delete. Send once per state change, record notifyTime, and let sitemaps carry routine freshness. Reserve quota for new publishes, material updates, and genuine removals with verified status codes.

The fourth mistake is ignoring property mismatch. Submitting staging URLs under a production property, or production URLs under a staging property where the service account lacks Owner, yields 403 across the batch. Confirm the canonical property string, confirm Owner role, and confirm the key belongs to the intended project before any bulk run. Keep a status code reference open during log review so 400, 403, 429, and 5xx are triaged without guesswork.

MistakeSymptomFix
Non canonical URL string400 invalid URLNormalize host, protocol, slash
Wrong type for stateConflicting signalsValidate 200 for updates, 404 for deletes
Repeat sends, no changeQuota burn, no effectSend once per state change
Property mismatch403 across batchConfirm Owner on canonical property

Python samples for both types

Python keeps update and delete handling explicit with shared auth and separate batch files. The sketch below loads a service account JSON from a private path, exchanges a JWT for an access token cached for 55 minutes, then sends one POST per URL with pacing. Updates read from updates.csv with live URLs, deletes read from deletes.csv with gone URLs. Each row logs url, type, code, notifyTime when present, and error excerpt for non 200. The sender stops at a daily cap and backs off on 429 with jitter. Adapt paths, caps, and sleeps to your quota.

Keep auth outside the send loop and reuse the token for the whole batch. Fetch once, send many, refresh only on invalid token. Validate lists before sending with canonical checks and status sampling. Run in dry run mode first to print what would send without calling the API. Start with 5 URLs per type, confirm 200 and metadata, then run full P1 slices. This staged approach catches list errors before they consume budget.

# Shared sender for URL_UPDATED and URL_DELETED. One at a time with sleep.
import time, random
def publish_one(url, kind, token):
    # POST url and kind to publish path with Bearer token.
    # Return status code and parsed notifyTime for logging.
    return 200, '2026-10-15T10:00:00Z'
def run_batch(rows, token, cap=150, sleep_s=3):
    sent = 0
    for url, kind in rows:
        if sent >= cap:
            break
        code, notify = publish_one(url, kind, token)
        print(url, kind, code, notify)
        sent += 1
        if code == 429:
            time.sleep(300 + random.randint(0, 60))
        else:
            time.sleep(sleep_s)

Log both types with the same fields so comparisons stay simple. Include batch ID such as 2026-10-15-UPD-01 or 2026-10-15-DEL-01, plus tries count and next retry timestamp for failures. Move rows to retry or dead letter after three attempts with type preserved. Review dead letter weekly by type, since update failures often point to canonical issues while delete failures often point to status handling. For bulk pacing that surrounds these samples, review bulk submission safe limits.

Node PHP and cURL samples

Node suits JavaScript teams with queue workers. Use fetch with Bearer auth, await a sleep between sends, and keep concurrency at one. Read updates and deletes from separate JSON files, send each file in its own run with its own batch ID, and write results to a log file with code and notifyTime. Handle 429 with a 5 minute pause and exit, handle 403 with exit and alert, and retry 5xx once after a short wait. Keep tokens in environment variables and never commit keys to the repo.

// Node sketch for both types. Separate runs for updates and deletes.
async function sendList(rows, token) {
  for (const r of rows) {
    const res = await fetch('https://indexing.googleapis.com/v3/urlNotifications:publish', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
      body: JSON.stringify({ url: r.url, type: r.type })
    });
    console.log(r.url, r.type, res.status);
    await new Promise(x => setTimeout(x, 3000));
  }
}

PHP fits CMS hosts and WP CLI runs. Use wp_remote_post or curl with the same JSON bodies, loop one at a time, and log to a private file. Keep update and delete CSVs separate, validate status codes before sending, and cap per run to avoid web timeouts. Prefer CLI or cron over admin page loads for larger lists. cURL fits audits and one off fixes: loop over a text file with sleep, read the token from an environment variable, and log HTTP codes per URL. Use distinct passes for updates and deletes with labeled result files for sheet import.

// PHP sketch. Separate CSVs for updates and deletes, paced sends.
function send_rows($rows, $token) {
    foreach ($rows as $r) {
        list($url, $type) = $r;
        $code = post_single($url, $type, $token);
        error_log('[notify] ' . $type . ' ' . $url . ' code=' . $code);
        sleep(3);
    }
}
# cURL delete pass. Only for URLs that return 404 or 410. Small batches with pauses.
# export TOKEN=ya29.xxx
# while read -r U; do
#   curl -s -o /tmp/del.json -w "%{http_code} $U\n" -X POST "https://indexing.googleapis.com/v3/urlNotifications:publish" \
#     -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
#     -d "{\"url\":\"$U\",\"type\":\"URL_DELETED\"}";
#   sleep 3;
# done < deletes.txt

Choose the stack that matches hosting and skill, but keep list format, pacing, and log fields identical across stacks. Consistency lets operators compare update versus delete 200 rates and tune caps without relearning a new schema per tool. When a new developer joins the rotation, a single runbook with shared field names shortens onboarding and reduces the chance of type errors during on call sends.

indexing api notification types diagram: official scope and why, urldeleted is the correct, read status with getmetadata <!-- IMAGE-PROMPT workflow-02: 1600px max, DependsIt brand, subject: update and delete batch workflow with validation steps, flat vector, accessible, no em dash, mint #22E3B0 on charcoal #121212, node-network line art, Clash Display style headings, General Sans clean labels -->

Errors pacing and logs per type

Error handling differs slightly by type, so encode the difference in code and docs. For URL_UPDATED, 400 often means non canonical or preview URLs, so fix the list and resend once after validation. For URL_DELETED, 400 often means the URL string is malformed or the type was mistyped, so fix and resend once. For both types, 403 means Owner or property mismatch and needs config work before any resend. For both types, 429 means pause with backoff and resume later with smaller batches. For both types, 5xx means wait and retry once, then queue for next window.

Pacing should respect type priority. When quota is tight, favor deletes for expired jobs that confuse searchers over minor update refreshes, and favor new job updates over low value tweaks. Allocate daily budget by type, for example 60 percent updates for new pages, 25 percent updates for major changes, 15 percent deletes and urgent fixes. Process in that order each day and defer the rest to sitemap coverage. This allocation keeps both lifecycle ends moving without starving either.

Logs should make type obvious at a glance. Include type in every log line, batch ID with UPD or DEL prefix, tries count, code, notifyTime, and error excerpt for non 200. Keep separate daily counters for updates and deletes so reports show lifecycle balance. Alert on 403 spikes for either type, on 429 across hours, and on dead letter growth.

CodeUpdate actionDelete action
200Record notifyTime, check coverageRecord notifyTime, check removal
400Fix canonical, resend onceFix URL string, resend once
403Fix Owner, do not blast retrySame, fix access first
429Pause, halve batchPause, resume next window
5xxBackoff onceBackoff once

Notification types work best when sitemaps, links, and Search Console agree with the signal. After URL_UPDATED, ensure the URL appears in the sitemap with accurate lastmod, is linked from relevant hubs, and serves 200 with self referencing canonical. After URL_DELETED, ensure the URL is removed from sitemaps, internal links are updated or removed, and the server returns 404 or 410. Mismatches such as deletes for URLs still listed in sitemaps or updates for URLs blocked by robots create conflicting signals that slow correct handling.

Use Search Console to confirm alignment. Inspect a sample of updated URLs for last crawl time and index state. Inspect a sample of deleted URLs for coverage moving toward excluded with not found or gone reasons. Compare sitemap index counts before and after delete batches to confirm drops. Check Crawl Stats for Googlebot activity on notified URLs in the days after sends, but treat timing as indicative. Document sample sizes and dates with each check for audit clarity. If updated URLs show discovered but not indexed, focus on content depth and internal linking rather than repeat pings. If deleted URLs persist in the index, recheck server status handling for soft 404s before resending.

Maintain a simple lifecycle sheet with columns for URL, current state live or gone, last type sent, notifyTime, sitemap presence, and link presence. Update the sheet on every publish, update, and removal so future sends use fresh state rather than memory. Review the sheet weekly during active hiring or streaming seasons and monthly otherwise. This small discipline prevents the common drift where deletes are forgotten, sitemaps retain gone URLs for months, and quota is spent re notifying stale state. Assign one owner for sheet updates so publish, unpublish, and sitemap edits stay synchronized across content and engineering.

FAQ

When should I use url_updated url_deleted for the same URL across its lifecycle?

Use url_updated url_deleted as opposite lifecycle signals for the same canonical URL at different times. Send URL_UPDATED once after publish when the page returns 200 with self referencing canonical and complete content. When the same job expires or the livestream page is taken down with 404 or 410, send URL_DELETED once after sitemaps and links are updated. Do not send both types together for one state, since that creates conflicting signals. Record notifyTime per send and check getMetadata for latestUpdate versus latestRemove to confirm which event is newest. Keep one history row per URL so editors see lifecycle order.

How does urlnotifications publish handle update versus delete?

Every urlnotifications publish call posts to the same endpoint path with a JSON body holding url and type, plus bearer auth headers. Use URL_UPDATED for live 200 pages after deploy and URL_DELETED for gone 404 or 410 pages after sitemap cleanup. The response returns 200 with urlNotificationMetadata and notifyTime on success, which confirms receipt rather than indexing. To notify google of changes cleanly, keep update and delete rows in separate batches with UPD and DEL batch IDs. Validate status codes before sending, since updates for gone pages and deletes for live pages waste quota and confuse removal reporting.

When is indexing api remove url the correct choice?

Choose indexing api remove url handling only when a previously indexed URL is permanently gone and serves 404 or 410 at the exact path. First remove the page, drop it from sitemaps, and update internal links, then send URL_DELETED once and confirm latestRemove with getMetadata. This is the correct way to delete url from google after takedowns without creating redirect confusion. Do not use deletes for 301 redirects, drafts that still render, or noindex pages that return 200. Those cases need canonical fixes or update pings for the new target, not removal signals that conflict with live content.

What makes a clean indexing api update notification?

A clean indexing api update notification targets a public canonical URL that is live with 200 status, self referencing canonical, and complete content already deployed. Send it once after publish or after a material change such as title, main content, availability, or schedule updates that matter to searchers. Skip typo fixes, template tweaks, previews, and autosaves, since those do not change the indexed state. Among common indexing api actions, update for live pages is the most frequent, so guard CMS hooks to fire only on publish transitions for allowed post types. Record notifyTime and monitor coverage instead of resending daily without new changes.

What does urlnotificationtype control in the request?

The urlnotificationtype field controls whether Google treats the hint as an update or a removal, and it accepts only URL_UPDATED or URL_DELETED. Any other string returns 400 and wastes a send. The full set of indexing api types is small by design, so map lifecycle states clearly in your runbook before coding. Use update for new and materially changed 200 pages, delete for gone 404 or 410 pages, and neither for redirects until the canonical target is resolved. Keep batches homogeneous by type with UPD and DEL IDs, since updates need coverage review for indexing while deletes need review for removal over days.

What should an indexing api json body include?

A minimal indexing api json body holds url as a fully qualified canonical string and type as URL_UPDATED or URL_DELETED, sent with content type application json and bearer auth. Reuse one access token across the batch and refresh only on invalid token errors. Success returns 200 with urlNotificationMetadata, latestUpdate or latestRemove blocks, and notifyTime in RFC 3339 format. Log the full notifyTime per URL with batch ID and tries. Keep update batches to live 200 URLs and delete batches to gone URLs, since mixed batches complicate retry rules when 429 requires a pause that affects both kinds at once.

Sources

  • https://developers.google.com/search/apis/indexing-api/v3/prereqs
  • https://developers.google.com/search/apis/indexing-api/v3/quickstart
  • https://support.google.com/webmasters/answer/7440203
  • https://schema.org/JobPosting

Further reading

Put this into practice. Indexer submits URLs to the Google Indexing API and IndexNow, audits coverage with Search Console, and shows exactly which pages are indexed. Start free or see how it works.