Learn · Setup guides
Connect Google Search Console to Outloop
Last updated:
In short
Google Search Console uses OAuth, not an API key.
You create one Google Cloud OAuth client, authorize the Search Console scope, and exchange it for a refresh token. Outloop stores the OAuth credential locally in macOS Keychain, pins it to the exact Search Console property, and lets agents use it only through the API Bridge — minting short-lived access tokens host-side, so the agent never sees the Google token.
What this setup gives you
You will create one Google Cloud OAuth client, generate a Search Console refresh token, pin the exact Search Console property into Outloop, and run a first proof through your agent. Outloop stores the OAuth credential locally and uses it through the API Bridge — the agent never sees the refresh token or access token.
client_secret, refresh_token,
access_token, Authorization header, or Bearer token. Their only destination is
the Outloop Mac app — never Outloop Cloud, the website, chat, docs, or .env files.
What you need before starting
- ✓Access to a Google Cloud project.
- ✓Access to the relevant Google Search Console property.
- ✓Outloop installed and activated, with a workspace selected.
Which Google account connects what
Three separate identities — keep them apart
Most failed Google Search Console setups are one confusion: assuming the Google account that manages the Cloud project is also the account that can open the client's verified Search Console property. It does not have to be, and often should not be.
- 1
The Google Cloud project and OAuth app
This owns the Client ID and Client Secret. It can belong to your agency or to your client — Outloop does not care which, and cannot tell the difference.
cloud-admin@agency.example— manages the Google Cloud project - 2
The connected Google account
This is the account you pick in Google's own chooser during the browser sign-in. It is the account that must actually own or be able to open the client's verified Search Console property.
data-owner@client.example— is chosen at sign-in because it owns the client's verified Search Console property - 3
Outloop workspace access
This decides which workspace may use the stored credential, which resources it may reach, and which capabilities agents get. It is set in the Access Profile, after the sign-in succeeds.
In that example, cloud-admin@agency.example
created the OAuth app once, and every connector after it reuses that app — but the account you
actually sign in as is data-owner@client.example,
because that is the identity Google Search Console will check when an agent asks for a file.
- →If the app's audience is External and it is still in Testing, the account must be added as a Test user first.
- →If the audience is Internal, only accounts inside that Google Workspace organisation can sign in at all.
- →The Search Console API must be enabled in the Google Cloud project the app belongs to.
- →The account must genuinely have access to the client's verified Search Console property. A successful sign-in proves identity, not reach.
1. Enable the Search Console API
In Google Cloud Console, open your project, then go to APIs & Services → Library and search Google Search Console API.
Open the result and click Enable.
2. Create an OAuth client (once, for all Google connectors)
Go to APIs & Services → Credentials, then Create credentials → OAuth client ID.
Choose Application type: Web application, name it Outloop Search Console OAuth, leave Authorized JavaScript origins empty, and under Authorized redirect URIs add the OAuth Playground URL:
https://developers.google.com/oauthplayground
Click Create, then copy the Client ID and Client secret from the dialog.
3. Find your exact Search Console property
This is the step people get wrong. Open Google Search Console, click the property dropdown, and check whether the property is a Domain property or a URL-prefix property. The label is shown right under the property name.
Enter it in Outloop in the matching format:
Domain property → sc-domain:yourdomain.com (e.g. sc-domain:outloop.co) URL-prefix property → https://yourdomain.com/ (exact URL, with trailing slash)
https:// and any trailing slash.
4. Add Google Search Console in Outloop
In Outloop, open API Access → Add an API key and choose Google Search Console. Use Agency-global / shared when the same Google user can access multiple properties and you want to grant workspaces over time — tick the workspaces that should use it. Outloop still pins the credential to the specific Search Console property you enter.
You only enter the Google OAuth app once
The first Google connector you set up asks for the Client ID and Client Secret from your Google Cloud OAuth client. Tick save as my default Google OAuth app and every later Google connector — Gmail, Drive, Analytics GA4, Sheets and Google Ads — picks it from the Google OAuth app dropdown with no Client Secret to re-enter. When a saved profile supplies the app, Outloop shows “Using <client-id> — no Client Secret needed. This connector still signs in separately and gets its own access.”
Reusing the app does not mean sharing one login. Each connector still opens its own browser sign-in and gets its own refresh token, its own scopes and its own connected account — so you can revoke or re-authenticate one connector without touching the others.
Shared agency app or workspace-dedicated?
Which setup should I choose?
There are two reasonable answers for Google Search Console, and the right one depends on who owns the Google Cloud infrastructure — not on how many clients you have.
Agency-global (shared OAuth app)
One OAuth app your agency owns, reused by every Google connector you add. This is the default and the right choice for most agencies.
- ✓Client ID and Client Secret entered once, then picked from a dropdown.
- ✓Every connector still runs its own Google sign-in.
- ✓Each one gets its own scopes, its own refresh token, its own connected account and its own revocation.
- ✓Reusing the app grants no data access by itself — workspace grants and Access Profiles stay explicit.
Workspace-dedicated
A separate OAuth client — or a separate Google Cloud project — for one workspace or one client.
- →The client owns the Google Cloud infrastructure and wants to keep owning it.
- →They need stronger administrative separation, or their own consent branding and audience rules.
- →They want separate quotas and their own lifecycle control.
- →The client verified the property themselves and wants the OAuth app inside their own Google Cloud project.
A separate Google Cloud project is the strongest operational separation. A separate OAuth client inside the same project is lighter separation — useful, but the project is still shared.
5. Connect the account in your browser
The panel opens on Connect in your browser, with the Cloud Console detail in the collapsed Setup details — Google Cloud OAuth client, scopes and caveats and Before you connect disclosures. Under Access to request from Google, choose the access level — the full option is preselected and its label ends in (recommended), and read-only is available but never preselected. Check the Google OAuth app dropdown; a saved profile supplies the app with no Client Secret to re-enter.
Click Connect Google Search Console in your browser. Google's own sign-in opens, you sign in with the account that verifies the property, and you approve the consent screen there. Outloop mints and stores the refresh token host-side — nothing to copy or paste.
6. Confirm the account and capabilities
Outloop shows Connected as the Google account you used — check it before an agent reads client search data. Under Agents will be able to (change any time in the Access profile), practical capabilities are pre-checked and destructive ones are prefixed ⚠ and left unchecked. Click Confirm — this is the approved account.
7. Enable the bridge and set the safe read path
OAuth is not the finish line — the Access Profile is
When Google Search Console hands you back to Outloop, the connector is authenticated but not yet authorized. Agents cannot use it until you make the authorization decision yourself:
- OAuth connected
- Confirm the account
- Open the Access Profile
- Approve the property URL
- Choose capabilities
- Save the Access Profile
- Copy the proof prompt
In the Access Profile you set two things. Reach — the one approved entry under Search Console property that this workspace may use. And capabilities — what agents may actually do inside it, with anything destructive left off unless you turn it on.
After setup, click View in stored keys. The row confirms the
credential is stored in macOS Keychain with secret_exposed: false.
On the key row, the bridge is bound to https://www.googleapis.com.
If Outloop asks for a safe read path, set it to a read-only Search
Console endpoint, then click Copy workspace run prompt:
/webmasters/v3/sites
The safe read path gives the agent a first safe GET request. It is a path only — never a secret, and no key re-paste.
8. Run the first proof
Paste the workspace run prompt into your agent. The first proof verifies Search Console access through Outloop:
GET /webmasters/v3/sites
A successful, verified Outloop proof looks like this:
decision / code: allow / OK HTTP status: 200 service: google_search_console secret_exposed: false GSC identity: siteEntry[].siteUrl = sc-domain:yourdomain.com runtime-verified: yes
The setup is complete when the proof shows runtime-verified: yes
and secret_exposed: false. Your agent can now use
Google Search Console through Outloop; the Google OAuth credential stays in macOS Keychain, and the agent
never sees the refresh token or access token.
Advanced — manual refresh token
Skip this if the browser connect worked. It stays documented because it still works, and because some teams prefer to mint the refresh token themselves. In the Outloop panel it sits behind the collapsed Advanced — manual refresh token disclosure.
Get a refresh token from the OAuth Playground
Open developers.google.com/oauthplayground, click the gear icon, and set: OAuth flow Server-side, Access type Offline, Force prompt Consent Screen, and check Use your own OAuth credentials. Paste the Client ID and Client secret (do not screenshot the pasted secret).
In Step 1, paste the Search Console scope and click Authorize APIs:
https://www.googleapis.com/auth/webmasters.readonly
webmasters.readonly if the workspace should only
ever report, or webmasters to match the
read + write tier Outloop preselects. A manual token authorized for a narrower scope than the tier selected in
Outloop fails at request time, not at setup time — which is a confusing place to discover it.
After approving the Google consent screen, OAuth Playground returns to Step 2. Click
Exchange authorization code for tokens and copy the
refresh_token (do not screenshot or publish it).
Paste the values into Outloop
Paste the values you collected, then click Save pasted refresh token:
- →Client ID and Client Secret from Google Cloud.
- →Refresh Token from the OAuth Playground.
- →Search Console property —
sc-domain:yourdomain.comorhttps://yourdomain.com/. - →OAuth scope — two tiers are offered. Read-only — Search Analytics + URL Inspection covers reporting work and is the smaller blast radius. Read + write — also approved sitemap submit / site add (recommended) is the tier Outloop preselects, because submitting a sitemap is ordinary agency work. Pick read-only deliberately if agents should only ever report.
What bites people about the Search Console API
Search Console is a reporting API with real shape constraints, and agents that treat it like a database produce confident, wrong summaries. These are worth putting in the agent's instructions up front.
The data is incomplete on purpose, and the API tells you where
The dataState parameter decides what you get:
final (the default) returns only finalised data,
all also returns fresh data still being processed,
and hourly_all adds an hourly breakdown with
partial data. When fresh data is included, the response carries
first_incomplete_date (or
first_incomplete_hour) marking where the numbers
stop being trustworthy. An agent that ignores that field will report a traffic cliff that is really just
today's data not having landed yet.
You get the top rows, not all the rows
rowLimit accepts 1 to 25,000 and defaults to
1,000 — so an agent that omits it silently truncates at a thousand
rows and then totals them as if they were everything. Page with
startRow (zero-based; past the end it returns
success with no rows). And Google is explicit that the API "does not guarantee to return all data rows but
rather top ones" — a query-level sum from this API is not a site total, and should never be presented to a
client as one.
The property string has to match exactly
A Domain property is sc-domain:example.com; a
URL-prefix property is https://example.com/,
trailing slash included. They are different properties with different data, and the pin Outloop holds is the
literal string. A mismatch is not a permission problem — it is a different property that this account may
genuinely not have.
Changing the account or the credential later
Changing the account or the credential later
Three controls on the Google Search Console connector look similar and do different things. Picking the wrong one is the most common way a working connector gets broken on purpose.
Re-authenticate
Reuses the OAuth app you already selected and refreshes the authorization for the account that is already connected.
When: Use it when the refresh token expired or was revoked and you want the same account back.
Safety: It must not quietly become an account switch. If Outloop finds a different account at the other end, it reports the mismatch and keeps the previous token.
Connect as a different Google account
Keeps the same Client ID and Client Secret and opens Google's account chooser so you can pick another identity.
When: Use it when the wrong account was connected, or when the client moved the data to a different Google account.
Safety: The stored token is replaced only after Outloop positively verifies that the newly connected identity is the one you intended. A mismatch, a missing identity, a failed verification or a cancelled sign-in all leave the previous credential exactly as it was.
Replace the full credential
Swaps the OAuth app itself — a different Google Cloud project, Client ID or Client Secret.
When: Use it when the OAuth app is changing hands, or a client is moving the connector onto their own Cloud project.
Safety: This is not the same as choosing another Google data account. Confirm with "Sign in and replace" only when you actually mean to change the app.
Verified vs not claimed yet
- Verified Search Console read access through Outloop:
GET /webmasters/v3/sitesreturned HTTP 200 with decision allow, an audit entry, the property identity (siteEntry[].siteUrl), andsecret_exposed: false. - Supported, not verified yet Broader write/inspection actions under the wider
webmastersscope: permitted through bridge policy when authorized, but not runtime-verified in this guide.
Troubleshooting
Google shows an account chooser
Expected. Outloop asks Google for the chooser on purpose, so a sign-in can never silently reuse whichever account your browser happened to be logged into. Pick the account that owns or can open the client's verified Search Console property — which is often not the account that manages the Google Cloud project.
“Google hasn’t verified this app”
This appears because the OAuth app is your own and has not been through Google's verification. If it is your app and you trust it, expand Advanced and continue. If you do not know who owns the app, stop — that warning is doing its job, and clicking past an unknown app is not a routine step.
Which audience the app uses decides who can get that far at all. An External app in Testing only admits accounts added as Test users. An Internal app only admits accounts inside its Google Workspace organisation. For customer-facing production use, complete Google's verification rather than living in Testing.
The wrong Google account got connected
Use Connect as a different Google account on the connector. It keeps the same Client ID and Client Secret and reopens Google's chooser. The stored token is only replaced once Outloop verifies the new identity is the intended one — if it does not match, Outloop reports the mismatch and keeps the previous credential. Nothing is lost by trying.
A credential that works but sits on the wrong account is deliberately not marked runtime-verified for that workspace. Working and correct are different things.
BACKEND_AUTH_FAILED during connect
Google rejected the sign-in, so the new credential failed Outloop's safe verification. The important part: the previous credential is unchanged. Do not delete the connector, the OAuth app or the workspace as a first move. Check, in this order — that you signed in as the account that can reach the client's verified Search Console property; that the account is admitted by the app's audience (a Test user on an External+Testing app); and that the API is enabled in the right Cloud project. Then try the connect again.
Reconnecting never asked for the Client ID and Secret
Expected. Disconnecting a Google Search Console credential does not delete your saved Google OAuth app profile — that is a separate object, kept on purpose so later connectors do not re-enter a Client Secret. Outloop reused it. If you specifically want a different app, pick another saved profile from the Google OAuth app dropdown, or create a new one and save it alongside. This is reuse working, not a stale credential silently retained.
“Copy workspace run prompt” is not available
The Access Profile has not been saved yet. Open the Access Profile, choose the reach and the capabilities, and click Save Access Profile — the run prompt becomes available once the authorization is recorded. OAuth succeeding is not the same as the workspace being authorized, and this is the step that closes the gap.
The connection stops working after about a week
If the OAuth app's audience is External and its publishing status is still Testing, Google expires refresh tokens for that app after roughly seven days. Two honest options: publish the app to In production, or use an Internal audience if everyone signing in is inside your Google Workspace organisation. Publishing may require Google's verification review depending on the scopes the app requests — that is Google's process and its outcome and timing are not ours to promise.
I do not see a refresh token
In the OAuth Playground, confirm Use your own OAuth credentials is checked, Access type is Offline, Force prompt is Consent Screen, and the redirect URI in Google Cloud is exactly https://developers.google.com/oauthplayground. Then authorize again.
Outloop says the property is wrong
Check the Search Console dropdown. If it says Domain property, use sc-domain:yourdomain.com (e.g. sc-domain:outloop.co). If it says URL-prefix property, use the exact URL shown, e.g. https://outloop.co/.
The proof returns 403
Usually the Google user who created the refresh token does not have access to that Search Console property, or the wrong OAuth scope was authorized. Confirm the user's Search Console access and that you authorized webmasters.readonly.
The proof shows a config issue
Check that the Search Console API is enabled, the client ID and secret are correct, the refresh token is pasted, the property is exact, and the safe read path is set to /webmasters/v3/sites if Outloop asks for it.
Adding another Search Console property
Reuse the same Google Cloud project and OAuth client if the same Google user has access. In Outloop, add another Google Search Console entry or assign the shared connector to the right workspace, and always pin the correct property — sc-domain:domain.com for a Domain property, or the exact URL for a URL-prefix property.
Rotate or revoke access
- →Move a workspace off a property — change the pinned property string and save. The workspace's reach changes immediately; the credential is untouched.
- →Rotate the token — use Re-authenticate on the connector. Same account, fresh authorization.
- →Revoke everything for this connector — remove the Search Console credential in Outloop, then revoke Outloop's access for that account at myaccount.google.com/permissions. Do both: removing the local credential does not revoke the grant at Google.
- →Off-boarding a client — also ask them to remove the connected address from the property's users in Search Console. Revoking on your side does not remove that account's standing access on theirs.
Official Google documentation
- →Search Console API reference — searchanalytics.query, sites and sitemaps.
- →Authorizing Search Console API requests — the webmasters scopes and what each permits.
- →Domain vs URL-prefix properties — why the property string has to match exactly.
- →Using OAuth 2.0 to access Google APIs — refresh-token behaviour, including the Testing-status expiry.
Outloop is available with guided onboarding for agency teams. Outloop is an independent tool and is not affiliated with or endorsed by Google. See the security model, the Google Ads API setup guide, or connect any custom API.
Once the read proof succeeds, your agent can use Google Search Console through Outloop — without seeing the OAuth token.
Outloop is available with guided onboarding for AI agencies, operators, and dev shops.