---
sharksapi_version: p-cdea55ac73
name: seo-audit
description: Perform an SEO/GEO audit using SharksAPI data sources — including a SERP top-10 competitor benchmark (keyword usage, intent, schema, speed, backlinks) — produce a prioritized strategy card with actionable tasks, and optionally execute them.
allowed-tools: [get_gsc_top_queries, get_gsc_top_pages, get_gsc_brand_queries, analyze_pagespeed, analyze_schema, get_ga4, get_ga4_channels, get_bing_webmaster, search_serp_google, keyword_search_volume, scrape_website, backlinks_summary, create_dashboard, update_dashboard, update_strategy_task, get_strategy_status]
---

# SEO / GEO Audit & Strategy

## When to use

User says things like: "do an SEO audit", "find SEO improvements", "create SEO strategy for this week", "audit our search performance", "GEO audit".

## Phase 1: Data Collection

Call these tools via A2A to gather the raw data. Use the last 30 days as default range.

1. **Search performance**: `get_gsc_top_queries` (limit: 20) + `get_gsc_top_pages` (limit: 20)
2. **Brand vs non-brand**: `get_gsc_brand_queries` (brand_keyword: company name)
3. **Bing search**: `get_bing_webmaster` (if connected -- check `get_analytics_summary` first)
4. **Traffic & engagement**: `get_ga4` (aggregate: true) + `get_ga4_channels`
5. **Technical**: `analyze_pagespeed` on the top 3 landing pages
6. **Schema**: `analyze_schema` on the homepage + top landing page

## Phase 2: SERP Top-10 Benchmark

Measure who actually ranks and why, so tasks target the real gap — not guesses.
Requires the **DataForSEO** connection (`search_serp_google` / `backlinks_summary`);
if it is not connected, note that in the report and skip to Phase 3.

**2a. Pick 3-5 priority keywords.** Combine: the main money keyword (ask the user
if unclear), the highest-impression GSC queries at position 5-20, and one
brand-adjacent query. Optionally validate with `keyword_search_volume` (batch)
so you benchmark keywords people actually search.

**2b. Pull the SERP** for each keyword: `search_serp_google` (depth: 10; default
location Estonia 2233 / `et` — change to the client's market). Record position,
URL, title, domain for all 10.

**2c. Classify intent** per keyword from the SERP composition: informational
(guides, blogs), commercial (comparisons, "best X"), transactional (product/
service pages), local (maps, local providers). If the client's page type does
not match the dominant intent, that is a task in itself — content type beats
on-page tweaks.

**2d. Measure the top pages.** For the top 5 organic results per keyword,
`scrape_website` with `extract: ["text", "meta", "headings"]`, then compute per page:

- **Title**: keyword present? exact or partial match? at the start of the title?
- **Headings**: keyword in H1 (should be once); count of keyword mentions across H2/H3
- **Keyword density**: occurrences in body text ÷ total word count, as % (typical winners: 0.5-2%)
- **Word count** of the main content
- Note recurring page patterns: FAQ blocks, tables, calculators, videos

**2e. Schema & speed** on the top 3 results per keyword: `analyze_schema` (which
types do winners use — FAQPage, Product, LocalBusiness, Article?) and
`analyze_pagespeed` (their scores vs. yours — is speed actually a differentiator here?).

**2f. Authority gap**: `backlinks_summary` on each **unique** domain in the
top 10 (dedupe first — do not call per URL) and on the client's own domain.
Compare referring domains + rank score.

**Call budget**: ~5 keywords × (1 SERP + 5 scrapes) + ≤15 schema/speed calls +
≤10 unique-domain backlink calls. Batch what you can; do not scrape the same URL twice.

**2g. Output a benchmark table** (goes into the strategy card content):

```
| # | Page | Kw in title | Kw in H1/H2s | Density | Words | Schema | Speed | Ref.domains |
|---|------|-------------|--------------|---------|-------|--------|-------|-------------|
| 1 | competitor.ee/x | yes, start | H1 + 4×H2 | 1.4% | 1850 | FAQ+Service | 78 | 412 |
| — | OUR PAGE | partial | H1 only | 0.3% | 420 | none | 61 | 37 |
```

End with a gap summary: what do the top 3 consistently have that the client's page lacks?

## Phase 3: Analysis

From the collected data, identify:

- **Quick wins**: Pages with high impressions but low CTR (>1000 impressions, <2% CTR) -- fix meta titles/descriptions
- **Technical issues**: PageSpeed score <70, missing schema, large images, no HTTPS
- **Content gaps**: Queries where position is 5-20 (page 1-2 potential) -- expand content on those topics
- **Competitor gaps** (from Phase 2): intent mismatch, thinner content than the top 3, missing schema types winners use, keyword absent from title/H1, authority shortfall
- **Brand health**: Brand click share % -- is it growing or stagnant?
- **Cannibalization**: Multiple pages ranking for the same query
- **Missing pages**: High-impression queries with no dedicated landing page

## Phase 4: Strategy Card Creation

Create a `strategy_card` widget on the user's dashboard with the top 10 prioritized tasks.

**Set dashboard password:** Ask the user for a dashboard password (required — `create_dashboard` rejects requests without one). Pass it via the `password` field.

```json
{
  "tool": "update_dashboard",
  "arguments": {
    "token": "{dashboard_token}",
    "add_widgets": [{
      "type": "strategy_card",
      "title": "SEO Strategy -- Week {N}",
      "position": 0,
      "grid_cols": 12,
      "content": "## SEO Audit Summary\n\n{your analysis}\n\n### SERP Benchmark — {keyword}\n{benchmark table from Phase 2g}\n\n### Data Sources\n- GSC: {clicks} clicks, {impressions} impressions\n- Brand share: {pct}%\n- PageSpeed: {score}/100 (top-3 avg: {competitor score})\n- Backlinks: {our ref.domains} vs top-3 avg {their ref.domains}",
      "source": {
        "mode": "human_controlled",
        "tasks": [
          {"title": "Improve meta description for /page -- CTR is 1.2% with 3.4K impressions", "description": "Current: '...' Suggested: '...'"},
          {"title": "Add FAQ schema to /page", "description": "All top-3 competitors for '{keyword}' use FAQPage schema; we have none. Target rich snippet."},
          {"title": "Expand /page from 420 to ~1500 words", "description": "Top-3 average 1850 words with keyword density 1.4%; our page is 420 words at 0.3%. Add sections: {from competitor heading patterns}."}
        ]
      }
    }]
  }
}
```

## Phase 5: Execution (if AI-controlled)

If mode is `ai_controlled`, execute tasks that can be done programmatically:

- **Schema fixes**: Use `analyze_schema` to validate after changes
- **Re-index requests**: Note in task -- actual submission requires GSC UI
- **PageSpeed follow-up**: Re-run `analyze_pagespeed` after optimization
- **Mark tasks done**: `update_strategy_task` with `is_completed: true`

After executing, call `get_strategy_status` to report progress.

## Phase 6: Weekly Follow-up

When repeating next week:

1. Call `get_strategy_status` on last week's card -- see what's done
2. Collect fresh data (Phase 1)
3. Create a NEW strategy card for the new week
4. Reference last week: "Last week: 7/10 tasks completed. Remaining: ..."
5. Don't repeat completed tasks -- build on progress

## Task Prioritization

1. Intent mismatch on a priority keyword (wrong page type ranks — fix beats everything else)
2. High-impression low-CTR pages (meta title/description fix)
3. Technical errors (broken links, 404s, missing canonical, schema)
4. Schema types the top-3 use and we lack (from Phase 2e)
5. Core Web Vitals failures (LCP, CLS, FID) — prioritize if top-3 are measurably faster
6. Content expansion for position 5-20 queries — size against the top-3 word count/density benchmark
7. New content for high-impression queries with no landing page
8. Authority building if referring-domain gap vs top-3 is >3× (hand off to backlink outreach)
9. Brand optimization if brand share is declining
