URL: /code/integrations/google-search-console · Id: `page:/code/integrations/google-search-console`

# Google Search Console

> Your agents add and verify your site, submit the sitemap, check that each key page is indexed, and read the searches that show you.

Your agents add and verify your site, submit the sitemap, check that each key page is indexed, and read the searches that show you.

```text title="Run it · Ask"
Check that my home, pricing and rent ledger template pages are indexed on Google.
```

```ts title="Run it · SDK"
import { $ } from 'startup-builder'

const result = await $.try.Domain.verify({ domain: 'leaseline.app', pages: ['https://leaseline.app/', 'https://leaseline.app/pricing', 'https://leaseline.app/rent-ledger-template'] })
```

```json title="Run it · Response"
{
  "$type": "Domain",
  "mode": "try",
  "stored": false,
  "domain": "leaseline.app",
  "searchEngines": [
    {
      "venue": "google-search",
      "verified": true,
      "propertyAdded": true,
      "sitemap": {
        "submitted": 48,
        "indexed": 31,
        "lastRead": "2026-10-25T03:10:00Z",
        "errors": 0
      }
    }
  ],
  "pages": [
    {
      "url": "https://leaseline.app/",
      "state": "indexed",
      "lastCrawl": "2026-10-24T11:02:00Z"
    },
    {
      "url": "https://leaseline.app/pricing",
      "state": "not-seen",
      "reason": "Discovered, not crawled yet",
      "fix": "Link it from the home page and the template"
    },
    {
      "url": "https://leaseline.app/rent-ledger-template",
      "state": "crawled-not-indexed",
      "reason": "Crawled, not indexed yet",
      "lastCrawl": "2026-10-23T08:41:00Z"
    }
  ],
  "lagDays": 2
}
```

- **Connect:** Verify your domain, 3 grants
- **Runs through:** [Your account](/code/integrations#three-ways)
- **First run:** Check that your key pages are indexed, free
- **Sites:** None, it holds your records

## Connect once
1. Connect your Domain with `Domain.connect`; the platform adds the property, writes the verification record to your DNS and submits the sitemap.
2. For a site already in Search Console, call `Integration.connect` with `system: 'seo'` instead, then open the `connectUrl` it returns and sign in as an owner of that property.
3. Name your key pages (home, pricing, the pages that sell); those are the ones your agents check every day.

| Grant | What it unlocks | Scope |
| --- | --- | --- |
| Prove you own the site | The DNS verification record the platform writes when you connect your Domain | `https://www.googleapis.com/auth/siteverification` |
| Manage the property | Adding the site, submitting and removing sitemaps, and inspecting pages | `https://www.googleapis.com/auth/webmasters` |
| Read only | Searches, clicks, impressions and position, when you would rather grant no changes | `https://www.googleapis.com/auth/webmasters.readonly` |

| To | Do this |
| --- | --- |
| Pause | `Integration.pause` stops every call through Google at once and keeps the token; `Integration.resume` picks up from the same cursor. |
| Reconnect | `Integration.reconnect` returns a fresh `connectUrl` that lasts one hour, and keeps the Integration's id and cursor, so nothing imports twice. |
| Disconnect | `Integration.revoke` revokes the token with Google; every record it brought in stays in your records. |

## What your agents do
| Ask | Verb | Runs through | Price |
| --- | --- | --- | --- |
| Is each key page indexed, and if not, why not? | [`Domain.verify`](/code/data/domains/verify) | Your account | Free |
| Show me the searches that showed my site last week, with clicks and position. | [`Metric.query`](/code/apps/analytics-and-experiments/query) | Your account | Free |
| Add my site to Google and submit the sitemap when I connect the domain. | [`Domain.connect`](https://startupbuilder.dev/business/nouns/domain/connect) | Your account | Free |
| Resubmit the sitemap whenever a page goes live. | [`Content.publish`](https://startupbuilder.dev/business/nouns/content/publish) | Your account | Free |
| Watch my key pages daily and wake me when one leaves the index. | [`Monitor.create`](/code/data/monitors/create) | Your account | Free |

Calls on your own account are free.

## What it holds
| Noun | The account’s object | When | Which side leads |
| --- | --- | --- | --- |
| [Domain](https://startupbuilder.dev/business/nouns/domain) | `sc-domain property` | You connect your Domain | Your records |
| [Page](https://startupbuilder.dev/business/nouns/page) | `inspectionResult` | Your agent checks a key page | The account |
| [Keyword](https://startupbuilder.dev/business/nouns/keyword) | `searchAnalytics row` | Each day’s searches settle | The account |

## Events and webhooks
| Direction | Event |
| --- | --- |
| Emits | `Domain.verified`, `Keyword.measured`, `Monitor.checked` |

Any Event can wake a Workflow, and a Watch delivers it to your endpoint, signed ([Events and webhooks](/code/events)).

## Limits
| What | Limit | Call |
| --- | --- | --- |
| Page checks | 2,000 a day and 600 a minute per property; past it a check refuses with `quota-reached` and runs after the reset | [`Domain.verify`](/code/data/domains/verify) |
| Search data | Settles about 2 days behind, so a readout of yesterday reads the last settled day | [`Metric.query`](/code/apps/analytics-and-experiments/query) |
| Request indexing | Has no API: for a key page still out of the index after a week, the browser agent presses it in Search Console, signed in as you | Every call |

## Field map
| Our field | Google Search Console’s field | Notes | Calls |
| --- | --- | --- | --- |
| `Metric.breakdown` | `dimensions` | query, page, country, device or date | [`Metric.query`](/code/apps/analytics-and-experiments/query) |
| `Metric.window` | `startDate and endDate` | None. | [`Metric.query`](/code/apps/analytics-and-experiments/query) |
| `Metric.metric` | `clicks, impressions, ctr or position` | None. | [`Metric.query`](/code/apps/analytics-and-experiments/query) |

## What try does here
Reads run for real, because a read changes nothing in Search Console; `try` stores no rows and submits no sitemap.

## How long a connection lasts
A connection lasts until you revoke it in your Google Account; Google also ends a grant left unused for six months, and every call your agents make counts as use.

The platform asks you to reconnect 7 days before it runs out; until you do, a call that needs it refuses with [`needs-reauth`](/code/refusals#needs-reauth).

## Plays and strategies
| Kind | Where |
| --- | --- |
| Plays | [Editorial SEO](/plays/editorial-seo), [Programmatic SEO](/plays/programmatic-seo), [Answer engine optimization](/plays/aeo), [Category hubs](/plays/category-hubs), [Switch kit](/plays/switch-kit), [Free tools](/plays/free-tools) |
| Strategies | [Launch and search](/strategy/launch-and-search) |

## Used by
- **Workflows:** [AI answer audit](/capabilities/check-ai-answers/ai-answer-audit) · [Index the site](/capabilities/get-indexed/index-the-site)
- **Agent tasks:** [Answer page per question](/capabilities/make-content/answer-pages)
- **Services:** [Ranked page](/capabilities/make-content/ranked-page)

## Reference

| Call | Path | Price |
| --- | --- | --- |
| [`Domain.verify`](/code/data/domains/verify) | `POST /domains/verify` | Free |
| [`Metric.query`](/code/apps/analytics-and-experiments/query) | `POST /metrics/query` | Free |
| [`Domain.connect`](https://startupbuilder.dev/business/nouns/domain/connect) | `POST /domains/connect` | Free |
| [`Content.publish`](https://startupbuilder.dev/business/nouns/content/publish) | `POST /content/publish` | Free |
| [`Monitor.create`](/code/data/monitors/create) | `POST /monitors/create` | Free |