Skip to main content
SEO Machine uses analytics data to identify content opportunities, track performance, and prioritize updates. This guide covers setting up all three data sources.

Overview

The analytics integrations provide:
  • Google Analytics 4 (GA4): Traffic, engagement, and conversion metrics
  • Google Search Console (GSC): Search performance and keyword rankings
  • DataForSEO: Competitive SEO data and keyword research
These data sources power the /performance-review command and inform content strategy decisions.

Prerequisites

  • Google account with access to GA4 and Search Console properties
  • DataForSEO account (optional, for competitive analysis)
  • Python 3.8+ installed
  • pip package manager

Install Dependencies

1

Install Python packages

From the repository root, install all required dependencies:
pip install -r data_sources/requirements.txt
This installs:
  • google-analytics-data - GA4 API client
  • google-auth-oauthlib - Google authentication
  • google-api-python-client - Search Console API
  • requests - HTTP client for DataForSEO
  • python-dotenv - Environment variable management
  • pandas - Data analysis and manipulation
2

Verify installation

Test that packages are installed correctly:
python3 -c "import google.analytics.data_v1beta; print('GA4 client installed')"
python3 -c "import googleapiclient.discovery; print('Search Console client installed')"

Google Analytics 4 Setup

Create Service Account

1

Create Google Cloud project

  1. Go to Google Cloud Console
  2. Click Select a projectNew Project
  3. Name it “SEO Machine” or similar
  4. Click Create
2

Enable Google Analytics Data API

  1. In your project, go to APIs & ServicesLibrary
  2. Search for “Google Analytics Data API”
  3. Click the API, then click Enable
3

Create service account

  1. Go to APIs & ServicesCredentials
  2. Click Create CredentialsService Account
  3. Name: seo-machine-analytics
  4. Description: “Service account for SEO Machine data access”
  5. Click Create and Continue
  6. Skip role assignment (permissions set in GA4)
  7. Click Done
4

Generate credentials JSON

  1. Click on the service account you just created
  2. Go to the Keys tab
  3. Click Add KeyCreate new key
  4. Select JSON format
  5. Click Create - the JSON file downloads automatically
  6. Save as credentials/ga4-credentials.json in your repository
5

Add service account to GA4

  1. Open Google Analytics
  2. Go to Admin (gear icon, bottom left)
  3. In the Property column, click Property Access Management
  4. Click Add users (+) button
  5. Paste the service account email (found in the JSON file, looks like [email protected])
  6. Select role: Viewer
  7. Uncheck “Notify new users by email”
  8. Click Add
Keep the credentials JSON file secure. Never commit it to version control. It’s already in .gitignore.

Configure GA4 Settings

Add your GA4 configuration to data_sources/config/.env:
# Google Analytics 4
GA4_PROPERTY_ID=123456789
GA4_CREDENTIALS_PATH=credentials/ga4-credentials.json
Find your GA4 Property ID in Analytics: AdminProperty SettingsProperty ID

Google Search Console Setup

1

Enable Search Console API

In the same Google Cloud project:
  1. Go to APIs & ServicesLibrary
  2. Search for “Google Search Console API”
  3. Click the API, then click Enable
2

Use existing service account

You can reuse the same service account created for GA4, or create a new one following the same process.If creating a new service account, save credentials as data_sources/config/gsc_credentials.json.
3

Add service account to Search Console

  1. Go to Google Search Console
  2. Select your property
  3. Click Settings (gear icon, left sidebar)
  4. Click Users and permissions
  5. Click Add user
  6. Paste service account email
  7. Select permission: Full (required for API access)
  8. Click Add

Configure GSC Settings

Add your Search Console configuration to data_sources/config/.env:
# Google Search Console
GSC_SITE_URL=https://yourdomain.com
GSC_CREDENTIALS_PATH=credentials/ga4-credentials.json
The GSC_SITE_URL must exactly match your verified property in Search Console, including https:// or http:// and with or without www.

DataForSEO Setup

DataForSEO provides competitive keyword data, SERP analysis, and ranking tracking.
1

Create DataForSEO account

  1. Sign up at DataForSEO
  2. Verify your email address
  3. Add payment method (pay-per-request pricing)
2

Get API credentials

  1. Log in to DataForSEO dashboard
  2. Go to API Access section
  3. Copy your Login (email)
  4. Copy or generate your Password (API password, not account password)
3

Configure credentials

Add DataForSEO credentials to data_sources/config/.env:
# DataForSEO
[email protected]
DATAFORSEO_PASSWORD=your_api_password
DATAFORSEO_BASE_URL=https://api.dataforseo.com
DataForSEO charges per API request. Enable caching and set budget limits to control costs.

DataForSEO Pricing Overview

Request TypeCost per RequestUse Case
SERP Check$0.006Check top 10 results for a keyword
Ranking Check$0.0005Check your position for a keyword
Keyword Data$0.006Get search volume and difficulty
Competitor Analysis$0.01-0.05Analyze competitor rankings
Cost Management Tips:
  • Enable 24-hour caching (see below)
  • Batch requests for multiple keywords
  • Focus on high-priority keywords only
  • Set monthly budget alerts in DataForSEO dashboard

Cache Configuration

Caching reduces API costs and rate limit issues by storing responses locally.
# Cache Settings
CACHE_ENABLED=true
CACHE_TTL_HOURS=24
  • First API request is made and response stored in data_sources/cache/
  • Subsequent requests for the same data return cached response
  • Cache expires after TTL (time-to-live) period
  • Expired cache automatically refreshes on next request
Clear all cache:
rm -rf data_sources/cache/*
Clear specific source:
rm -rf data_sources/cache/ga4_*
rm -rf data_sources/cache/gsc_*
rm -rf data_sources/cache/dataforseo_*
Check cache size:
du -sh data_sources/cache/
  • After making changes to tracked keywords
  • When you need real-time data (performance review)
  • If seeing stale or incorrect data
  • After significant traffic events

Complete .env Configuration

Your final data_sources/config/.env file should look like:
# Google Analytics 4
GA4_PROPERTY_ID=123456789
GA4_CREDENTIALS_PATH=credentials/ga4-credentials.json

# Google Search Console
GSC_SITE_URL=https://yourdomain.com
GSC_CREDENTIALS_PATH=credentials/ga4-credentials.json

# DataForSEO (optional)
[email protected]
DATAFORSEO_PASSWORD=your_api_password
DATAFORSEO_BASE_URL=https://api.dataforseo.com

# Cache Settings
CACHE_ENABLED=true
CACHE_TTL_HOURS=24

# WordPress Publishing (optional)
WP_SITE_URL=https://yourdomain.com
WP_USERNAME=your_username
WP_APP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx

Test API Connections

Verify each integration is working correctly:
python3 test_dataforseo.py --test ga4
The test_dataforseo.py script validates API credentials and returns sample data to confirm connectivity.

Using Analytics Data

Performance Review Command

Run a comprehensive performance analysis:
/performance-review
This command:
  1. Fetches data from GA4, GSC, and DataForSEO
  2. Identifies declining content
  3. Finds quick-win opportunities (keywords ranking 11-20)
  4. Prioritizes content updates
  5. Suggests new content topics
  6. Generates a detailed report in reports/performance-review-YYYY-MM-DD.md

Python Module Usage

Fetch GA4 Data

from data_sources.modules.google_analytics import GoogleAnalytics

ga = GoogleAnalytics()

# Get top performing articles (last 30 days)
top_articles = ga.get_top_pages(days=30, limit=10)

# Get traffic trends for specific URL
trends = ga.get_page_trends(
    url="/blog/podcast-monetization-guide",
    days=90
)

# Get conversion data
conversions = ga.get_conversions(days=30)

Fetch Search Console Data

from data_sources.modules.google_search_console import GoogleSearchConsole

gsc = GoogleSearchConsole()

# Get keyword rankings
rankings = gsc.get_keyword_positions(days=30)

# Find quick win opportunities (position 11-20)
quick_wins = gsc.get_quick_wins()

# Get specific page performance
page_data = gsc.get_page_performance(
    url="/blog/podcast-monetization-guide"
)

Fetch DataForSEO Data

from data_sources.modules.dataforseo import DataForSEO

dfs = DataForSEO()

# Get keyword rankings
rankings = dfs.get_rankings(
    keywords=["podcast hosting", "podcast analytics"]
)

# Analyze competitor rankings
competitor_data = dfs.analyze_competitor(
    competitor_domain="competitor.com",
    keywords=["podcast hosting"]
)

# Get SERP data
serp = dfs.get_serp_data(keyword="podcast monetization")

Aggregate All Data Sources

from data_sources.modules.data_aggregator import DataAggregator

aggregator = DataAggregator()

# Get comprehensive page performance
performance = aggregator.get_page_performance(
    url="/blog/podcast-monetization-guide"
)

print(performance)
# Returns:
# {
#   'url': '/blog/podcast-monetization-guide',
#   'ga4': {
#     'pageviews': 12500,
#     'avg_engagement_time': 245,
#     'bounce_rate': 0.42
#   },
#   'gsc': {
#     'impressions': 45000,
#     'clicks': 3200,
#     'avg_position': 8.5,
#     'ctr': 0.071
#   },
#   'dataforseo': {
#     'primary_keyword': 'podcast monetization',
#     'position': 8,
#     'search_volume': 2900
#   }
# }

Data-Driven Decisions

SEO Machine uses analytics data to:

Identify Declining Content

  • Articles losing traffic (GA4)
  • Keywords dropping in rankings (GSC + DataForSEO)
  • Increased bounce rates (GA4)

Find Quick Wins

  • Keywords ranking 11-20 (GSC + DataForSEO)
  • High impressions, low CTR (GSC)
  • Competitor keyword gaps (DataForSEO)

Prioritize Updates

  • High-traffic articles with outdated data
  • Page 2 rankings for valuable keywords
  • Content gaps in topic clusters

Suggest New Content

  • Rising search queries (GSC)
  • Competitor content gaps (DataForSEO)
  • Related questions people ask (DataForSEO)

Rate Limits & Quotas

Google Analytics 4

  • Free Tier: 25,000 requests/day per property
  • Standard Properties: Unlimited (within quotas)
  • Cost: Free

Google Search Console

  • Rate Limit: Unlimited (reasonable use)
  • Rows per Request: 1,000 maximum
  • Cost: Free

DataForSEO

  • Pricing: Pay-per-request (see pricing table above)
  • No Rate Limits: Based on account balance
  • Tip: Enable aggressive caching to minimize costs

Troubleshooting

Problem: google.auth.exceptions.DefaultCredentialsErrorSolutions:
  • Verify credentials JSON file exists at specified path
  • Check service account has access to GA4/GSC property
  • Ensure APIs are enabled in Google Cloud Console
  • Confirm service account email is correct
  • Try regenerating credentials JSON
Problem: API returns empty resultsSolutions:
  • Check date ranges (some properties have 24-48 hour data delay)
  • Verify property IDs and site URLs are correct
  • Ensure property has data for requested time period
  • Confirm filters aren’t too restrictive
  • Check that site has traffic in that date range
Problem: 429 Too Many Requests or insufficient balanceSolutions:
  • Enable caching to reduce API calls
  • Increase cache TTL in .env to 24-48 hours
  • Check DataForSEO account balance
  • Reduce number of keywords tracked
  • Batch requests instead of individual calls
Problem: ModuleNotFoundError: No module named 'google'Solutions:
  • Install dependencies: pip install -r data_sources/requirements.txt
  • Check Python path includes data_sources directory
  • Verify using correct Python version (3.8+)
  • Try: python3 -m pip install -r data_sources/requirements.txt
Problem: GA4 returns “Property not found” errorSolutions:
  • Verify GA4_PROPERTY_ID is the numeric property ID, not measurement ID (starts with “G-”)
  • Check service account has Viewer access to property
  • Confirm using correct Google account for property ownership
  • Wait 24 hours after adding service account (propagation delay)

Security Best Practices

NEVER commit credentials to version control!
  • .env files are in .gitignore
  • Credential JSON files are in .gitignore
  • Use service accounts, not user accounts
  • Grant minimum required permissions (Viewer for GA4/GSC)
  • Rotate credentials every 90 days
  • Store credentials in secure password manager
  • Use separate service accounts for production/development

Next Steps

WordPress Integration

Set up WordPress publishing with Yoast SEO metadata

Content Commands

Learn commands that use analytics data for content decisions

Build docs developers (and LLMs) love