Technical SEO Audit
Comprehensive technical SEO audit workflow that analyzes website health, performance, and optimization opportunities
Workflow Information
ID: technical_seo_audit_v1
Namespace: default
Version: 1.0.0
Created: 2025-07-07
Updated: 2025-07-07
Tasks: 11
Quick Actions
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
scriptNo description
analyze_page
mcpNo description
parse_content
mcpNo description
get_serp_data
mcpNo description
domain_overview
mcpNo description
ranked_keywords
mcpNo description
backlink_analysis
mcpNo description
process_audit_data
scriptNo description
generate_recommendations
ai_agentNo description
compile_report
scriptNo description
store_results
storageNo description
YAML Source
id: technical_seo_audit_v1
name: Technical SEO Audit
tasks:
- id: parse_url
type: script
script: "import json\nfrom urllib.parse import urlparse\n\ntarget_url = \"\"\"${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\npage_analysis = json.loads(os.environ.get('analyze_page', '{}'))\n\
content_data = json.loads(os.environ.get('parse_content', '{}'))\ndomain_overview\
\ = json.loads(os.environ.get('domain_overview', '{}'))\n\n# Extract key metrics\n\
on_page_result = page_analysis.get('tasks', [{}])[0].get('result', [{}])[0]\n\
items = on_page_result.get('items', [{}])[0]\n\n# Basic metrics\nmetrics = {\n\
\ \"url\": items.get('url'),\n \"status_code\": items.get('status_code'),\n\
\ \"load_time\": items.get('page_timing', {}).get('time_to_secure_connection'),\n\
\ \"size\": items.get('size'),\n \"encoded_size\": items.get('encoded_size'),\n\
\ \"total_transfer_size\": items.get('total_transfer_size'),\n \"is_https\"\
: items.get('meta', {}).get('htags', {}).get('is_https', False)\n}\n\n# SEO elements\n\
seo_elements = {\n \"title\": items.get('meta', {}).get('title'),\n \"title_length\"\
: items.get('meta', {}).get('title_length'),\n \"description\": items.get('meta',\
\ {}).get('description'),\n \"description_length\": items.get('meta', {}).get('description_length'),\n\
\ \"canonical\": items.get('meta', {}).get('canonical'),\n \"robots\": items.get('meta',\
\ {}).get('robots'),\n \"og_properties\": items.get('meta', {}).get('open_graph',\
\ {}),\n \"h1_count\": len(items.get('meta', {}).get('htags', {}).get('h1',\
\ [])),\n \"h2_count\": len(items.get('meta', {}).get('htags', {}).get('h2',\
\ [])),\n \"images_without_alt\": items.get('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\")\n\
elif 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)\")\nelif 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\")\nelif 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: 1.0.0
description: Comprehensive technical SEO audit workflow that analyzes website health,
performance, and optimization opportunities
model_clients:
seo_analyzer:
model: gpt-4o-mini
api_key: ${env.OPENAI_API_KEY}
provider: openai
| Execution ID | Status | Started | Duration | Actions |
|---|---|---|---|---|
88d8a7c4...
|
COMPLETED |
2025-07-07
08:15:54 |
N/A | View |