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
Current Setup
Adding a New Admin Account
When you reach ~900 sites onadmin_1, itβs time to add admin_2@searchcompany.co.
Step 1: Create the Google Account
- Create a new Google Workspace account:
admin_2@searchcompany.co - 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.- Go to OAuth Playground
- Click the gear icon (βοΈ) β Check βUse your own OAuth credentialsβ
- Enter the existing
GOOGLE_CLIENT_ID_GSCandGOOGLE_CLIENT_SECRET_GSC - Select scopes:
https://www.googleapis.com/auth/siteverificationhttps://www.googleapis.com/auth/webmasters
- Click βAuthorize APIsβ
- Sign in as
admin_2@searchcompany.co(not admin_1) - Grant permissions
- Click βExchange authorization code for tokensβ
- Copy the Refresh Token
Step 3: Add Environment Variable
Add the new refresh token to your.env:
Step 4: Update the Code
ModifyBackend/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 toai_sites table to track which account owns each site:
Token Refresh Behavior
The refresh token stays valid as long as:- Used at least once every 6 months - Our daily cron (sitemap resubmission) handles this automatically
- User doesnβt revoke access - Only if someone logs into the Google account and revokes app access
- 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
Theai_sites table stores Google verification state:
Troubleshooting
βMissing Google OAuth credentialsβ
Check that all three environment variables are set:GOOGLE_CLIENT_ID_GSCGOOGLE_CLIENT_SECRET_GSCGOOGLE_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β
- Check that the TXT record was added correctly
- DNS propagation can take up to 48 hours (usually 5-30 minutes)
- Verify the TXT record with:
dig TXT example.com