# Website SEO & Metadata Extractor (`winning_moonstone/website-seo-metadata-extractor`) Actor

Extract SEO metadata, headings, links, images, and content statistics from any public web page.

- **URL**: https://apify.com/winning\_moonstone/website-seo-metadata-extractor.md
- **Developed by:** [月 明](https://apify.com/winning_moonstone) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Website SEO & Metadata Extractor do?

Run **batch on-page SEO checks for up to 50 public HTML pages** and get structured metadata plus prioritized review suggestions. Inspect titles, descriptions, headings, canonical links, images and internal/external links. Try https://apify.com/ as a small first run. Apify provides API access, saved tasks, schedules, integrations and run monitoring.

### Why use this SEO audit?

Agencies can review client landing pages, developers can check metadata after a deployment, and content teams can compare titles and descriptions. Each issue includes evidence and a recommendation. The summary identifies exact duplicate titles and descriptions among processed pages. These checks support human review; they are not a ranking score or a guarantee of search performance.

### How to use it

1. Enter a single URL or add explicit Batch page URLs.
2. Set Maximum pages. Start with two pages.
3. Start the Actor and review Page audits.
4. Open Batch summary and errors for skipped URLs, duplicates and stopping reason.
5. Download results or connect your workflow using the Apify API.

### Input

Batch URLs take precedence over the single URL. Duplicate URLs and fragments are removed. Links are not automatically crawled.

```json
{"startUrls":[{"url":"https://apify.com/"},{"url":"https://apify.com/store"}],"maxPages":2,"maxLinks":25,"maxImages":20,"timeoutSeconds":20}
```

Existing integrations using url remain supported. maxPages defaults to 20 (1–50), maxLinks to 100 (0–1000), maxImages to 50 (0–500), and timeoutSeconds to 20 (5–60). Empty input audits the Apify homepage.

### Output

One dataset record is written per successfully analyzed HTML page. Failed, blocked and non-HTML pages appear in SUMMARY instead. Download the dataset in JSON, CSV or Excel.

Illustrative fields:

```json
{"requestedUrl":"https://example.com/","title":"Example Domain","success":true,"issues":[{"code":"missing_description","severity":"medium","evidence":"No meta description","recommendation":"Write a page-specific summary for search snippets."}]}
```

### Data table

| Field | Meaning |
| --- | --- |
| requestedUrl / finalUrl | Input URL and final destination |
| statusCode / contentType | HTTP response information |
| title / metaDescription / canonicalUrl | Search metadata |
| headings / h1Count | H1–H6 structure |
| wordCount | Whitespace-separated body words, excluding scripts/styles/templates |
| links / linkSummary | Capped details and uncapped counts |
| images / imageCount | Capped details and total count |
| seoChecks / imagesEmptyAlt | Missing alt attributes and separately counted empty alt text |
| issues / recommendations | Review priorities, evidence and fixes |
| linksTruncated / imagesTruncated | Whether lists were capped |

SUMMARY contains attempted pages, saved results, errors, duplicate metadata, duration and stopReason. Counts may be partial when spending or time limits stop a run.

### Pricing and cost estimation

See Pricing for current event prices. At the current base rate, 100 analyzed pages cost $0.40 in result events, plus Actor-start events. Failed pages do not create result events; the start event still applies. Batch pages to reduce repeated startup overhead. Set your run spending limit and maxPages. The Actor stops when the SDK reports the result-charge limit.

### Tips and limitations

Server-rendered HTML only. JavaScript-only content, logged-in pages, PDFs, browser performance metrics and backlink analysis are outside scope. Links are extracted, not fetched for broken-link testing. Whitespace-based word counts are not linguistic segmentation for every language. Empty alt may be intentional for decorative images.

Requests respect robots.txt, with a minimum one-second page delay and bounded retries for selected transient HTTP errors. Unverifiable robots responses cause skips. Limits include 2 MB per response, five redirects and a roughly four-minute work budget checked between pages. Only public HTTP(S) URLs on standard ports are supported.

### FAQ and support

Use URLs you are permitted to access and respect site terms. Review noindex flags and multiple H1s in context. Missing data can indicate client-side rendering. For issues or custom workflow requests, use the Issues tab with a public URL and run ID, without passwords or private data.

# Actor input Schema

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

Backwards-compatible single page input; ignored when batch URLs are supplied.

## `startUrls` (type: `array`):

Explicit pages to audit; duplicates and fragments removed. No automatic site crawling.

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

Hard cap on attempted unique URLs.

## `maxLinks` (type: `integer`):

Summary counts include all links even when this list is capped.

## `maxImages` (type: `integer`):

Image and missing-alt counts include all images.

## `timeoutSeconds` (type: `integer`):

Network timeout; an additional whole-page timeout bounds robots and redirects.

## Actor input object example

```json
{
  "url": "https://apify.com/",
  "maxPages": 20,
  "maxLinks": 100,
  "maxImages": 50,
  "timeoutSeconds": 20
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `summary` (type: `string`):

No description

# 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://apify.com/"
};

// Run the Actor and wait for it to finish
const run = await client.actor("winning_moonstone/website-seo-metadata-extractor").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://apify.com/" }

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

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).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://apify.com/"
}' |
apify call winning_moonstone/website-seo-metadata-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,winning_moonstone/website-seo-metadata-extractor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/LgTyGx00WJqYEOdo5/builds/JIEKIiYuHjasUVAuE/openapi.json
