# Website SEO Audit (`blank_butter/website-seo-audit`) Actor

Comprehensive SEO audit tool that scans websites for technical SEO issues, content gaps, and optimization opportunities. Get actionable recommendations to improve search rankings.

- **URL**: https://apify.com/blank\_butter/website-seo-audit.md
- **Developed by:** [AI Developer](https://apify.com/blank_butter) (community)
- **Categories:** SEO tools
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Website SEO Audit

A comprehensive SEO audit tool that crawls websites and identifies technical SEO issues, content gaps, and optimization opportunities. **Works without any external API keys** — all core SEO checks use built-in rule engines. Optional AI enhancement available for advanced recommendations.

### Features

#### Core SEO Audit (No API Key Required)
- **Crawl & Scan**: Automatically crawls up to 50 pages of your website
- **Technical SEO Checks**:
  - Title tag length validation (optimal: 10-70 characters)
  - Meta description presence and length (optimal: 50-160 characters)
  - H1 / H2 heading validation and count
  - Canonical tag correctness
  - Image alt text completeness
  - Mobile viewport meta tag detection
  - Robots noindex detection
- **Broken Link Detection**: Checks internal links for 4xx/5xx errors (up to 15 per page)
- **SSL Certificate Analysis**: TLS version, cipher, certificate expiry
- **Security Headers**: HSTS, X-Frame-Options, CSP, Referrer-Policy
- **Open Graph Tags**: Facebook/social sharing meta tags
- **Schema.org Structured Data**: JSON-LD detection
- **Sitemap Discovery**: Via robots.txt
- **Rule-Based Scoring**: 0-100 SEO score calculated from detected issues (no AI needed)

#### Optional AI Enhancement
- **Enhanced Recommendations**: Enable `useAI` for Kimi AI-generated prioritized fix lists and deeper analysis
- Requires `KIMI_API_KEY` environment variable (set in Apify Console)
- When disabled: all scoring and recommendations are generated by built-in rules — faster, zero AI cost, no external dependencies

### Input Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `url` | string | — | **Required.** Website URL to audit (e.g. `https://example.com`) |
| `maxPages` | integer | 10 | Maximum pages to scan (1-50) |
| `checkBrokenLinks` | boolean | true | Check internal links for 4xx/5xx errors |
| `checkMobileFriendly` | boolean | true | Analyze mobile viewport meta tag |
| `useAI` | boolean | **false** | Enable Kimi AI enhancement (requires KIMI_API_KEY). **Default OFF** for zero-cost, stable runs. |

### Output

```json
{
  "overallScore": 72,
  "scoreBreakdown": {
    "onPageSEO": 18,
    "technicalSEO": 20,
    "contentQuality": 19,
    "securityPerformance": 15
  },
  "summary": "Scanned 10 pages, 8 successful, found 12 SEO issues.",
  "priorityFixes": [
    "Fix missing meta descriptions",
    "Add alt text to images",
    "Optimize title tags"
  ],
  "quickWins": [
    "Add Open Graph tags",
    "Include viewport meta tag"
  ],
  "recommendations": [
    "Monitor site structure changes",
    "Regular SEO health checks"
  ],
  "pagesScanned": 10,
  "pagesAccessible": 8,
  "pagesFailed": 2,
  "failedUrls": ["https://example.com/broken"],
  "sslInfo": {
    "hasSSL": true,
    "sslVersion": "TLSv1.3"
  },
  "sitemaps": ["https://example.com/sitemap.xml"],
  "totalIssues": 12,
  "issueBreakdown": {
    "Missing meta description": 5,
    "Missing alt text": 3
  },
  "pageDetails": [
    {
      "url": "https://example.com",
      "title": "Home Page",
      "titleLength": 9,
      "metaDescription": "",
      "metaDescriptionLength": 0,
      "h1": "Welcome",
      "h1Count": 1,
      "h2Count": 3,
      "canonical": "https://example.com",
      "robots": "",
      "imageCount": 12,
      "missingAltCount": 3,
      "internalLinks": 8,
      "brokenLinks": [],
      "openGraph": {"title": "Home Page", "description": ""},
      "schemaOrg": ["WebPage"],
      "schemaOrgCount": 1,
      "securityHeaders": {
        "securityHeaders": {
          "strict-transport-security": "max-age=31536000",
          "x-content-type-options": "nosniff",
          "x-frame-options": "DENY",
          "content-security-policy": "...",
          "referrer-policy": "strict-origin-when-cross-origin"
        },
        "missingHeaders": []
      },
      "issues": [
        "Title 过短 (9 字符)",
        "缺少 meta description",
        "3/12 张图片缺少 alt 文本"
      ]
    }
  ]
}
````

### Use Cases

- **Pre-launch audits**: Check new websites before going live
- **Competitor analysis**: Audit competitor sites for SEO insights
- **Regular monitoring**: Periodic health checks of your web properties
- **SEO agencies**: Batch audits for client onboarding
- **Developers**: Quick technical SEO validation in CI/CD pipelines

### Pricing

This Actor uses **Pay-per-Event** pricing:

- **Actor Start**: FREE — no charge to start the run
- **Successful Audit**: $0.08 per successfully audited page
- **Failed pages**: FREE — no charge if a page cannot be accessed or times out
- **No AI costs**: Built-in rule engine is free; optional AI enhancement is billed separately via your own Kimi API key (not included in Actor pricing)

A typical 10-page audit costs **$0.80** (if all pages succeed). Failed or timed-out pages are not charged.

### Requirements

- **No API key required** for core SEO audit functionality
- **Optional**: Set `KIMI_API_KEY` environment variable if you want AI-enhanced recommendations (set `useAI: true` in input)

### Limitations

- Cannot audit JavaScript-rendered SPAs (React, Vue, Angular) — static HTML only
- Broken link check limited to 15 links per page (performance optimization)
- Page fetch timeout: 15 seconds per page
- SSL check requires port 443 to be open
- AI enhancement requires valid KIMI\_API\_KEY and may fail gracefully (falls back to rule-based scoring)

### Support

For issues or feature requests, please open an issue on GitHub or contact the developer via Apify messaging.

***

**Built with**: Apify SDK, BeautifulSoup, Requests, Python (core); Kimi AI (optional enhancement)

# Actor input Schema

## `url` (type: `string`):

The website URL to audit (e.g., https://example.com)

## `maxPages` (type: `integer`):

Maximum number of pages to scan

## `checkBrokenLinks` (type: `boolean`):

Check for broken internal and external links

## `checkMobileFriendly` (type: `boolean`):

Analyze mobile responsiveness indicators

## Actor input object example

```json
{
  "url": "https://example.com",
  "maxPages": 10,
  "checkBrokenLinks": true,
  "checkMobileFriendly": true
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "url": "https://example.com"
};

// Run the Actor and wait for it to finish
const run = await client.actor("blank_butter/website-seo-audit").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "url": "https://example.com" }

# Run the Actor and wait for it to finish
run = client.actor("blank_butter/website-seo-audit").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "url": "https://example.com"
}' |
apify call blank_butter/website-seo-audit --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=blank_butter/website-seo-audit",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Website SEO Audit",
        "description": "Comprehensive SEO audit tool that scans websites for technical SEO issues, content gaps, and optimization opportunities. Get actionable recommendations to improve search rankings.",
        "version": "0.1",
        "x-build-id": "lbMhnWbVtmniE0Ke7"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/blank_butter~website-seo-audit/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-blank_butter-website-seo-audit",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/blank_butter~website-seo-audit/runs": {
            "post": {
                "operationId": "runs-sync-blank_butter-website-seo-audit",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/blank_butter~website-seo-audit/run-sync": {
            "post": {
                "operationId": "run-sync-blank_butter-website-seo-audit",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "url"
                ],
                "properties": {
                    "url": {
                        "title": "Website URL",
                        "type": "string",
                        "description": "The website URL to audit (e.g., https://example.com)"
                    },
                    "maxPages": {
                        "title": "Max Pages to Scan",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of pages to scan",
                        "default": 10
                    },
                    "checkBrokenLinks": {
                        "title": "Check Broken Links",
                        "type": "boolean",
                        "description": "Check for broken internal and external links",
                        "default": true
                    },
                    "checkMobileFriendly": {
                        "title": "Check Mobile Friendly",
                        "type": "boolean",
                        "description": "Analyze mobile responsiveness indicators",
                        "default": true
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
