Skip to main content
Google Search Console (GSC) integration allows us to verify customer domains with Google and submit sitemaps for better indexing. This is critical for visibility in Google AI Overviews, as Google does not support IndexNow.

Why Google Search Console?

Google is the only major search engine that doesn’t support IndexNow. To get our AI-optimized pages indexed by Google (and visible in AI Overviews), we must use the Search Console API.

Architecture

We use a master account approach:
  • One Google account owns all verified customer domains
  • Customers don’t need their own Google accounts
  • We use OAuth2 with a refresh token for API access
  • The refresh token never expires (as long as used every 6 months)

Limits

Each Google account can manage a maximum of 1,000 sites in Search Console. When approaching this limit, you must add a new admin account (see below).

Current Setup

Adding a New Admin Account

When you reach ~900 sites on admin_1, it’s time to add admin_2@searchcompany.co.

Step 1: Create the Google Account

  1. Create a new Google Workspace account: admin_2@searchcompany.co
  2. Ensure it has access to Google Search Console

Step 2: Get OAuth Credentials

The same OAuth client (Client ID + Secret) can be used for multiple accounts. You only need a new refresh token.
  1. Go to OAuth Playground
  2. Click the gear icon (βš™οΈ) β†’ Check β€œUse your own OAuth credentials”
  3. Enter the existing GOOGLE_CLIENT_ID_GSC and GOOGLE_CLIENT_SECRET_GSC
  4. Select scopes:
    • https://www.googleapis.com/auth/siteverification
    • https://www.googleapis.com/auth/webmasters
  5. Click β€œAuthorize APIs”
  6. Sign in as admin_2@searchcompany.co (not admin_1)
  7. Grant permissions
  8. Click β€œExchange authorization code for tokens”
  9. Copy the Refresh Token

Step 3: Add Environment Variable

Add the new refresh token to your .env:

Step 4: Update the Code

Modify Backend/src/app/shared/google_search_console/client.py to support multiple accounts:

Step 5: Implement Account Selection Logic

Add logic to select which account to use based on current site counts:

Step 6: Store Account Assignment

Add a column to ai_sites table to track which account owns each site:

Token Refresh Behavior

The refresh token stays valid as long as:
  1. Used at least once every 6 months - Our daily cron (sitemap resubmission) handles this automatically
  2. User doesn’t revoke access - Only if someone logs into the Google account and revokes app access
  3. Under 50 refresh tokens per account - We only have 1 per account, so no issue
If a refresh token is revoked or expires, you’ll need to repeat the OAuth Playground flow to get a new one.

Endpoints

Flow During Domain Connection

Google verification runs in a two-step process:

Step 1: Get TXT Records (Frontend)

Step 2: Verify Google + Submit (Backend)

Why poll in Step 2? The Google TXT record is added during Step 1, but DNS propagation takes time. By polling in Step 2 (after the user completes the CNAME switch), we give DNS more time to propagate. The backend polls every 10 seconds for up to 2 minutes.
Google verification failure is non-blocking. If it fails, the domain is still connected and IndexNow submission still runs. Only GSC sitemap submission is skipped.

Database Columns

The ai_sites table stores Google verification state:

Troubleshooting

”Missing Google OAuth credentials”

Check that all three environment variables are set:
  • GOOGLE_CLIENT_ID_GSC
  • GOOGLE_CLIENT_SECRET_GSC
  • GOOGLE_REFRESH_TOKEN_GSC_ADMIN_1

”Failed to get access token”

The refresh token may be invalid. Re-run the OAuth Playground flow to get a new one.

”Domain verification failed”

  1. Check that the TXT record was added correctly
  2. DNS propagation can take up to 48 hours (usually 5-30 minutes)
  3. Verify the TXT record with: dig TXT example.com

”Failed to add site to Search Console”

The domain may already be verified by another account. Check Search Console manually.