# Readability & SEO Content Checker – German + English (`fast_data_asap/readability-seo-content-checker`) Actor

Bulk readability checker for URLs or text in English and German: Flesch Reading Ease, Flesch-Kincaid, Gunning Fog, SMOG, Flesch-Amstad, Wiener Sachtextformel, LIX, long sentences, passive voice, headings, title/meta length, keyword density and concrete fix hints.

- **URL**: https://apify.com/fast_data_asap/readability-seo-content-checker.md
- **Developed by:** [Fast Data](https://apify.com/fast_data_asap) (community)
- **Categories:** SEO tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 page or text analyseds

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

## Readability & SEO Content Checker (German + English)

Check the readability and on-page SEO basics of many web pages or texts in one run, in **English and German**. You get one flat row per page or text with all the classic readability scores, long sentences, the passive voice share, heading structure, title and meta description length, keyword usage and a short list of concrete fixes.

- **English formulas:** Flesch Reading Ease, Flesch-Kincaid Grade, Gunning Fog, SMOG
- **German formulas:** Flesch-Amstad (German Flesch) and the Wiener Sachtextformel (1. WSTF)
- **Both languages:** LIX, average sentence length, syllables per word, long and complex words
- **Writing checks:** long sentences (>20 words in English, >25 in German) with the 3 longest examples, passive voice share (estimate), paragraph length, reading time
- **SEO checks for URLs:** H1 count (missing or multiple H1), H2/H3 outline, heading level skips, title and meta description length, canonical, meta robots
- **Keyword checks (optional):** occurrences, keyword density and whether the keyword appears in the title, H1, meta description and first paragraph
- **Improvement hints** in plain language, e.g. *"15 sentence(s) (37%) have more than 25 words. Split the longest one (41 words) first."*

### Who it is for

- **SEO agencies and content teams** auditing blogs, category texts or landing pages in bulk
- **German-speaking publishers and companies** who need real German readability formulas, not English formulas applied to German text
- **Copywriters and editors** checking drafts before they go live (paste the text, no URL needed)
- **AI and automation workflows** that score or rewrite content: n8n, Make, Zapier or an AI agent via MCP

### Why this checker

- **German done properly.** English formulas misjudge German because German words are longer. This actor uses Flesch-Amstad and the Wiener Sachtextformel for German, with syllables counted through German hyphenation patterns.
- **Main content only.** Pages are cleaned with trafilatura: navigation, footer, cookie banners and reference lists are removed before scoring, so the score reflects the article, not the menu.
- **Bulk and cheap.** Hundreds of URLs and texts per run for $0.002 each, with no start fee. Failed pages are free.
- **Flat, AI-friendly output.** One row per page with stable field names. Export as CSV, Excel or JSON, or feed it to an LLM.
- **Polite crawling.** Plain HTTP requests, robots.txt is respected, no browser and no login.

### Input

| Field | Description |
|---|---|
| `urls` | Web pages to check (plain HTML, no JavaScript rendering). |
| `texts` | Inline texts: `[{"id": "draft-1", "text": "...", "targetKeyword": "optional"}]`. Line breaks separate paragraphs. HTML is accepted too. |
| `language` | `auto` (default), `en` or `de`. Auto detects the language per page/text. |
| `targetKeyword` | Optional focus keyword or phrase. |
| `targetGrade` | Optional maximum school grade, e.g. `8`. Compared with Flesch-Kincaid (English) or the Wiener Sachtextformel (German). |
| `includeText` | Adds the extracted main text (`mainText`) to each row. |
| `respectRobotsTxt` | Default `true`. Disallowed URLs are returned as `blocked_by_robots` and are free. |

Example:

```json
{
  "urls": [
    "https://en.wikipedia.org/wiki/Readability",
    "https://de.wikipedia.org/wiki/Lesbarkeit"
  ],
  "texts": [
    {"id": "entwurf-de", "text": "Gute Texte sind leicht zu lesen. Kurze Sätze helfen dabei, ..."}
  ],
  "language": "auto",
  "targetKeyword": "readability",
  "targetGrade": 9
}
```

### Output

Real result for `https://de.wikipedia.org/wiki/Lesbarkeit` from a test run (shortened):

```json
{
  "inputType": "url",
  "id": "https://de.wikipedia.org/wiki/Lesbarkeit",
  "status": "ok",
  "httpStatus": 200,
  "title": "Lesbarkeit – Wikipedia",
  "titleLength": 22,
  "metaDescriptionLength": 0,
  "h1Count": 1,
  "h1": "Lesbarkeit",
  "missingH1": false,
  "multipleH1": false,
  "h2Count": 9,
  "h3Count": 3,
  "headingOutline": ["H2: Inhaltsverzeichnis", "H2: Lesbarkeits- bzw. Verständlichkeitskriterien", "  H3: Erkennbarkeit – Typografie", "..."],
  "language": "de",
  "wordCount": 894,
  "sentenceCount": 41,
  "paragraphCount": 17,
  "readabilityScore": 36.2,
  "readabilityLevel": "difficult",
  "gradeLevel": 12.1,
  "fleschAmstad": 36.2,
  "wienerSachtextformel": 12.1,
  "lix": 58.5,
  "avgSentenceLength": 21.8,
  "avgSyllablesPerWord": 2.09,
  "longWordsPercent": 36.7,
  "complexWordsPercent": 31.1,
  "longSentencesOver20": 21,
  "longSentencesOver25": 15,
  "longestSentenceWords": 41,
  "longSentenceExamples": ["Der Leseprozess wird allerdings außer von der Lesbarkeit bzw. Verständlichkeit auch von Kriterien beeinflusst, die nicht auf Seiten des Textes selbst liegen, ..."],
  "passiveVoicePercent": 36.6,
  "readingTimeMinutes": 4.5,
  "hints": [
    "15 sentence(s) (37%) have more than 25 words. Split the longest one (41 words) first.",
    "Average sentence length is 21.8 words. Aim for 12-18 words.",
    "Flesch-Amstad is 36.2 (difficult). Use shorter sentences and replace long or technical words with everyday ones.",
    "31.1% of words have 3+ syllables. Split compound nouns (e.g. with a hyphen) or rephrase them.",
    "About 36.6% of sentences use the passive voice (estimate). Rewrite some in the active voice: say who does what.",
    "Title has only 22 characters. Use 30-60 characters and include the main keyword.",
    "Missing meta description. Add one with 120-155 characters that summarizes the page."
  ],
  "hintCount": 7
}
```

From the same run, the English article `https://en.wikipedia.org/wiki/Readability` scored Flesch Reading Ease **47.2**, Flesch-Kincaid grade **10.7**, Gunning Fog **13.5**, SMOG **12.8** and LIX **46.9** (4,847 words, 17% passive sentences). The short German draft text scored Flesch-Amstad **46.5** and WSTF **7.7**.

Other fields: `url`, `finalUrl`, `error`, `checkedAt`, `metaDescription`, `headingLevelSkips`, `canonicalUrl`, `metaRobots`, `htmlLang`, `languageSource`, `languageConfidence`, `characterCount`, `avgWordsPerParagraph`, `longSentenceThreshold`, `passiveVoiceSentences`, `note`, and with a keyword: `targetKeyword`, `keywordOccurrences`, `keywordDensityPercent`, `keywordInTitle`, `keywordInH1`, `keywordInMetaDescription`, `keywordInFirstParagraph`. With a target grade: `targetGrade`, `meetsTargetGrade`.

`status` is `ok`, `error` (unreachable, HTTP error, not HTML), `blocked_by_robots` or `too_short` (fewer than 20 words of main content).

#### How to read the scores

| Score | Language | Good for general audiences |
|---|---|---|
| `readabilityScore` | Flesch Reading Ease (en) or Flesch-Amstad (de), 0-100, higher = easier | 60 or more |
| `gradeLevel` | Flesch-Kincaid (en) or Wiener Sachtextformel (de), school grade | 8 or less |
| `gunningFog`, `smogIndex` | English, years of schooling | 12 or less |
| `lix` | both, under 40 easy, over 50 hard, over 60 very hard | under 45 |

Formulas for English: Flesch Reading Ease = 206.835 − 1.015 × ASL − 84.6 × ASW, Flesch-Kincaid = 0.39 × ASL + 11.8 × ASW − 15.59, Gunning Fog = 0.4 × (ASL + 100 × words with 3+ syllables / words), SMOG = 1.043 × √(polysyllables × 30 / sentences) + 3.1291. ASL = average sentence length in words, ASW = average syllables per word. LIX = ASL + 100 × words longer than 6 letters / words.

Syllables are counted with pyphen hyphenation patterns (en_US or de_DE) and checked against a vowel-group count, because hyphenation dictionaries do not split short words such as "about". Scores are most reliable for texts with 30 or more sentences; shorter texts get a `note`. The passive voice share is a pattern-based estimate (forms of *be/get* + past participle in English; *werden/worden* + Partizip II in German).

### Deutsch: Lesbarkeitsformeln für deutsche Texte

Englische Formeln bewerten deutsche Texte zu schlecht, weil deutsche Wörter im Schnitt mehr Silben haben. Für deutsche Texte nutzt der Actor daher eigene Formeln. Silben werden mit den deutschen Silbentrennungsmustern (pyphen, de_DE) gezählt.

**Flesch-Amstad (deutscher Flesch-Index, Toni Amstad 1978)**

FA = 180 − ASL − 58,5 × ASW

ASL = durchschnittliche Satzlänge in Wörtern, ASW = durchschnittliche Silbenzahl pro Wort. Skala 0 bis 100, je höher, desto leichter:

| Wert | Bewertung |
|---|---|
| 80-100 | leicht bis sehr leicht |
| 60-80 | mittel, gut für Webtexte und Ratgeber |
| 50-60 | mittelschwer |
| 30-50 | schwer (Fach- und Sachtexte) |
| unter 30 | sehr schwer (wissenschaftliche Texte) |

**Erste Wiener Sachtextformel (1. WSTF, Bamberger und Vanecek 1984)**

WSTF = 0,1935 × MS + 0,1672 × SL + 0,1297 × IW − 0,0327 × ES − 0,875

- MS = Anteil der Wörter mit drei oder mehr Silben in %
- SL = mittlere Satzlänge in Wörtern
- IW = Anteil der Wörter mit mehr als sechs Buchstaben in %
- ES = Anteil der einsilbigen Wörter in %

Das Ergebnis entspricht ungefähr einer Schulstufe von 4 (sehr leicht) bis 15 (sehr schwer). Für Webtexte an ein breites Publikum sind Werte bis etwa 8 bis 9 ein gutes Ziel. Mit `targetGrade` können Sie eine Zielstufe vorgeben.

**LIX (Lesbarkeitsindex nach Björnsson)** = mittlere Satzlänge + Anteil der Wörter mit mehr als sechs Buchstaben in %. Unter 40 leicht, 40 bis 50 mittel, über 50 schwer, über 60 sehr schwer.

Lange Sätze werden für Deutsch ab 25 Wörtern gezählt (`longSentencesOver25`), die drei längsten stehen als Beispiele in `longSentenceExamples`. Der Passivanteil ist eine Schätzung (Formen von *werden* bzw. *worden* plus Partizip II).

### Pricing

Pay per event: **$0.002 per analysed page or text** ($2 per 1,000), no start fee. Pages that fail, are blocked by robots.txt or have too little text are free. Platform usage is small: about 5 seconds for the default input at 512 MB.

### Use via API, n8n or MCP

**API (synchronous, returns the items):**

```bash
curl -X POST "https://api.apify.com/v2/acts/fast_data_asap~readability-seo-content-checker/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls":["https://en.wikipedia.org/wiki/Readability"],"targetKeyword":"readability"}'
```

**n8n / Make / Zapier:** use the Apify node or app, choose *Run Actor* with `fast_data_asap/readability-seo-content-checker`, pass `urls` or `texts`, then read the dataset items.

**MCP (Claude, Cursor, other AI agents):** add the server `https://mcp.apify.com?tools=fast_data_asap/readability-seo-content-checker`. Your agent can then check a draft's readability and rewrite it until it meets a target grade.

### Limits

- Only publicly available HTML is read; no login, no JavaScript rendering. Single-page apps that render text in the browser may return `too_short`.
- Languages: English and German. Other languages are scored with the English formulas when detected as neither.
- Readability formulas measure sentence and word length, not meaning. Use them as a guide together with your own judgement.
- No personal data is collected.

# Actor input Schema

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

Web pages to check. Each page is fetched as plain HTML (no browser, robots.txt respected), the main content is extracted (navigation, footer and ads removed) and analysed.

## `texts` (type: `array`):

Optional inline texts, e.g. drafts before publishing. Each entry: {"id": "my-draft", "text": "..."} and optionally its own "targetKeyword". Line breaks separate paragraphs. HTML is accepted too (then headings, title and meta description are checked).

## `language` (type: `string`):

auto detects German or English per page/text. Set de or en to force the formulas for one language.

## `targetKeyword` (type: `string`):

Focus keyword or phrase. Adds keyword count, density and whether it appears in the title, H1, meta description and first paragraph.

## `targetGrade` (type: `integer`):

Maximum school grade your audience should need, e.g. 8. Compared with Flesch-Kincaid grade (English) or Wiener Sachtextformel (German, also a school-grade scale 4-15).

## `includeText` (type: `boolean`):

Adds the extracted main content as plain text (mainText, up to 100,000 characters), e.g. to verify the extraction or feed it to an AI model.

## `respectRobotsTxt` (type: `boolean`):

Skip URLs that the site's robots.txt disallows (they are returned with status blocked_by_robots and are free).

## `maxConcurrency` (type: `integer`):

How many pages are fetched in parallel.

## `maxRetries` (type: `integer`):

Retries on network errors and 5xx/429 responses.

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

Optional. Usually not needed for public articles and blogs.

## Actor input object example

```json
{
  "urls": [
    "https://en.wikipedia.org/wiki/Readability",
    "https://de.wikipedia.org/wiki/Lesbarkeit"
  ],
  "texts": [
    {
      "id": "entwurf-de",
      "text": "Gute Texte sind leicht zu lesen. Kurze Sätze helfen dabei, denn jeder Gedanke bekommt seinen eigenen Satz.\nWenn ein Satz dagegen mehr als fünfundzwanzig Wörter enthält und zudem mit verschachtelten Nebensätzen, Fachbegriffen sowie langen zusammengesetzten Hauptwörtern wie Bundesverfassungsgerichtsentscheidung gespickt ist, dann wird er von vielen Lesern nur langsam verstanden.\nDieser Absatz wurde von der Redaktion überarbeitet. Schreiben Sie aktiv und konkret: Wer macht was?"
    }
  ],
  "language": "auto",
  "includeText": false,
  "respectRobotsTxt": true,
  "maxConcurrency": 5,
  "maxRetries": 1
}
```

# Actor output Schema

## `results` (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 = {
    "urls": [
        "https://en.wikipedia.org/wiki/Readability",
        "https://de.wikipedia.org/wiki/Lesbarkeit"
    ],
    "texts": [
        {
            "id": "entwurf-de",
            "text": "Gute Texte sind leicht zu lesen. Kurze Sätze helfen dabei, denn jeder Gedanke bekommt seinen eigenen Satz.\nWenn ein Satz dagegen mehr als fünfundzwanzig Wörter enthält und zudem mit verschachtelten Nebensätzen, Fachbegriffen sowie langen zusammengesetzten Hauptwörtern wie Bundesverfassungsgerichtsentscheidung gespickt ist, dann wird er von vielen Lesern nur langsam verstanden.\nDieser Absatz wurde von der Redaktion überarbeitet. Schreiben Sie aktiv und konkret: Wer macht was?"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fast_data_asap/readability-seo-content-checker").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 = {
    "urls": [
        "https://en.wikipedia.org/wiki/Readability",
        "https://de.wikipedia.org/wiki/Lesbarkeit",
    ],
    "texts": [{
            "id": "entwurf-de",
            "text": """Gute Texte sind leicht zu lesen. Kurze Sätze helfen dabei, denn jeder Gedanke bekommt seinen eigenen Satz.
Wenn ein Satz dagegen mehr als fünfundzwanzig Wörter enthält und zudem mit verschachtelten Nebensätzen, Fachbegriffen sowie langen zusammengesetzten Hauptwörtern wie Bundesverfassungsgerichtsentscheidung gespickt ist, dann wird er von vielen Lesern nur langsam verstanden.
Dieser Absatz wurde von der Redaktion überarbeitet. Schreiben Sie aktiv und konkret: Wer macht was?""",
        }],
}

# Run the Actor and wait for it to finish
run = client.actor("fast_data_asap/readability-seo-content-checker").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 '{
  "urls": [
    "https://en.wikipedia.org/wiki/Readability",
    "https://de.wikipedia.org/wiki/Lesbarkeit"
  ],
  "texts": [
    {
      "id": "entwurf-de",
      "text": "Gute Texte sind leicht zu lesen. Kurze Sätze helfen dabei, denn jeder Gedanke bekommt seinen eigenen Satz.\\nWenn ein Satz dagegen mehr als fünfundzwanzig Wörter enthält und zudem mit verschachtelten Nebensätzen, Fachbegriffen sowie langen zusammengesetzten Hauptwörtern wie Bundesverfassungsgerichtsentscheidung gespickt ist, dann wird er von vielen Lesern nur langsam verstanden.\\nDieser Absatz wurde von der Redaktion überarbeitet. Schreiben Sie aktiv und konkret: Wer macht was?"
    }
  ]
}' |
apify call fast_data_asap/readability-seo-content-checker --silent --output-dataset

```

## MCP server setup

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

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/8fzWuw4J2BXD3lRbJ/builds/r6BKjNjdlhMEB9DXa/openapi.json
