Claude Training Program · Week 3 · Build Track

Building API-Powered SEO Tools:
Real Data, Automated Reports

📖 Tutorial 6 of 8 ⏱ 2–3 hours 👥 Build Track — all levels 🎯 Prerequisites: Tutorials 3 & 4

The tools we've built so far work with files you provide manually. This tutorial goes further: connecting directly to external APIs so your tools can pull live data automatically. You'll build two real tools — a PageSpeed Insights batch checker and a Google Search Console data puller — and learn the universal technique for working with any API using Claude Code.

Learning Objectives
  • Understand what APIs are and how to authenticate with them
  • Learn how to give Claude Code API documentation to work with
  • Store API keys securely using environment variables
  • Build a PageSpeed Insights batch checker with CSV output
  • Build a Search Console data puller that surfaces declining queries
  • Know how to adapt this pattern to any API you encounter

1Understanding APIs — The Short Version

New to APIs? An API (Application Programming Interface) is a way for your script to talk to another service over the internet. Instead of you opening a browser and clicking around in PageSpeed Insights manually, your script sends a request directly to Google's servers and gets the data back — instantly, for hundreds of URLs at once.

🔑
API Key

A secret password that proves to the API who you are. Never share it or commit it to code. We store it in a separate config file.

📡
API Request

Your script asks the API a question — e.g. "give me the PageSpeed score for this URL" — and the API sends data back as JSON.

📦
JSON Response

The format most APIs return data in. It's structured text that Python can easily read. Claude Code handles all the parsing for you.

⏱️
Rate Limits

Most APIs restrict how many requests you can make per second or per day. Our scripts include delays to stay within limits.

2Storing API Keys Safely

The golden rule: never put an API key directly in your code. If you share the script or accidentally push it to a shared drive, your key is exposed. Instead, we use a .env file — a simple text file that stores secrets separately from your code.

Setting up your .env file

seo-tools/
├── .env # API keys — NEVER share this file
├── .gitignore # Tells git to ignore .env
├── scripts/
└── data/
# .env — secret keys, one per line
# Do not share this file or commit it anywhere
GOOGLE_API_KEY=AIzaSyABC123yourkeyhere
GSC_CREDENTIALS_FILE=config/gsc_credentials.json

How to tell Claude Code about your keys: You never paste your actual API keys into the Claude Code conversation. Instead, tell Claude Code: "API keys are stored in a .env file. Use the python-dotenv library to load them — never hardcode them." Claude Code will write the correct loading code automatically.

Terminal — create .gitignore to protect your keys
# Create a .gitignore to protect your .env file $ echo ".env" >> .gitignore $ echo "config/*.json" >> .gitignore

3The Universal Technique — Giving Claude API Documentation

Claude Code was trained on a huge amount of code and API documentation, so it already knows many popular APIs. But for any API, the best approach is to paste the relevant section of the official documentation directly into your opening prompt. This removes any ambiguity and ensures Claude uses the exact endpoints, parameters, and response formats that the API currently supports.

How to find and use API documentation

Find the official docs

Search "[API name] documentation" — e.g. "PageSpeed Insights API documentation". Always use the official Google/provider source, not third-party tutorials.

Find the relevant endpoint

Look for a "Reference" or "API Reference" section. Find the endpoint that does what you need — e.g. "run pagespeed" or "query search analytics".

Copy the key sections

Copy the: endpoint URL, required parameters, authentication method, and example response JSON. You don't need the full docs page — just the relevant sections.

Paste into your Claude Code prompt

Include it in a clearly labelled section of your opening prompt: "Here is the relevant API documentation: [paste]". Claude Code will write code that matches it exactly.

Tool 1 — PageSpeed Insights Batch Checker
API Core Web Vitals

What it does

Takes a CSV of URLs, calls the PageSpeed Insights API for each one (for both mobile and desktop), and outputs a report showing Core Web Vitals scores, performance category, and the top 3 opportunities for each URL — the kind of report that previously meant opening each URL manually in PageSpeed and copying numbers into a spreadsheet.

Step 1 — Get your Google API key

Go to the Google Cloud Console

Visit console.cloud.google.com and sign in with your Google account.

Create or select a project

Create a new project (e.g. "SEO Tools") or use an existing one.

Enable the PageSpeed Insights API

Go to APIs & Services → Library → search "PageSpeed Insights API" → Enable.

Create an API key

Go to APIs & Services → Credentials → Create Credentials → API key. Copy it and paste it into your .env file as GOOGLE_API_KEY.

Free tier: The PageSpeed Insights API is free up to 25,000 requests per day — more than enough for agency use. No billing setup required for this volume.

Step 2 — The Claude Code prompt

Build a Python script at scripts/pagespeed_checker.py that batch-checks URLs using the PageSpeed Insights API. SETUP - Load the API key from .env using python-dotenv (key name: GOOGLE_API_KEY) - Read URLs from data/urls.csv (column: "url") - API keys must never be hardcoded API DETAILS The PageSpeed Insights API endpoint is: GET https://www.googleapis.com/pagespeedonline/v5/runPagespeed Parameters: - url (required): the page URL to test - key (required): the API key - strategy: "mobile" or "desktop" - category: "performance" (we only need performance for now) Key fields in the response to extract: - lighthouseResult.categories.performance.score (multiply by 100 for 0-100 score) - lighthouseResult.audits["first-contentful-paint"].displayValue - lighthouseResult.audits["largest-contentful-paint"].displayValue - lighthouseResult.audits["total-blocking-time"].displayValue - lighthouseResult.audits["cumulative-layout-shift"].displayValue - The top 3 opportunities: from lighthouseResult.audits, find items where "details.type" == "opportunity", sort by "details.overallSavingsMs" descending, take top 3, extract their "title" and "displayValue" BEHAVIOUR - Check each URL for both mobile and desktop strategy - Add a 1 second delay between API calls (to respect rate limits) - Handle API errors gracefully — log the error and continue to next URL - Show progress: "Checking [url] (mobile)... score: 84" OUTPUT Write two files: 1. output/pagespeed_report.csv — all raw data, one row per URL per strategy Columns: url, strategy, performance_score, fcp, lcp, tbt, cls, opportunity_1, opportunity_2, opportunity_3 2. output/pagespeed_summary.html — a styled HTML report showing: - A table sorted by mobile performance score (worst first) - Score cells colour-coded: green (90+), orange (50-89), red (0-49) - The top opportunities listed under each URL - A summary at the top: average mobile score, average desktop score, count of URLs failing Core Web Vitals After building, test it on 3 URLs from data/urls.csv and show me the results.

Expected output sample

Terminal output while running
Checking https://example.com/ (mobile)...    score: 91
Checking https://example.com/ (desktop)...   score: 97
Checking https://example.com/services (mobile)... score: 44
Checking https://example.com/services (desktop)... score: 78
Checking https://example.com/blog/seo-guide (mobile)... score: 61

✓ Saved raw data to output/pagespeed_report.csv
✓ Saved HTML report to output/pagespeed_summary.html

Summary: avg mobile 65 | avg desktop 84 | 1 URL failing CWV thresholds
      

Useful follow-up improvements

ImprovementFollow-up prompt
Filter to failing URLs only"Add a --failing-only flag that outputs only URLs with mobile score below 50."
Add score trends"Modify the script to load a previous report CSV and add a trend column showing score change since last run."
Slack notification"After the run, send a Slack webhook message summarising the results. The webhook URL should come from .env as SLACK_WEBHOOK_URL."
Tool 2 — Google Search Console Data Puller
OAuth2 Search Analytics

What it does

Connects to the Google Search Console API, pulls query performance data for any property, and surfaces the top declining queries week-over-week — without you having to log into GSC, export CSVs, and compare them manually each week.

Authentication is more complex here. The Search Console API uses OAuth2 (not a simple API key) because it accesses private data. This requires a one-time setup involving a credentials JSON file. The steps below walk through it — it looks intimidating but Claude Code handles all the hard parts once you have the credentials file.

Step 1 — Set up OAuth2 credentials

Enable the Search Console API

In Google Cloud Console, go to APIs & Services → Library → search "Google Search Console API" → Enable.

Create OAuth2 credentials

Go to APIs & Services → Credentials → Create Credentials → OAuth client ID. Choose "Desktop app". Name it "SEO Tools".

Download the credentials file

Click the download icon next to your new OAuth client. Save the downloaded JSON file to seo-tools/config/gsc_credentials.json.

First run — authorise access

The first time you run the script, a browser window will open asking you to grant access to your Google account's Search Console data. After approving, a token is saved locally so you won't need to do this again.

Which account to use? Authorise with the Google account that has access to the GSC properties you want to query. For agency work, you'll typically have a service account or verified access to client properties. Claude Code can be asked to support multiple properties if needed.

Step 2 — The Claude Code prompt

Build a Python script at scripts/gsc_puller.py that pulls Search Console data and surfaces declining queries. AUTHENTICATION - Use the google-auth and google-api-python-client libraries - Load credentials from config/gsc_credentials.json (OAuth2 Desktop credentials) - On first run, open a browser for the user to authorise access - Save the resulting token to config/gsc_token.json so future runs don't need re-authorisation - The credentials and token files must never be hardcoded into the script CONFIGURATION (read from a simple config at the top of the script) - SITE_URL: the GSC property URL (e.g. "https://example.com/") - DAYS_CURRENT: 28 (compare last 28 days...) - DAYS_PREVIOUS: 28 (...against the 28 days before that) - MIN_IMPRESSIONS: 100 (ignore queries with fewer than 100 impressions in either period) - MAX_RESULTS: 200 ANALYSIS Using the Search Console API searchanalytics.query endpoint: - Pull query data for the current period and previous period - For each query present in both periods, calculate: clicks_change (absolute), clicks_change_pct, impressions_change_pct, position_change - Flag queries as DECLINING if clicks are down more than 20% AND impressions are not down proportionally (suggesting a ranking/CTR issue rather than demand drop) - Flag queries as DROPPED if they had impressions in the previous period but zero in the current (potential deindexation or penalty signal) OUTPUT 1. output/gsc_declining.csv — all declining queries sorted by absolute click loss Columns: query, current_clicks, prev_clicks, click_change_pct, current_position, prev_position, position_change, flag 2. output/gsc_summary.txt — a plain text summary containing: - Total queries analysed - Number flagged as DECLINING and total clicks lost - Number flagged as DROPPED - Top 10 declining queries with their click loss Print the summary to the terminal after running as well. After building, run it for the site https://[my-site.com]/ — I'll update the SITE_URL config variable before running.

Sample summary output

output/gsc_summary.txt
GSC Declining Queries Report
Generated: 2026-02-19 | Site: https://example.com/
Period: Last 28 days vs previous 28 days
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Total queries analysed: 187
Declining queries: 23 (total click loss: -412)
Dropped queries:    4

TOP 10 DECLINING QUERIES
━━━━━━━━━━━━━━━━━━━━━━━━
technical seo audit     clicks: 84→41  (-51%)  pos: 3.2→5.8
core web vitals guide   clicks: 67→29  (-57%)  pos: 4.1→7.3
hreflang checker        clicks: 55→38  (-31%)  pos: 6.2→6.8
...
      

Automating weekly runs

Once the script is working, ask Claude Code to help you schedule it to run automatically every Monday morning:

The gsc_puller.py script is working. Help me schedule it to run every Monday at 8am and email the gsc_summary.txt to team@myagency.com. Use the system's built-in scheduler (cron on Mac/Linux). The email credentials should be loaded from .env.

6The Universal Pattern — Applying This to Any API

Every API integration you'll ever build follows the same pattern. Once you've built these two tools, you can apply the same approach to any data source:

StepWhat to doClaude Code's role
1. Get credentialsSign up, create API key or OAuth app in the provider's consoleYou do this manually — credentials can't be automated
2. Store secretsAdd keys to .env fileClaude Code writes the loading code using python-dotenv
3. Find the endpointRead the API docs and find the relevant endpoint + parametersYou paste the docs; Claude Code interprets them
4. Write the integrationDescribe what you want to pull and in what formatClaude Code writes all the request/response handling
5. Handle errorsTell Claude Code what edge cases to handleClaude Code adds try/catch, retries, rate limit delays
6. Format outputSpecify CSV, HTML, JSON, or plain text outputClaude Code writes all the formatting and file writing

Other APIs worth integrating using this same pattern:

  • Ahrefs / Semrush API — pull backlink data or keyword rankings for automated monthly reports
  • Google Analytics 4 (Data API) — pull traffic by landing page to correlate with SEO changes
  • Screaming Frog API — trigger crawls and pull results programmatically (available in Screaming Frog v20+)
  • ValueSERP / SerpAPI — pull SERP features data for tracking rich result ownership

7Practice Exercises

✏️ Exercise 1 — Build the PageSpeed batch checker

Build Tool 1 using the prompt in Section 4:

  1. Get your Google API key from Google Cloud Console and add it to .env
  2. Create a urls.csv with 5–10 URLs from one of your client sites
  3. Open Claude Code in your seo-tools folder and use the prompt from Section 4
  4. Let Claude Code build and run the script — review the HTML report in your browser
  5. Follow up: "Sort the HTML report by mobile score ascending so worst pages appear first"
✏️ Exercise 2 — Build the GSC data puller

Build Tool 2 for one of your GSC properties:

  1. Set up OAuth2 credentials in Google Cloud Console (follow Step 1 in Section 5)
  2. Save the credentials JSON to config/gsc_credentials.json
  3. Use the Claude Code prompt from Section 5
  4. On first run, complete the browser authorisation flow
  5. Review the declining queries output — do the flagged queries match your expectations from manually reviewing GSC?
✏️ Exercise 3 — Apply the pattern to a new API

Choose one additional API and build a simple integration:

  1. Pick an API your team uses: SerpAPI, ValueSERP, Ahrefs, or GA4
  2. Find the relevant API documentation endpoint for the data you want
  3. Copy the key sections (endpoint URL, parameters, example response)
  4. Write a Claude Code prompt using the universal pattern from Section 6
  5. Build, test, and save the script to your scripts/ folder

8Summary

🔑
Keys in .env
Always store API credentials in a .env file — never in your code
📄
Paste the Docs
Give Claude Code the relevant API documentation — it writes exact, working integrations
♻️
One Pattern, Any API
Every API integration follows the same 6-step process — learn it once, apply it everywhere

Key takeaway: API integrations unlock the biggest time savings in SEO tool building — they replace manual data collection entirely. Once the PageSpeed checker and GSC puller are running, tasks that previously took 30–60 minutes of manual work happen in seconds, on a schedule, without anyone touching them.