A practical guide to accessing your GSC data programmatically. OAuth setup, code examples, rate limits, and common pitfalls.
https://www.googleapis.com/auth/webmasters.readonlyUse webmasters scope (without readonly) if you need write access for sitemaps.
The GSC API uses OAuth 2.0 for authentication. You'll need to implement the OAuth flow to get access tokens for your users (or yourself).
Note: Service accounts don't work well with GSC. You need OAuth with user consent to access Search Console data.
Access tokens expire after 1 hour. Store the refresh token securely and use it to get new access tokens when needed.
pip install google-api-python-client google-auth-oauthlibfrom googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
# Setup credentials (from your OAuth flow)
creds = Credentials.from_authorized_user_file('token.json')
service = build('searchconsole', 'v1', credentials=creds)
# Query for last 7 days
request = {
'startDate': '2025-01-01',
'endDate': '2025-01-07',
'dimensions': ['query'],
'rowLimit': 100
}
response = service.searchanalytics().query(
siteUrl='https://example.com',
body=request
).execute()
for row in response.get('rows', []):
query = row['keys'][0]
clicks = row['clicks']
impressions = row['impressions']
print(f"{query}: {clicks} clicks, {impressions} impressions")# Get all sites you have access to
site_list = service.sites().list().execute()
for site in site_list.get('siteEntry', []):
print(site['siteUrl'], site['permissionLevel'])npm install googleapisconst { google } = require('googleapis');
// Setup OAuth2 client with your credentials
const oauth2Client = new google.auth.OAuth2(
CLIENT_ID,
CLIENT_SECRET,
REDIRECT_URI
);
// Set credentials (from your OAuth flow)
oauth2Client.setCredentials({
access_token: 'your-access-token',
refresh_token: 'your-refresh-token'
});
const searchconsole = google.searchconsole({
version: 'v1',
auth: oauth2Client
});
// Query search analytics
const response = await searchconsole.searchanalytics.query({
siteUrl: 'https://example.com',
requestBody: {
startDate: '2025-01-01',
endDate: '2025-01-07',
dimensions: ['query'],
rowLimit: 100
}
});
response.data.rows?.forEach(row => {
console.log(row.keys[0], row.clicks, row.impressions);
});| Limit | Value |
|---|---|
| Queries per day | 50,000 per project |
| Queries per second | ~5 QPS recommended |
| Rows per request | 25,000 max |
GSC data is 2-3 days behind. Don't query for today or yesterday — you'll get incomplete data or nothing at all.
The siteUrl format matters:
sc-domain:example.comhttps://example.com/ (with trailing slash)High-traffic sites may return sampled data. The totals won't match what you see in the GSC UI exactly.
You can't combine all dimensions in one query. For example, you can't get query + page + country + device all at once.
Site URLs in API requests must be URL-encoded. Use encodeURIComponent() in JavaScript or urllib.parse.quote() in Python.
Building your own GSC dashboard is a great learning project. But if you just want aggregated data across multiple properties without maintaining code, there are alternatives.
Connects to your GSC via OAuth and shows all your properties in one dashboard. No API code to maintain, no rate limit handling, no token refresh logic.
Try SearchBird FreeOr keep building your own solution — both are valid choices depending on your needs.