Comprehensive SEO Analysis Workflow

Advanced SEO analysis with technical audit, keyword research, backlink analysis, and competitor comparison

Back
Workflow Information

ID: seo_analysis_v1

Namespace: default

Version: 2.1.0

Created: 2025-07-07

Updated: 2025-07-07

Tasks: 5

Quick Actions
Manage Secrets
Inputs
Name Type Required Default
target_url string Required None
target_keywords array Required None
analysis_depth string Optional standard
location_name string Optional United States
Outputs
Name Type Source
seo_score string Overall SEO health score (0-100)
seo_report string Complete SEO analysis report with actionable recommendations
domain_analysis string Domain structure and URL analysis
technical_audit string Technical SEO assessment with performance metrics and score
keyword_insights string Keyword research with search volume and competition data
Tasks
keyword_overview
mcp

No description

technical_assessment
script

No description

domain_analysis
script

No description

generate_seo_report
ai_agent

No description

store_results
storage

No description

YAML Source
id: seo_analysis_v1
name: SEO Analysis Workflow
tasks:
- id: keyword_overview
  type: mcp
  tool_name: dataforseo_labs_google_keyword_overview
  retry_policy:
    max_attempts: 3
    initial_interval: 3
  deployment_id: pod-ow0pvk2h
  tool_arguments:
    keywords: ${target_keywords}
    language_code: en
    location_name: ${location_name}
  timeout_seconds: 90
- id: technical_assessment
  type: script
  script: "import json\nimport re\nimport os\nfrom urllib.parse import urlparse\n\
    import requests\n\ndef perform_technical_analysis():\n    target_url = \"${target_url}\"\
    \n    results = {\n        \"url_analysis\": {},\n        \"accessibility_check\"\
    : {},\n        \"seo_fundamentals\": {},\n        \"performance_metrics\": {},\n\
    \        \"recommendations\": [],\n        \"score\": 0\n    }\n    \n    # URL\
    \ Analysis\n    parsed_url = urlparse(target_url)\n    results[\"url_analysis\"\
    ] = {\n        \"is_https\": parsed_url.scheme == \"https\",\n        \"url_length\"\
    : len(target_url),\n        \"has_www\": parsed_url.netloc.startswith(\"www.\"\
    ),\n        \"path_structure\": parsed_url.path,\n        \"domain\": parsed_url.netloc\n\
    \    }\n    \n    # Basic HTTP check with performance metrics\n    try:\n    \
    \    response = requests.get(target_url, timeout=15, allow_redirects=True)\n \
    \       results[\"accessibility_check\"] = {\n            \"status_code\": response.status_code,\n\
    \            \"response_time_seconds\": round(response.elapsed.total_seconds(),\
    \ 2),\n            \"redirects_count\": len(response.history),\n            \"\
    final_url\": response.url,\n            \"content_type\": response.headers.get('content-type',\
    \ 'unknown')\n        }\n        \n        # Performance analysis\n        results[\"\
    performance_metrics\"] = {\n            \"response_time_ms\": round(response.elapsed.total_seconds()\
    \ * 1000, 0),\n            \"content_size_bytes\": len(response.content),\n  \
    \          \"content_size_kb\": round(len(response.content) / 1024, 1),\n    \
    \        \"has_gzip\": 'gzip' in response.headers.get('content-encoding', ''),\n\
    \            \"server\": response.headers.get('server', 'unknown')\n        }\n\
    \        \n        # Basic SEO checks\n        content = response.text.lower()\n\
    \        results[\"seo_fundamentals\"] = {\n            \"has_title\": bool(re.search(r'<title.*?</title>',\
    \ content)),\n            \"has_meta_description\": bool(re.search(r'<meta.*?name=[\"\
    \\']description[\"\\']', content)),\n            \"has_h1\": bool(re.search(r'<h1.*?</h1>',\
    \ content)),\n            \"has_canonical\": bool(re.search(r'<link.*?rel=[\"\\\
    ']canonical[\"\\']', content)),\n            \"has_robots_meta\": bool(re.search(r'<meta.*?name=[\"\
    \\']robots[\"\\']', content)),\n            \"has_viewport\": bool(re.search(r'<meta.*?name=[\"\
    \\']viewport[\"\\']', content)),\n            \"content_length\": len(content),\n\
    \            \"word_count\": len(content.split())\n        }\n        \n     \
    \   # Extract actual title and meta description\n        title_match = re.search(r'<title[^>]*>(.*?)</title>',\
    \ response.text, re.IGNORECASE | re.DOTALL)\n        results[\"seo_fundamentals\"\
    ][\"title_text\"] = title_match.group(1).strip() if title_match else \"\"\n  \
    \      \n        meta_desc_match = re.search(r'<meta[^>]*name=[\"\\']description[\"\
    \\'][^>]*content=[\"\\']([^\"\\']*)[\"\\']', response.text, re.IGNORECASE)\n \
    \       results[\"seo_fundamentals\"][\"meta_description_text\"] = meta_desc_match.group(1).strip()\
    \ if meta_desc_match else \"\"\n        \n    except Exception as e:\n       \
    \ results[\"accessibility_check\"] = {\"error\": str(e), \"accessible\": False}\n\
    \        results[\"seo_fundamentals\"] = {\"error\": \"Could not analyze content\"\
    }\n        results[\"performance_metrics\"] = {\"error\": \"Could not measure\
    \ performance\"}\n    \n    # Calculate SEO score\n    score = 0\n    if results[\"\
    url_analysis\"][\"is_https\"]:\n        score += 15\n    if results[\"accessibility_check\"\
    ].get(\"status_code\") == 200:\n        score += 10\n    if results[\"performance_metrics\"\
    ].get(\"response_time_ms\", 10000) < 2000:\n        score += 10\n    if results[\"\
    seo_fundamentals\"].get(\"has_title\"):\n        score += 15\n    if results[\"\
    seo_fundamentals\"].get(\"has_meta_description\"):\n        score += 10\n    if\
    \ results[\"seo_fundamentals\"].get(\"has_h1\"):\n        score += 10\n    if\
    \ results[\"seo_fundamentals\"].get(\"has_canonical\"):\n        score += 10\n\
    \    if results[\"seo_fundamentals\"].get(\"has_viewport\"):\n        score +=\
    \ 10\n    if results[\"seo_fundamentals\"].get(\"word_count\", 0) > 300:\n   \
    \     score += 10\n    \n    results[\"score\"] = score\n    \n    # Generate\
    \ specific recommendations\n    if not results[\"url_analysis\"][\"is_https\"\
    ]:\n        results[\"recommendations\"].append({\n            \"type\": \"security\"\
    ,\n            \"priority\": \"critical\",\n            \"issue\": \"No HTTPS\"\
    ,\n            \"recommendation\": \"Implement SSL certificate and redirect HTTP\
    \ to HTTPS\"\n        })\n        \n    if results[\"accessibility_check\"].get(\"\
    status_code\") != 200:\n        results[\"recommendations\"].append({\n      \
    \      \"type\": \"technical\",\n            \"priority\": \"critical\",\n   \
    \         \"issue\": f\"HTTP {results['accessibility_check'].get('status_code')}\
    \ error\",\n            \"recommendation\": \"Fix server response issues\"\n \
    \       })\n        \n    if results[\"performance_metrics\"].get(\"response_time_ms\"\
    , 0) > 3000:\n        results[\"recommendations\"].append({\n            \"type\"\
    : \"performance\",\n            \"priority\": \"high\",\n            \"issue\"\
    : \"Slow page load\",\n            \"recommendation\": f\"Optimize server response\
    \ time (currently {results['performance_metrics'].get('response_time_ms')}ms)\"\
    \n        })\n        \n    if not results[\"seo_fundamentals\"].get(\"has_title\"\
    ):\n        results[\"recommendations\"].append({\n            \"type\": \"seo\"\
    ,\n            \"priority\": \"critical\",\n            \"issue\": \"Missing title\
    \ tag\",\n            \"recommendation\": \"Add descriptive title tag to every\
    \ page\"\n        })\n        \n    if not results[\"seo_fundamentals\"].get(\"\
    has_meta_description\"):\n        results[\"recommendations\"].append({\n    \
    \        \"type\": \"seo\",\n            \"priority\": \"high\",\n           \
    \ \"issue\": \"Missing meta description\",\n            \"recommendation\": \"\
    Add compelling meta description (150-160 characters)\"\n        })\n        \n\
    \    if not results[\"seo_fundamentals\"].get(\"has_h1\"):\n        results[\"\
    recommendations\"].append({\n            \"type\": \"seo\",\n            \"priority\"\
    : \"high\",\n            \"issue\": \"Missing H1 tag\",\n            \"recommendation\"\
    : \"Add single, descriptive H1 heading tag\"\n        })\n    \n    if not results[\"\
    seo_fundamentals\"].get(\"has_viewport\"):\n        results[\"recommendations\"\
    ].append({\n            \"type\": \"mobile\",\n            \"priority\": \"high\"\
    ,\n            \"issue\": \"Missing viewport meta tag\",\n            \"recommendation\"\
    : \"Add viewport meta tag for mobile responsiveness\"\n        })\n    \n    return\
    \ results\n\nanalysis_results = perform_technical_analysis()\nprint(f\"__OUTPUTS__\
    \ {json.dumps(analysis_results)}\")\n"
  depends_on:
  - keyword_overview
  requirements:
  - requests==2.31.0
  - urllib3==2.0.4
- id: domain_analysis
  type: script
  script: "import json\nimport requests\nfrom urllib.parse import urlparse\n\ndef\
    \ analyze_domain():\n    target_url = \"${target_url}\"\n    parsed_url = urlparse(target_url)\n\
    \    domain = parsed_url.netloc.replace(\"www.\", \"\")\n    \n    results = {\n\
    \        \"domain\": domain,\n        \"analysis\": {\n            \"domain_age_estimate\"\
    : \"unknown\",\n            \"subdomain_structure\": \"www\" if parsed_url.netloc.startswith(\"\
    www.\") else \"root\",\n            \"url_structure\": {\n                \"scheme\"\
    : parsed_url.scheme,\n                \"path_length\": len(parsed_url.path),\n\
    \                \"has_trailing_slash\": parsed_url.path.endswith(\"/\"),\n  \
    \              \"clean_urls\": \"/\" not in parsed_url.path[1:] if parsed_url.path\
    \ else True\n            }\n        },\n        \"recommendations\": []\n    }\n\
    \    \n    # Check for common SEO-friendly URL patterns\n    if len(parsed_url.path)\
    \ > 100:\n        results[\"recommendations\"].append(\"Consider shorter URL paths\
    \ for better SEO\")\n    \n    if not parsed_url.scheme == \"https\":\n      \
    \  results[\"recommendations\"].append(\"Implement HTTPS for security and SEO\
    \ benefits\")\n    \n    return results\n\ndomain_results = analyze_domain()\n\
    print(f\"__OUTPUTS__ {json.dumps(domain_results)}\")\n"
  depends_on:
  - technical_assessment
  requirements:
  - requests==2.31.0
- id: generate_seo_report
  type: ai_agent
  prompt: "Generate a comprehensive SEO analysis report for ${target_url} based on\
    \ the available data:\n\nTARGET INFORMATION:\n- URL: ${target_url}\n- Keywords:\
    \ ${target_keywords}\n- Location: ${location_name}\n- Analysis Depth: ${analysis_depth}\n\
    \nKEYWORD ANALYSIS DATA:\n${keyword_overview}\n\nTECHNICAL ASSESSMENT:\n${technical_assessment}\n\
    \nDOMAIN ANALYSIS:\n${domain_analysis}\n\nPlease create a detailed SEO analysis\
    \ report with the following sections:\n\n# SEO Analysis Report for ${target_url}\n\
    \n## Executive Summary\n- Overall SEO Health Score: ${technical_assessment.score}/100\n\
    - Website Status: ${technical_assessment.accessibility_check.status_code} response\n\
    - Response Time: ${technical_assessment.performance_metrics.response_time_ms}ms\n\
    - Key findings and recommendations\n\n## Keyword Performance Analysis\nBased on\
    \ the keyword data provided:\n- Analyze search volume for each keyword\n- Competition\
    \ level assessment\n- Commercial intent and opportunities\n- Monthly search trends\n\
    - Keyword difficulty analysis\n\n## Technical SEO Assessment\nBased on the technical\
    \ analysis:\n- HTTPS Status: ${technical_assessment.url_analysis.is_https}\n-\
    \ Page Performance: ${technical_assessment.performance_metrics.response_time_ms}ms\
    \ load time\n- Content Size: ${technical_assessment.performance_metrics.content_size_kb}KB\n\
    - Essential SEO Elements:\n  - Title Tag: ${technical_assessment.seo_fundamentals.has_title}\n\
    \  - Meta Description: ${technical_assessment.seo_fundamentals.has_meta_description}\n\
    \  - H1 Tag: ${technical_assessment.seo_fundamentals.has_h1}\n  - Canonical Tag:\
    \ ${technical_assessment.seo_fundamentals.has_canonical}\n  - Viewport Meta: ${technical_assessment.seo_fundamentals.has_viewport}\n\
    \n## Content Analysis\n- Word Count: ${technical_assessment.seo_fundamentals.word_count}\
    \ words\n- Content Quality Assessment\n- Structure and readability evaluation\n\
    \n## Critical Issues & Recommendations\nList all recommendations from technical\
    \ assessment with priorities:\n${technical_assessment.recommendations}\n\n## Action\
    \ Plan\n\n### Phase 1: Critical Fixes (Immediate - 1 week)\n- Address any critical\
    \ security or accessibility issues\n- Fix missing essential SEO elements\n\n###\
    \ Phase 2: Performance Optimization (2-4 weeks)\n- Improve page load speed if\
    \ needed\n- Optimize content structure\n- Enhance meta tags\n\n### Phase 3: Content\
    \ & Keyword Strategy (1-3 months)\n- Develop content strategy around target keywords\n\
    - Optimize for search intent\n- Build topical authority\n\n## Success Metrics\n\
    - Target SEO score: 85+/100\n- Page load time: <2 seconds\n- Keyword ranking improvements\n\
    - Traffic increase projections\n\nFormat the report with specific, actionable\
    \ recommendations based on the actual data provided. Include exact numbers and\
    \ metrics where available.\n"
  agent_type: seo_specialist
  depends_on:
  - keyword_overview
  - technical_assessment
  - domain_analysis
  model_client_id: seo_analyzer
- id: store_results
  data:
    keywords: ${target_keywords}
    location: ${location_name}
    seo_score: ${technical_assessment.score}
    seo_report: ${generate_seo_report}
    target_url: ${target_url}
    analyzed_at: ${execution.started_at}
    domain_data: ${domain_analysis}
    workflow_id: ${workflow.id}
    execution_id: ${execution.id}
    keyword_data: ${keyword_overview}
    analysis_depth: ${analysis_depth}
    technical_data: ${technical_assessment}
  type: storage
  table: seo_analysis_results
  operation: insert
  depends_on:
  - generate_seo_report
inputs:
- name: target_url
  type: string
  required: true
  validation:
    pattern: ^https?://.+
  description: Website URL to analyze (e.g., https://example.com)
- name: target_keywords
  type: array
  required: true
  validation:
    max_items: 5
    min_items: 1
  description: List of keywords to analyze (max 5)
- enum:
  - quick
  - standard
  - comprehensive
  name: analysis_depth
  type: string
  default: standard
  description: Analysis depth level
- name: location_name
  type: string
  default: United States
  description: Target location for SEO analysis
outputs:
  seo_score:
    source: technical_assessment.score
    description: Overall SEO health score (0-100)
  seo_report:
    source: generate_seo_report
    description: Complete SEO analysis report with actionable recommendations
  domain_analysis:
    source: domain_analysis
    description: Domain structure and URL analysis
  technical_audit:
    source: technical_assessment
    description: Technical SEO assessment with performance metrics and score
  keyword_insights:
    source: keyword_overview
    description: Keyword research with search volume and competition data
version: 2.1.0
description: Robust SEO analysis with graceful error handling and AI-powered insights
model_clients:
- id: seo_analyzer
  config:
    model: gpt-4o-mini
    api_key: ${env.OPENAI_API_KEY}
    max_tokens: 3000
    temperature: 0.4
  provider: openai
Execution ID Status Started Duration Actions
9c2b3d8d... COMPLETED 2025-07-07
10:23:32
N/A View
aeab745f... COMPLETED 2025-07-07
10:22:04
N/A View
c0dfe71f... COMPLETED 2025-07-07
10:21:12
N/A View
4fc2160b... COMPLETED 2025-07-07
10:18:24
N/A View
1d750526... COMPLETED 2025-07-07
10:17:17
N/A View
84fc682e... COMPLETED 2025-07-07
10:15:59
N/A View