Technical SEO Audit

Comprehensive technical SEO audit workflow that analyzes website health, performance, and optimization opportunities

Back
Workflow Information

ID: technical_seo_audit_v2

Namespace: default

Version: 2.0.0

Created: 2025-07-07

Updated: 2025-07-07

Tasks: 11

Quick Actions
Manage Secrets
Inputs
Name Type Required Default
target_url string Required None
audit_depth string Optional standard
crawl_limit integer Optional 50
Outputs
Name Type Source
score string Overall SEO health score (0-100)
audit_report string Complete Technical SEO Audit Report
critical_issues string List of critical issues found
recommendations string AI-generated recommendations
Tasks
parse_url
script

No description

analyze_page
mcp

No description

parse_content
mcp

No description

get_serp_data
mcp

No description

domain_overview
mcp

No description

ranked_keywords
mcp

No description

backlink_analysis
mcp

No description

process_audit_data
script

No description

generate_recommendations
ai_agent

No description

compile_report
script

No description

store_results
storage

No description

YAML Source
id: technical_seo_audit_v2
name: Technical SEO Audit
tasks:
- id: parse_url
  type: script
  script: "import json\nfrom urllib.parse import urlparse\nimport os\n\ntarget_url\
    \ = os.environ.get('target_url', '')\nparsed = urlparse(target_url)\n\nresult\
    \ = {\n    \"domain\": parsed.netloc,\n    \"scheme\": parsed.scheme,\n    \"\
    path\": parsed.path or \"/\",\n    \"base_url\": f\"{parsed.scheme}://{parsed.netloc}\"\
    ,\n    \"is_homepage\": parsed.path in [\"\", \"/\"]\n}\n\nprint(f\"__OUTPUTS__\
    \ {json.dumps(result)}\")\n"
  timeout_seconds: 10
- id: analyze_page
  type: mcp
  tool_name: on_page_instant_pages
  depends_on:
  - parse_url
  retry_policy:
    max_attempts: 3
    initial_interval: 5
  deployment_id: pod-ow0pvk2h
  tool_arguments:
    url: ${target_url}
    accept_language: en-US
    enable_javascript: true
  timeout_seconds: 120
- id: parse_content
  type: mcp
  tool_name: on_page_content_parsing
  depends_on:
  - parse_url
  retry_policy:
    max_attempts: 2
  deployment_id: pod-ow0pvk2h
  tool_arguments:
    url: ${target_url}
    enable_javascript: true
  timeout_seconds: 90
- id: get_serp_data
  type: mcp
  when: audit_depth != 'basic'
  tool_name: serp_organic_live_advanced
  depends_on:
  - analyze_page
  retry_policy:
    max_attempts: 2
  deployment_id: pod-ow0pvk2h
  tool_arguments:
    depth: 10
    keyword: ${parse_content.items[0].meta.title || parse_url.domain}
    language_code: en
    location_name: United States
    search_engine: google
  timeout_seconds: 60
- id: domain_overview
  type: mcp
  when: audit_depth != 'basic'
  tool_name: dataforseo_labs_google_domain_rank_overview
  depends_on:
  - parse_url
  retry_policy:
    max_attempts: 2
  deployment_id: pod-ow0pvk2h
  tool_arguments:
    target: ${parse_url.domain}
    language_code: en
    location_name: United States
  timeout_seconds: 90
- id: ranked_keywords
  type: mcp
  when: audit_depth == 'comprehensive'
  tool_name: dataforseo_labs_google_ranked_keywords
  depends_on:
  - parse_url
  deployment_id: pod-ow0pvk2h
  tool_arguments:
    limit: 20
    target: ${parse_url.domain}
    language_code: en
    location_name: United States
  timeout_seconds: 120
- id: backlink_analysis
  type: mcp
  when: audit_depth == 'comprehensive'
  tool_name: backlinks_summary
  depends_on:
  - parse_url
  deployment_id: pod-ow0pvk2h
  tool_arguments:
    target: ${parse_url.domain}
  timeout_seconds: 90
- id: process_audit_data
  type: script
  script: "import json\nimport os\nfrom datetime import datetime\n\n# Get data from\
    \ previous tasks\ntry:\n    page_analysis = json.loads(os.environ.get('analyze_page',\
    \ '{}'))\n    content_data = json.loads(os.environ.get('parse_content', '{}'))\n\
    \    domain_overview = json.loads(os.environ.get('domain_overview', '{}'))\nexcept:\n\
    \    page_analysis = {}\n    content_data = {}\n    domain_overview = {}\n\n#\
    \ Extract key metrics with safe navigation\ntry:\n    on_page_result = page_analysis.get('tasks',\
    \ [{}])[0].get('result', [{}])[0]\n    items = on_page_result.get('items', [{}])[0]\n\
    except:\n    items = {}\n\n# Basic metrics\nmetrics = {\n    \"url\": items.get('url',\
    \ ''),\n    \"status_code\": items.get('status_code', 0),\n    \"load_time\":\
    \ items.get('page_timing', {}).get('time_to_secure_connection', 0),\n    \"size\"\
    : items.get('size', 0),\n    \"encoded_size\": items.get('encoded_size', 0),\n\
    \    \"total_transfer_size\": items.get('total_transfer_size', 0),\n    \"is_https\"\
    : items.get('meta', {}).get('charset', {}).get('scheme', '') == 'https'\n}\n\n\
    # SEO elements\nmeta = items.get('meta', {})\nhtags = meta.get('htags', {})\n\n\
    seo_elements = {\n    \"title\": meta.get('title', ''),\n    \"title_length\"\
    : meta.get('title_length', 0),\n    \"description\": meta.get('description', ''),\n\
    \    \"description_length\": meta.get('description_length', 0),\n    \"canonical\"\
    : meta.get('canonical', ''),\n    \"robots\": meta.get('robots', ''),\n    \"\
    og_properties\": meta.get('open_graph', {}),\n    \"h1_count\": len(htags.get('h1',\
    \ [])),\n    \"h2_count\": len(htags.get('h2', [])),\n    \"images_without_alt\"\
    : meta.get('images_without_alt', [])\n}\n\n# Technical checks\nchecks = items.get('checks',\
    \ {})\n\n# Issues and warnings\nissues = []\nwarnings = []\n\n# Check for critical\
    \ issues\nif metrics['status_code'] != 200:\n    issues.append(f\"Page returns\
    \ {metrics['status_code']} status code\")\n\nif not metrics['is_https']:\n   \
    \ issues.append(\"Site is not using HTTPS\")\n\nif not seo_elements['title']:\n\
    \    issues.append(\"Missing page title\")\nelif seo_elements['title_length']\
    \ > 60:\n    warnings.append(f\"Title too long ({seo_elements['title_length']}\
    \ chars, recommended: <60)\")\nelif seo_elements['title_length'] < 30:\n    warnings.append(f\"\
    Title too short ({seo_elements['title_length']} chars, recommended: 30-60)\")\n\
    \nif not seo_elements['description']:\n    issues.append(\"Missing meta description\"\
    )\nelif seo_elements['description_length'] > 160:\n    warnings.append(f\"Description\
    \ too long ({seo_elements['description_length']} chars, recommended: <160)\")\n\
    elif seo_elements['description_length'] < 120:\n    warnings.append(f\"Description\
    \ too short ({seo_elements['description_length']} chars, recommended: 120-160)\"\
    )\n\nif seo_elements['h1_count'] == 0:\n    issues.append(\"Missing H1 tag\")\n\
    elif seo_elements['h1_count'] > 1:\n    warnings.append(f\"Multiple H1 tags found\
    \ ({seo_elements['h1_count']})\")\n\nif len(seo_elements['images_without_alt'])\
    \ > 0:\n    warnings.append(f\"{len(seo_elements['images_without_alt'])} images\
    \ missing alt text\")\n\n# Performance warnings\nif metrics['load_time'] and metrics['load_time']\
    \ > 3000:\n    warnings.append(f\"Slow load time ({metrics['load_time']/1000:.1f}s)\"\
    )\n\nif metrics['total_transfer_size'] and metrics['total_transfer_size'] > 3000000:\n\
    \    warnings.append(f\"Large page size ({metrics['total_transfer_size']/1048576:.1f}MB)\"\
    )\n\n# Domain metrics (if available)\ndomain_metrics = {}\nif domain_overview:\n\
    \    try:\n        domain_data = domain_overview.get('tasks', [{}])[0].get('result',\
    \ [{}])[0]\n        domain_metrics = {\n            \"organic_keywords\": domain_data.get('metrics',\
    \ {}).get('organic', {}).get('count', 0),\n            \"organic_traffic\": domain_data.get('metrics',\
    \ {}).get('organic', {}).get('etv', 0),\n            \"paid_keywords\": domain_data.get('metrics',\
    \ {}).get('paid', {}).get('count', 0),\n            \"paid_traffic\": domain_data.get('metrics',\
    \ {}).get('paid', {}).get('etv', 0)\n        }\n    except:\n        pass\n\n\
    # Compile audit results\naudit_results = {\n    \"audit_date\": datetime.now().isoformat(),\n\
    \    \"target_url\": os.environ.get('target_url'),\n    \"metrics\": metrics,\n\
    \    \"seo_elements\": seo_elements,\n    \"technical_checks\": checks,\n    \"\
    domain_metrics\": domain_metrics,\n    \"issues\": issues,\n    \"warnings\":\
    \ warnings,\n    \"score\": max(0, 100 - len(issues) * 15 - len(warnings) * 5)\n\
    }\n\nprint(f\"__OUTPUTS__ {json.dumps(audit_results)}\")\n"
  depends_on:
  - analyze_page
  - parse_content
  requirements:
  - beautifulsoup4==4.12.2
  timeout_seconds: 30
- id: generate_recommendations
  type: ai_agent
  prompt: 'Analyze this Technical SEO Audit data and provide actionable recommendations:


    Audit Results:

    ${process_audit_data}


    Provide:

    1. Executive Summary (2-3 sentences)

    2. Critical Issues to Fix Immediately

    3. High Priority Recommendations

    4. Quick Wins (easy fixes with high impact)

    5. Long-term Optimization Opportunities


    Format your response as structured JSON with these sections.

    '
  agent_type: analyst
  depends_on:
  - process_audit_data
  model_client_id: seo_analyzer
  timeout_seconds: 60
- id: compile_report
  type: script
  script: "import json\nimport os\nfrom datetime import datetime\n\naudit_data = json.loads(os.environ.get('process_audit_data',\
    \ '{}'))\nrecommendations = json.loads(os.environ.get('generate_recommendations',\
    \ '{}'))\n\n# Create comprehensive report\nreport = {\n    \"report_metadata\"\
    : {\n        \"title\": \"Technical SEO Audit Report\",\n        \"generated_at\"\
    : datetime.now().isoformat(),\n        \"target_url\": os.environ.get('target_url'),\n\
    \        \"audit_depth\": os.environ.get('audit_depth', 'standard')\n    },\n\
    \    \"executive_summary\": {\n        \"overall_score\": audit_data.get('score',\
    \ 0),\n        \"critical_issues\": len(audit_data.get('issues', [])),\n     \
    \   \"warnings\": len(audit_data.get('warnings', [])),\n        \"summary\": recommendations.get('executive_summary',\
    \ '')\n    },\n    \"technical_analysis\": {\n        \"performance_metrics\"\
    : audit_data.get('metrics', {}),\n        \"seo_elements\": audit_data.get('seo_elements',\
    \ {}),\n        \"technical_checks\": audit_data.get('technical_checks', {}),\n\
    \        \"domain_authority\": audit_data.get('domain_metrics', {})\n    },\n\
    \    \"issues_and_warnings\": {\n        \"critical_issues\": audit_data.get('issues',\
    \ []),\n        \"warnings\": audit_data.get('warnings', [])\n    },\n    \"recommendations\"\
    : recommendations,\n    \"next_steps\": [\n        \"Fix critical issues identified\
    \ in the report\",\n        \"Implement quick wins for immediate improvements\"\
    ,\n        \"Plan long-term optimization based on recommendations\",\n       \
    \ \"Re-run audit after implementing changes to measure improvement\"\n    ]\n\
    }\n\nprint(f\"__OUTPUTS__ {json.dumps(report)}\")\n"
  depends_on:
  - process_audit_data
  - generate_recommendations
  timeout_seconds: 20
- id: store_results
  data:
    warnings: ${compile_report.executive_summary.warnings}
    audit_date: ${execution.started_at}
    target_url: ${target_url}
    full_report: ${compile_report}
    workflow_id: ${workflow.id}
    execution_id: ${execution.id}
    overall_score: ${compile_report.executive_summary.overall_score}
    critical_issues: ${compile_report.executive_summary.critical_issues}
  type: storage
  table: seo_audit_results
  operation: insert
  depends_on:
  - compile_report
inputs:
- name: target_url
  type: string
  required: true
  validation:
    pattern: ^https?://[\w\-\.]+(\.[\w\-]+)+.*$
  description: The website URL to audit (e.g., https://example.com)
- enum:
  - basic
  - standard
  - comprehensive
  name: audit_depth
  type: string
  default: standard
  description: 'Depth of audit: basic, standard, or comprehensive'
- name: crawl_limit
  type: integer
  default: 50
  validation:
    maximum: 500
    minimum: 10
  description: Maximum number of pages to crawl
outputs:
  score:
    source: compile_report.executive_summary.overall_score
    description: Overall SEO health score (0-100)
  audit_report:
    source: compile_report
    description: Complete Technical SEO Audit Report
  critical_issues:
    source: compile_report.issues_and_warnings.critical_issues
    description: List of critical issues found
  recommendations:
    source: generate_recommendations
    description: AI-generated recommendations
version: 2.0.0
description: Comprehensive technical SEO audit workflow that analyzes website health,
  performance, and optimization opportunities
model_clients:
- id: seo_analyzer
  config:
    model: gpt-4o-mini
    api_key: ${env.OPENAI_API_KEY}
  provider: openai
Execution ID Status Started Duration Actions
543e4a5f... COMPLETED 2025-07-07
09:02:59
N/A View
50aa0465... COMPLETED 2025-07-07
08:34:49
N/A View
e2713561... COMPLETED 2025-07-07
08:17:55
N/A View