SKILL.md
Google SEO APIs
Google's own APIs are the ground truth for how Google sees a site: real Chrome user metrics, real indexation status, real search performance. All free tiers. Detect what credentials exist, state what that unlocks, and never present lab data as field data.
Credential tiers
Check credentials before promising anything. Expect an API key in $GOOGLE_API_KEY and, for authenticated APIs, a service account JSON at $GOOGLE_APPLICATION_CREDENTIALS.
| Tier | Requires | Unlocks |
|---|---|---|
| 0 | API key only | PageSpeed Insights, CrUX + CrUX History, YouTube Data, Knowledge Graph, Web Risk, Cloud NLP (needs billing enabled) |
| 1 | + service account or OAuth | Search Console (Search Analytics, URL Inspection, Sitemaps), Indexing API |
| 2 | + GA4 property ID | GA4 organic traffic and landing page reports |
| 3 | + Ads developer token and customer ID | Keyword Planner ideas and volume |
Always state the detected tier and list what is unavailable before running anything. For Tier 1, the service account's client_email must be added as a user on the Search Console property.
Task routing
| Question | API | Tier |
|---|---|---|
| Real-user Core Web Vitals now | CrUX API | 0 |
| CWV trend over ~25 weeks | CrUX History API | 0 |
| Lab audit plus field data | PageSpeed Insights v5 | 0 |
| Clicks, impressions, CTR, position | GSC Search Analytics | 1 |
| Is this URL actually indexed | GSC URL Inspection | 1 |
| Sitemap submission status | GSC Sitemaps | 1 |
| Push a JobPosting/Broadcast URL to Google | Indexing API | 1 |
| Organic sessions and landing pages | GA4 Data API | 2 |
| Video SEO research | YouTube Data API | 0 |
| Entity and E-E-A-T analysis | Cloud Natural Language | 0 |
| Brand entity presence | Knowledge Graph Search | 0 |
| Malware/social engineering flags | Web Risk | 0 |
| Keyword volume, gold standard | Ads Keyword Planner | 3 |
Read references/api-catalog.md for endpoints, request shapes, quotas, and per-API gotchas before calling anything.
Workflow
- Detect tier, state it.
- Route the question with the table above. Prefer the cheapest sufficient API.
- Call the API with defaults: last 28 days for GSC and GA4, both mobile and desktop for PSI, US/en where locale applies.
- Interpret honestly. CrUX 404 means insufficient Chrome traffic, not an error, fall back to PSI lab data and label it lab. GSC data lags 2-3 days, say so. Sitemap reports show submitted counts, only URL Inspection proves indexation.
- Report: traffic-light ratings for CWV (Good / Needs Improvement / Poor at p75), tables for query data, a data-freshness note, and quick wins (GSC queries at position 4-10 with high impressions).
Hard rules
- INP replaced FID as the responsiveness metric. Never report FID.
- The Indexing API is officially limited to JobPosting and BroadcastEvent/VideoObject pages, 200 publish requests per day. Tell the user before submitting anything else.
- URL Inspection is capped at 2,000 inspections per property per day, batch accordingly.
- On 429, back off exponentially and report which API throttled.
Verification
Run curl -s "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=<URL>&key=$GOOGLE_API_KEY" | head -c 300. Expect JSON starting with lighthouse/loadingExperience fields. A 400 with API_KEY_INVALID means the key is bad; a 403 means the API is not enabled on the Cloud project. Fix credentials before running any analysis.
Good vs bad
Good: "Field LCP is 3.1s at p75 (CrUX, 28-day window). Lab LCP is 1.8s, the gap suggests slow real-world networks or cache misses. Fix priority: field data." Bad: "Lighthouse says LCP 1.8s so Core Web Vitals pass." Lab data does not decide CWV assessment, field data does.
Footguns
- CrUX 404 read as failure. It means the URL lacks sufficient Chrome traffic. Fall back to origin-level CrUX, then PSI lab data, and label which you used.
- Service account added to GCP but not GSC. API calls 403 until the
client_emailis added under the Search Console property's user settings. This is the most common Tier 1 setup failure. - CLS arrives string-encoded from CrUX. Parse "0.05" to a float before comparing thresholds.
- Treating sitemap "submitted" as "indexed". Submitted counts come from the sitemap report; indexation truth requires URL Inspection per URL.
Completion checklist
- [ ] Tier detected and stated before any promise
- [ ] Field vs lab data labeled on every metric
- [ ] Data freshness noted (GSC lag, CrUX 28-day window)
- [ ] Quotas respected, no blind batch loops
- [ ] Quick-win queries surfaced when GSC data was pulled
- [ ] Report saved as GOOGLE-API-REPORT-<domain>.md when the user wants an artifact
Any box unchecked: not done. Fix or say so.