# Title Tag Analyzer (`zerobreak/title-tag-analyzer`) Actor

Title tag analyzer that checks page titles and meta descriptions across any list of URLs, so SEO teams can catch missing or oversized tags before rankings slip.

- **URL**: https://apify.com/zerobreak/title-tag-analyzer.md
- **Developed by:** [ZeroBreak](https://apify.com/zerobreak) (community)
- **Categories:** SEO tools
- **Stats:** 3 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

## Title Tag Analyzer: Audit Page Titles and Meta Descriptions at Scale

Title tag analyzer for SEO teams who need to check page titles and meta descriptions without opening each URL by hand. Paste in one URL or a bulk list and get back the character length, a pass/fail status, and the HTTP response code for every page. Short, missing, or oversized titles cost rankings before anyone clicks, and this actor surfaces them fast.

### Use cases

- **SEO auditing**: scan every page for missing or oversized title tags without touching a browser
- **Site migrations**: confirm title tags transferred correctly after moving to a new CMS or domain
- **Pre-publish checks**: verify title and meta description length before pages go live
- **Competitor research**: pull title tags from competitor URLs to see how they approach page titles
- **Ongoing monitoring**: run on a schedule to catch title tag regressions after template or CMS updates

### What data does this actor extract?

Each result contains:

```json
{
    "url": "https://apify.com",
    "finalUrl": "https://apify.com/",
    "httpStatus": 200,
    "titleTag": "Apify: Full-Stack Web Scraping and Data Extraction Platform",
    "titleLength": 59,
    "titleStatus": "optimal",
    "titleWordCount": 9,
    "metaDescription": "Apify is the full-stack web scraping and data extraction platform. Build reliable scrapers. Fast.",
    "metaDescriptionLength": 97,
    "metaDescriptionStatus": "optimal",
    "scrapedAt": "2025-01-15T10:23:41.123456+00:00"
}
````

| Field | Type | Description |
|-------|------|-------------|
| `url` | string | The original URL submitted for analysis |
| `finalUrl` | string | URL after following all redirects |
| `httpStatus` | integer | HTTP response code (200, 301, 404, etc.) |
| `titleTag` | string | Full text of the `<title>` tag |
| `titleLength` | integer | Character count of the title tag |
| `titleStatus` | string | `optimal` (30-60 chars), `too_short`, `too_long`, or `missing` |
| `titleWordCount` | integer | Number of words in the title |
| `metaDescription` | string | Content of the `<meta name="description">` tag |
| `metaDescriptionLength` | integer | Character count of the meta description |
| `metaDescriptionStatus` | string | `optimal` (70-155 chars), `too_short`, `too_long`, or `missing` |
| `scrapedAt` | string | ISO 8601 timestamp of when the page was fetched |
| `error` | string | Error message if the request failed; absent on success |

### Input

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `url` | string | | Single URL to analyze |
| `urls` | array | `[]` | List of URLs for bulk title tag checking, one per line |
| `checkMetaDescription` | boolean | `true` | Also extract and rate the meta description |
| `maxUrls` | integer | `100` | Maximum URLs processed per run (hard cap: 1000) |
| `requestTimeoutSecs` | integer | `30` | Per-request timeout in seconds |
| `timeoutSecs` | integer | `300` | Total actor run timeout in seconds |
| `proxyConfiguration` | object | Datacenter (Anywhere) | Proxy type and location for requests. Supports Datacenter, Residential, Special, and custom proxies. Optional. |

Provide at least one URL via `url` or `urls`.

#### Example input

```json
{
    "urls": [
        "https://apify.com",
        "https://apify.com/store",
        "https://docs.apify.com"
    ],
    "checkMetaDescription": true,
    "maxUrls": 100,
    "proxyConfiguration": { "useApifyProxy": true }
}
```

### How it works

1. Takes one or more URLs from the input, deduplicates them, and applies the `maxUrls` cap
2. Fetches each page with a realistic browser User-Agent and follows redirects automatically
3. Parses the raw HTML to extract the `<title>` and `<meta name="description">` tags
4. Measures character length and assigns a status: `optimal`, `too_short`, `too_long`, or `missing`
5. Records the HTTP status code so broken pages and redirect chains show up in results
6. Pushes each result to the Apify dataset as it processes, so you can see progress in real time

### Title tag length reference

| Status | Character range | What it means |
|--------|----------------|---------------|
| `missing` | 0 characters | No title tag on the page |
| `too_short` | 1-29 characters | Too brief; Google may rewrite it |
| `optimal` | 30-60 characters | Displays fully in search results |
| `too_long` | 61+ characters | Google cuts it off at roughly 580 pixels |

### Meta description length reference

| Status | Character range | What it means |
|--------|----------------|---------------|
| `missing` | 0 characters | No meta description tag found |
| `too_short` | 1-69 characters | May be too thin to display in results |
| `optimal` | 70-155 characters | Falls within Google's typical display range |
| `too_long` | 156+ characters | Google truncates it in search results |

### Integrations

Connect Title Tag Analyzer with other tools using [Apify integrations](https://apify.com/integrations). Works with Make, Zapier, Slack, Airbyte, GitHub, Google Sheets, Google Drive, and more. You can also set up [webhooks](https://docs.apify.com/integrations/webhooks) to trigger downstream actions as soon as results are ready.

### FAQ

**How many URLs can this actor handle per run?**
The default cap is 100 URLs. Raise it up to 1000 with the `maxUrls` input. For larger lists, split them across multiple runs or schedule the actor to run on a crawl-friendly pace.

**Does it work on JavaScript-rendered pages?**
The actor uses plain HTTP requests and parses the raw HTML. Pages that inject the title tag only via JavaScript may return a missing status. For JS-heavy sites, pair this with a browser-based actor to render the page first.

**Why is my title flagged as too\_long when it looks fine in the browser tab?**
Browsers show the full title regardless of length. Google limits displayed titles to around 580 pixels, which works out to about 60 characters. Longer titles get cut off in search results, which is what this actor flags.

**What does finalUrl mean?**
It's the URL the actor actually landed on after following all redirects. If `url` and `finalUrl` differ, there's a redirect in place. Spot redirect chains you may not know about by comparing the two fields.

**Can I export results to a spreadsheet?**
Yes. Open the dataset in Apify Console and download as CSV or JSON. You can also pipe results directly into Google Sheets using the Apify Google Sheets integration.

Run a bulk title tag audit on any site in minutes. Paste your URLs, hit run, and export the results to see exactly which pages need work.

# Actor input Schema

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

Single URL to analyze. You can also use the URLs field below to run bulk checks. Provide at least one.

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

List of URLs to analyze in bulk. Enter one URL per line. Combines with the single URL field if both are provided.

## `checkMetaDescription` (type: `boolean`):

When enabled, also extracts and analyzes the meta description length and status for each page.

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

Maximum number of URLs to process per run. Use this to control costs. Hard cap at 1000.

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

How long to wait for a page to respond before moving on. Increase for slow sites.

## `timeoutSecs` (type: `integer`):

Total time the actor is allowed to run. Increase if processing a large URL list.

## `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://apify.com/store",
    "https://docs.apify.com"
  ],
  "checkMetaDescription": true,
  "maxUrls": 100,
  "requestTimeoutSecs": 30,
  "timeoutSecs": 300,
  "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",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("zerobreak/title-tag-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",
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Title Tag Analyzer",
        "description": "Title tag analyzer that checks page titles and meta descriptions across any list of URLs, so SEO teams can catch missing or oversized tags before rankings slip.",
        "version": "0.0",
        "x-build-id": "leev7wFTCoQGcdfoQ"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/zerobreak~title-tag-analyzer/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-zerobreak-title-tag-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~title-tag-analyzer/runs": {
            "post": {
                "operationId": "runs-sync-zerobreak-title-tag-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~title-tag-analyzer/run-sync": {
            "post": {
                "operationId": "run-sync-zerobreak-title-tag-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": "URL",
                        "type": "string",
                        "description": "Single URL to analyze. You can also use the URLs field below to run bulk checks. Provide at least one."
                    },
                    "urls": {
                        "title": "URLs (bulk)",
                        "type": "array",
                        "description": "List of URLs to analyze in bulk. Enter one URL per line. Combines with the single URL field if both are provided.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "checkMetaDescription": {
                        "title": "Check meta description",
                        "type": "boolean",
                        "description": "When enabled, also extracts and analyzes the meta description length and status for each page.",
                        "default": true
                    },
                    "maxUrls": {
                        "title": "Max URLs",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum number of URLs to process per run. Use this to control costs. Hard cap at 1000.",
                        "default": 100
                    },
                    "requestTimeoutSecs": {
                        "title": "Request timeout (seconds)",
                        "minimum": 5,
                        "maximum": 120,
                        "type": "integer",
                        "description": "How long to wait for a page to respond before moving on. Increase for slow sites.",
                        "default": 30
                    },
                    "timeoutSecs": {
                        "title": "Actor timeout (seconds)",
                        "minimum": 30,
                        "maximum": 3600,
                        "type": "integer",
                        "description": "Total time the actor is allowed to run. Increase if processing a large URL list.",
                        "default": 300
                    },
                    "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
