# SEO Content Gap Analyzer - Keyword, Topic & Question Gaps (`centorprat/seo-content-gap-analyzer`) Actor

Give your page + 1-5 competitor pages. Returns the keyword phrases, topic clusters, questions, entities and non-keyword signals competitors emphasise that your page under-covers or omits - weighted by competitor consensus, scored, and prioritized into actions. Keyless, read-only, agent-callable.

- **URL**: https://apify.com/centorprat/seo-content-gap-analyzer.md
- **Developed by:** [Centor Prat](https://apify.com/centorprat) (community)
- **Categories:** SEO tools, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $25.50 / 1,000 content gap analyses

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## SEO Content Gap Analyzer — Keyword, Topic & Question Gaps vs Competitors

Find what the pages that out-rank you talk about that **your** page doesn't. Give your URL + 1–5 competitor URLs and get back the keyword phrases, topic clusters, questions, entities and non-keyword signals your competitors emphasise that your page under-covers or omits — weighted by **competitor consensus**, scored, and turned into a prioritized action list. Keyless, read-only, agent-callable.

Built for SEO/content teams, agencies, and AI agents doing content research at scale.

### What it does

- Fetches your page **and** each competitor page (read-only, exactly what a crawler does — no login, no keys).
- Runs a **prominence-weighted recognition layer**: extracts text from every zone (title, meta, H1, H2–H6, anchor text, image alt, bold, body, JSON-LD) and scores 1–4-word phrases by where they appear — a word in a `<title>`/`<h1>` counts far more than one in the body.
- Computes the **gap**: phrases *multiple* competitors emphasise that your page is missing or thin on (a single rival's brand word never counts as a gap).
- Adds the **expert layer** a specialist would look at, not just "add keywords":

| Output field | What it tells you |
|---|---|
| `contentGapScore` | 0–100, how much of the competitors' topical consensus you're **missing** (higher = bigger gap) |
| `coverageOfCompetitorTopics` | the inverse — % of competitor topics you already cover |
| `missingPhrases` | ranked keyword phrases you omit / under-cover, with competitor consensus + weights |
| `missingTopics` | phrases clustered into whole **subtopics** you don't cover |
| `questionIntentGaps` | questions competitors answer (FAQ/How-to schema + `?` headings) that you don't |
| `entityGaps` | brands/products/named entities competitors reference that you don't |
| `nonKeywordGaps` | structured-data types, thin content, Open Graph, HTTPS competitors have and you lack |
| `prioritizedActions` | a plain do-this-next list |
| `competitors[]` | each competitor's word count, schema types and top phrases |

### Why not just ask an AI agent?

An agent can fetch one page and eyeball it. It **can't** reliably crawl several competitors, extract every zone, weight phrases by prominence, intersect them by consensus, cluster the remainder into subtopics and diff the structured-data/question coverage — deterministically and the same way every time. That tedious, error-prone-by-hand computation is exactly what this actor does. It's the expert, repeatable version, not "improve your wording".

### Input

| Field | Type | Required | Description |
|---|---|---|---|
| `yourUrl` | string | ✅ | The page you want to rank. |
| `competitorUrls` | array of strings | ✅ | 1–5 competing pages ranking for your topic. |
| `webhookUrl` | string | | If set, the finished analysis is POSTed here as JSON. |

**Example input**

```json
{
  "yourUrl": "https://www.python.org/about/",
  "competitorUrls": [
    "https://www.ruby-lang.org/en/about/",
    "https://go.dev/doc/"
  ]
}
```

### Output

One analysis record per run. **Example output** (trimmed, from a real run):

```json
{
  "yourUrl": "https://www.python.org/about/",
  "signal": "large-content-gap",
  "contentGapScore": 88,
  "coverageOfCompetitorTopics": 12,
  "competitorsAnalyzed": 2,
  "yourWordCount": 663,
  "competitorMedianWordCount": 1910,
  "missingPhrases": [
    {"phrase": "module", "status": "missing", "competitorConsensus": 2, "competitorsTotal": 2, "competitorWeight": 51.0, "yourWeight": 0.0, "gapScore": 51.0},
    {"phrase": "documentation", "status": "under-covered", "competitorConsensus": 2, "competitorsTotal": 2, "competitorWeight": 57.0, "yourWeight": 15.0, "gapScore": 42.0}
  ],
  "missingTopics": [
    {"topic": "manual", "examplePhrases": ["reference manual", "manual"], "competitorConsensus": 2, "gapScore": 21.8}
  ],
  "nonKeywordGaps": [
    {"type": "thin-content", "detail": "Your page ~663 words vs competitor median ~1910.", "recommendation": "Competitors cover the topic more deeply; expand the thin sections."}
  ],
  "prioritizedActions": [
    "Target \"module\" - 2/2 competitors emphasise it; your page omits it.",
    "Target \"documentation\" - 2/2 competitors emphasise it; you under-cover it."
  ],
  "disclaimer": "Signals from read-only page text analysis, not live search-ranking data..."
}
```

### Use cases

- **Content briefs** — hand a writer the exact phrases, subtopics and questions to cover before writing.
- **Closing a ranking gap** — see concretely why three competitors out-rank a thin page.
- **Agency audits** — a repeatable, scored gap report per client page vs their named competitors.
- **AI content agents** — one call returns structured gap data to feed into a drafting/optimization step.
- **Topic-cluster planning** — spot entire subtopics the competitive set covers and you don't.

### Ready-made tasks

- [Content Gap Analysis vs Competitor Pages](https://apify.com/centorprat/seo-content-gap-analyzer/examples/content-gap-analysis-vs-competitors)
- [Keyword Gap for a Landing Page](https://apify.com/centorprat/seo-content-gap-analyzer/examples/keyword-gap-landing-page)
- [Blog Post Topic Gap - What Competing Articles Cover](https://apify.com/centorprat/seo-content-gap-analyzer/examples/blog-post-topic-gap)

### For AI agents / MCP

Every public Apify actor is callable through the Apify MCP server — nothing to enable.

```
https://mcp.apify.com/?tools=actors,docs,centorprat/seo-content-gap-analyzer
```

Loads as the tool `centorprat--seo-content-gap-analyzer`. Call it with `yourUrl` + `competitorUrls`; it returns one structured gap analysis. Claude Code one-liner:

```
claude mcp add apify -- npx -y @apify/actors-mcp-server --actors centorprat/seo-content-gap-analyzer
```

### Alerts / scheduling

Set `webhookUrl` and schedule the actor to re-run (e.g. weekly) — the fresh gap analysis is POSTed to Make/Zapier/your endpoint so you're told when a competitor adds coverage you're missing.

### FAQ

**Does it use real search-ranking / keyword-volume data?** No. It's keyless by design: it compares the **content** of the pages you provide. A gap is a content-coverage difference to review, not proof a competitor outranks you. (You bring the competitor URLs — e.g. from a SERP you already looked at.)

**How many competitors can I compare?** 1–5 per run. More competitors = stronger consensus signal.

**How are "gaps" decided?** A phrase is a gap when **multiple** competitors emphasise it (by prominence-weighted zone) and your page is missing it or covers it far less. One rival's unique/brand term is filtered out.

**Does it crawl a whole site?** No — it analyses the exact pages you pass (one per URL), so it's fast and cheap. Point it at the specific competing pages.

**What languages?** Tokenisation is tuned for Latin-script content; it works best on English and similar.

**Is it allowed / legal?** It performs a single read-only GET per page, the same request any browser or search crawler makes. No logins, no bypassing paywalls, public pages only.

**Why a score instead of a verdict?** SEO is multi-factor. This measures **content/topical** coverage; it's one strong input, not the whole ranking truth — hence a signal, not a guarantee.

**How fast?** Typically a few seconds for a handful of pages.

**What does it cost?** Pay-per-event: one charge per completed analysis. Unreachable inputs aren't billed.

**Can I get the raw per-competitor phrases?** Yes — `competitors[]` includes each competitor's top phrases, word count and schema types.

### Data & attribution

Analyses only the public HTML of the URLs you supply, fetched read-only. No third-party API, no keys, no personal data collected. Results are computed signals, not legal/commercial advice.

### Related actors

Part of our keyless SEO toolkit:

- [On-Page SEO Audit](https://apify.com/centorprat/on-page-seo-audit)
- [Broken Link Checker](https://apify.com/centorprat/broken-link-checker)
- [Structured Data Schema Validator](https://apify.com/centorprat/structured-data-schema-validator)
- [Robots.txt & Sitemap Analyzer](https://apify.com/centorprat/robots-sitemap-analyzer)
- [Open Graph Social Preview Checker](https://apify.com/centorprat/open-graph-social-preview-checker)

# Actor input Schema

## `yourUrl` (type: `string`):

The page you want to rank, e.g. "https://your-site.com/guide". Its content is compared against the competitors.

## `competitorUrls` (type: `array`):

Competing pages that rank for your topic, e.g. \["https://competitor-a.com/guide", "https://competitor-b.com/guide"]. One gap analysis is produced comparing your page against all of them.

## `webhookUrl` (type: `string`):

If set, the finished gap analysis is POSTed here as JSON when the run completes (Make/Zapier/custom).

## Actor input object example

```json
{
  "yourUrl": "https://www.python.org/about/",
  "competitorUrls": [
    "https://www.ruby-lang.org/en/about/",
    "https://go.dev/doc/"
  ]
}
```

# Actor output Schema

## `analysis` (type: `string`):

One gap analysis per run: a content-gap score and signal, the missing/under-covered keyword phrases (weighted by competitor consensus), missing topic clusters, question-intent gaps, entity gaps, non-keyword gaps (structured data, thin content, Open Graph, HTTPS), and a prioritized action list.

# 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 = {
    "yourUrl": "https://www.python.org/about/",
    "competitorUrls": [
        "https://www.ruby-lang.org/en/about/",
        "https://go.dev/doc/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("centorprat/seo-content-gap-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 = {
    "yourUrl": "https://www.python.org/about/",
    "competitorUrls": [
        "https://www.ruby-lang.org/en/about/",
        "https://go.dev/doc/",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("centorprat/seo-content-gap-analyzer").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 '{
  "yourUrl": "https://www.python.org/about/",
  "competitorUrls": [
    "https://www.ruby-lang.org/en/about/",
    "https://go.dev/doc/"
  ]
}' |
apify call centorprat/seo-content-gap-analyzer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,centorprat/seo-content-gap-analyzer"
        }
    }
}
```

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/Qi4NYaI41KnLeBRgd/builds/g19sjfyFdi9Hlbw11/openapi.json
