# Meta Description Analyzer (`zerobreak/meta-description-analyzer`) Actor

Meta description analyzer that checks any URL for missing or incorrectly sized meta descriptions, so SEO teams can catch and fix issues before they cost search rankings.

- **URL**: https://apify.com/zerobreak/meta-description-analyzer.md
- **Developed by:** [ZeroBreak](https://apify.com/zerobreak) (community)
- **Categories:** SEO tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.99/month + usage

To use this Actor, you pay a monthly rental fee to the developer. The rent is subtracted from your prepaid usage every month after the free trial period.You also pay for the Apify platform usage, which gets cheaper the higher Apify subscription plan you have.

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

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

## Meta Description Analyzer: Audit Meta Descriptions Across Any List of URLs

Meta Description Analyzer fetches pages and checks whether their meta description tags are present, the right length, and formatted correctly for search engines. Give it a list of URLs and get back a result per page showing the description text, character count, and a plain status: ok, too_short, too_long, or missing.

It also pulls Open Graph and Twitter card descriptions alongside the standard meta tag, so you're not guessing about what social platforms read. No full site crawl needed.

### Use cases

- **Pre-launch SEO audits**: catch missing or oversized meta descriptions before a site goes live
- **Post-migration checks**: verify meta descriptions survived a CMS or template change intact
- **Content team reviews**: build a list of pages that need description work, without manual clicking
- **Client reporting**: pull bulk meta tag data for SEO audits faster than any manual process
- **Scheduled monitoring**: run on a schedule to catch regressions when new pages are published

### What data does this actor extract?

Each result maps to one URL and looks like this:

```json
{
    "inputUrl": "https://apify.com",
    "url": "https://apify.com/",
    "httpStatus": 200,
    "pageTitle": "Apify: Full-Stack Web Scraping and Data Extraction Platform",
    "titleLength": 56,
    "metaDescription": "Apify is the full-stack web scraping and data extraction platform. Get started with ready-made scrapers or build your own.",
    "metaDescLength": 121,
    "metaDescStatus": "ok",
    "ogDescription": "Apify is the full-stack web scraping and data extraction platform.",
    "twitterDescription": "",
    "scrapedAt": "2025-01-15T10:23:45.123456+00:00",
    "error": null
}
````

### Input

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `url` | string | - | Single URL to analyze. Combined with `urls` if both are provided. |
| `urls` | array | - | List of URLs to check, one per line. |
| `maxUrls` | integer | 100 | Maximum number of URLs to process per run (hard cap: 1,000). |
| `requestTimeoutSecs` | integer | 30 | Per-request timeout in seconds. Increase for slow servers. |
| `proxyConfiguration` | object | Datacenter (Anywhere) | Proxy type and location for requests. Optional. |

#### Example input

```json
{
    "urls": [
        "https://apify.com",
        "https://apify.com/about",
        "https://apify.com/pricing"
    ],
    "maxUrls": 100,
    "requestTimeoutSecs": 30,
    "proxyConfiguration": { "useApifyProxy": true }
}
```

### Output

The `metaDescStatus` field is the quickest way to find problems:

| Status | Meaning |
|--------|---------|
| `ok` | Meta description is 70-160 characters. |
| `too_short` | Under 70 characters. Consider expanding. |
| `too_long` | Over 160 characters. Likely truncated in search results. |
| `missing` | No meta description tag found on the page. |
| `error` | Page could not be fetched. Check the `error` field. |

Full output field reference:

| Field | Type | Description |
|-------|------|-------------|
| `inputUrl` | string | The original URL submitted. |
| `url` | string | Final URL after following any redirects. |
| `httpStatus` | integer | HTTP status code (200, 404, etc.). |
| `pageTitle` | string | Text of the `<title>` tag. |
| `titleLength` | integer | Character count of the page title. |
| `metaDescription` | string | Content of the meta description tag. Empty string if missing. |
| `metaDescLength` | integer | Character count of the meta description. 0 if missing. |
| `metaDescStatus` | string | SEO status: ok, too\_short, too\_long, missing, or error. |
| `ogDescription` | string | Open Graph og:description content. Empty if not present. |
| `twitterDescription` | string | Twitter card twitter:description content. Empty if not present. |
| `scrapedAt` | string | ISO 8601 UTC timestamp of when the page was fetched. |
| `error` | string | Error message if the request failed. Null on success. |

### How it works

1. Takes the URL list from input (single `url`, `urls` list, or both combined and deduplicated)
2. Caps the list at `maxUrls` and logs a warning if URLs were dropped
3. Fetches each page with a realistic browser User-Agent, following redirects automatically
4. Parses the HTML to extract the meta description, OG description, and Twitter card description
5. Classifies the meta description by character length against the 70-160 character range
6. Pushes each result to the dataset

### FAQ

**What counts as the right meta description length?**

Google typically truncates descriptions longer than 155-160 characters in search snippets. Descriptions under 70 characters tend to look thin. The actor flags anything outside 70-160 as `too_short` or `too_long`.

**Does the actor work on JavaScript-rendered pages?**

It uses standard HTTP requests and reads what the server returns before JavaScript runs. If a site builds its meta description client-side (React, Vue, etc.) without server-side rendering, the tag may be empty or absent in the response. Check whether the site uses SSR or pre-rendering if results look off.

**Can I check hundreds of URLs at once?**

Yes. Pass a list of up to 1,000 URLs via the `urls` input. The actor processes them in sequence and rotates proxies if you have that configured.

**What happens if a page returns a 404 or other error?**

The actor records the HTTP status and an error message in that row and keeps processing the rest of the list. It does not stop the run.

**Does it follow redirects?**

Yes. The final URL after all redirects goes into the `url` field. The original input stays in `inputUrl`, so you can see both.

### Integrations

Connect Meta Description Analyzer with other tools using [Apify integrations](https://apify.com/integrations). Push results to Google Sheets, trigger a Slack alert when missing descriptions are found, or wire it into Make and Zapier. You can also use [webhooks](https://docs.apify.com/integrations/webhooks) to kick off a downstream action as soon as the run finishes.

# Actor input Schema

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

One URL to analyze. Combined with the URLs list if both are provided.

## `urls` (type: `array`):

List of URLs to analyze. Enter one URL per line.

## `maxUrls` (type: `integer`):

Maximum number of URLs to process per run. Useful for controlling cost and run time.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for a page response before timing out. Increase for slow servers.

## `proxyConfiguration` (type: `object`):

Select proxies to use for requests. Helps avoid IP blocking and rate limits. Datacenter proxies are fastest; Residential proxies are harder to detect.

## Actor input object example

```json
{
  "url": "https://apify.com",
  "urls": [
    "https://apify.com",
    "https://docs.python.org/3/"
  ],
  "maxUrls": 100,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": 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://apify.com",
    "maxUrls": 100,
    "requestTimeoutSecs": 30,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("zerobreak/meta-description-analyzer").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",
    "maxUrls": 100,
    "requestTimeoutSecs": 30,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("zerobreak/meta-description-analyzer").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://apify.com",
  "maxUrls": 100,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call zerobreak/meta-description-analyzer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=zerobreak/meta-description-analyzer",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Meta Description Analyzer",
        "description": "Meta description analyzer that checks any URL for missing or incorrectly sized meta descriptions, so SEO teams can catch and fix issues before they cost search rankings.",
        "version": "0.0",
        "x-build-id": "yYo1GYIMteBm9PTRD"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/zerobreak~meta-description-analyzer/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-zerobreak-meta-description-analyzer",
                "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/zerobreak~meta-description-analyzer/runs": {
            "post": {
                "operationId": "runs-sync-zerobreak-meta-description-analyzer",
                "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/zerobreak~meta-description-analyzer/run-sync": {
            "post": {
                "operationId": "run-sync-zerobreak-meta-description-analyzer",
                "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",
                "properties": {
                    "url": {
                        "title": "Single URL",
                        "type": "string",
                        "description": "One URL to analyze. Combined with the URLs list if both are provided."
                    },
                    "urls": {
                        "title": "URLs",
                        "type": "array",
                        "description": "List of URLs to analyze. Enter one URL per line.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxUrls": {
                        "title": "Max URLs",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum number of URLs to process per run. Useful for controlling cost and run time.",
                        "default": 100
                    },
                    "requestTimeoutSecs": {
                        "title": "Request timeout (seconds)",
                        "minimum": 5,
                        "maximum": 120,
                        "type": "integer",
                        "description": "How long to wait for a page response before timing out. Increase for slow servers.",
                        "default": 30
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Select proxies to use for requests. Helps avoid IP blocking and rate limits. Datacenter proxies are fastest; Residential proxies are harder to detect."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
