Google Indexing API, from a sheet or a database

A destination whose load step is a notification. Point a job at whatever already holds your URLs, and it tells Google those pages changed — on a schedule, without a script.

Coming soon — join the list for early access

An ETL destination that publishes, rather than stores

Every other destination is a place rows land — a sheet, a base, a table. This one's load step is a request to Google saying a URL was updated or removed. Whatever already holds your URL list becomes the source, and the notification is the write.

That shape matters, because it means you do not need a new system to manage. If your URLs live in a spreadsheet a content team maintains, that spreadsheet is the source. If they come out of a WHERE updated_at > … query against your CMS database, the query is the source. The job reads the list, filters it, and publishes.

Quota is the design constraint

The default project quota is 200 URL notifications per day, and publishing is one request per URL — there is no batch endpoint that submits several for one unit of quota. Every behaviour below follows from that single fact.

  • An oversized frame is refused before any request is issued, rather than publishing until the quota dies partway through.
  • Mid-run exhaustion stops the loop immediately: a daily quota is not a "slow down" signal.
  • test_connection never publishes, because the pipeline calls it before every load and a publishing test would double the quota cost of every run.
  • Re-publishing a URL Google has already seen is accepted, but still spends quota. This destination is not cheaply re-runnable, which is the opposite of every other one here.

The practical consequence: send changed URLs. A filter on a last-modified column is worth more here than anywhere else in the product, because the cost of getting it wrong is a day of quota rather than a few wasted seconds.

You must be a verified owner

Google only accepts notifications from an account that is a verified owner of the site in Search Console. That is a separate grant from the Search Console reporting connector — different scopes, different consent — so the two connections cannot be shared even though they concern the same sites.

indexing sensitive
Publish URL notifications. This one writes
userinfo.email non-sensitive
Label the connection

Reading back what Google recorded

The Indexing Status source is the other half of the pair. For a list of URLs it returns what Google has on record from your notifications — when each was last submitted, and whether it was an update or a removal. Reading status costs no publish quota.

Columns returned by Indexing Status
ColumnTypeNotes
urlstring
latest_update_typestring
latest_update_timedatetime
latest_update_urlstring
latest_remove_typestring
latest_remove_timedatetime
latest_remove_urlstring
notify_statusstring
notify_errorstringPopulated only when the lookup failed for that URL

Worth being precise about what this is not: it reports your notifications, not Google's index. It will not tell you whether a page is indexed or ranking — that question belongs in Search Console, and the Search Console source is how you get that data onto a schedule.

Where the URL list comes from

A spreadsheet

A tab a content team already maintains. Add a column for last-changed and filter on it.

A database query

Select URLs whose updated_at moved since the last run. The most precise option.

A file at a URL

A sitemap export or a CSV your CMS publishes on change.

A worked example

The shape that works: a query returning only URLs whose content changed since the last run, capped well under the daily quota, on a schedule that matches how often you actually publish. The filter is doing the important work here, not the connector.

Publishing changed pages from a CMS database

A Postgres source runs a query selecting the canonical URL of every page whose updated_at is newer than yesterday, with a LIMIT comfortably below the daily quota. The Indexing destination publishes each one as an update notification.

On a quiet day that job publishes nothing and costs nothing. On a day you ship thirty pages, it publishes thirty. Compare that with re-submitting a full sitemap, which spends the entire day's quota telling Google about pages that have not changed since last year.

Schedule: 0 3 * * *read it back in plain English

Pairing it with status

A second job runs the Indexing Status source over the same URL list and writes the result to a sheet, so you have a record of what was submitted and when. Because reading status costs no publish quota, that job can run as often as you like — and it is the only way to answer "did we actually tell Google about this page?" without guessing.

Questions

How many URLs can I submit a day?

The default project quota is 200 notifications per day, and each URL is one request - there is no endpoint that submits several URLs for one unit of quota. That constraint shapes the whole connector.

Why is this a destination rather than an action?

Because the input is a table of URLs. Whatever produces that list - a sheet, a database query, a file - becomes the source, and the load step is the notification.

Does submitting a URL guarantee it gets indexed?

No. You are telling Google a page changed. Google decides whether to crawl it, and separately whether to index it. Anyone promising otherwise is selling something.

Can I use my Search Console connection for this?

No. The Indexing API needs a different scope and separate consent, and it requires the account to be a verified owner of the site. You will authorise twice, deliberately.

What should I actually send?

URLs that changed. With 200 notifications a day and one request per URL, re-publishing your whole sitemap on a daily schedule spends the quota on pages Google already knows about.