# Readability Analyzer (`maximedupre/readability-analyzer`) Actor

Analyze pasted text or uploaded TXT, Markdown, HTML, PDF, and DOCX files. Get readability scores, grade bands, sentence flags, word statistics, and score drivers in a clean Apify dataset.

- **URL**: https://apify.com/maximedupre/readability-analyzer.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Developer tools, Marketing, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / 1,000 analyzed words

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/platform/actors/running/actors-in-store#pay-per-event

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

### 📖 Readability analyzer for text and documents

Readability Analyzer checks pasted text and uploaded documents for reading difficulty. Paste copy, or upload a `.txt`, `.md`, `.html`, `.pdf`, or `.docx` file, and get one clean dataset row with readability formula scores, grade bands, sentence flags, text statistics, and score drivers.

Use it when you need a readability analyzer API for documentation, help-center articles, landing page copy, policy drafts, classroom material, content QA, or editorial workflows. The Actor analyzes the content you provide. It does not crawl web pages, require cookies, ask for a login, call an AI model, or need a third-party readability API key.

For a quick first run, keep the prefilled text and start the Actor. You will see how formula scores, hard sentences, word counts, reading time, and summary fields appear before you connect larger document checks through the Apify API, schedules, webhooks, or dataset exports.

### ✅ What this readability analyzer does

- Analyzes pasted text.
- Analyzes uploaded `.txt`, `.md`, `.html`, `.pdf`, and `.docx` files.
- Uses the uploaded file instead of pasted text when both are provided.
- Supports long text by splitting analysis into chunks internally.
- Returns 11 standard readability formula scores.
- Flags hard and very hard sentences.
- Lists long words, many-syllable words, and adverbs for each sentence.
- Returns text statistics such as letters, words, unique words, sentences, syllables, paragraphs, longest sentence, and time estimates.
- Adds deterministic summary fields such as readability band, approximate grade band, hardest sentence, and score drivers.
- Charges only successfully analyzed words.

The Actor is deterministic. The same extracted text returns the same kind of row each time. It is built for text-bearing files. Scanned or image-only PDFs do not produce readability scores because there is no OCR step.

### 📊 Data you get

Each dataset row represents one successfully analyzed text or file. Rows include:

| Field | Description |
| --- | --- |
| `content` | Source type, uploaded file name and extension when available, analyzed word count, and chunk count. |
| `summary` | Readability band, approximate grade band, average sentence length, hard sentence counts, hardest sentence, and score drivers. |
| `readability` | Flesch Reading Ease, Flesch-Kincaid, Gunning Fog, SMOG, Powers-Sumner-Kearl, FORCAST, Coleman-Liau, ARI, Dale-Chall, Spache, and Linsear Write scores. |
| `textStats` | Letter, word, unique word, sentence, syllable, paragraph, longest sentence, and reading/speaking/writing time statistics. |
| `sentences` | Sentence-level evidence with original text, cleaned text, word count, hard flags, long words, many-syllable words, and adverbs. |

You can export the dataset as JSON, CSV, Excel, XML, RSS, or HTML, or use the same output from the Apify API, webhooks, schedules, and integrations.

### 🚀 How to run it

1. Open the Actor input.
2. Paste text into **Text to analyze**, or upload a supported file in **File to analyze**.
3. Start the Actor.
4. Open the dataset to review the readability scores and sentence evidence.

If you provide both pasted text and a file, the file is analyzed. This is useful when you leave the example text in place but upload your own document.

### 🧾 Input example

```json
{
	"textContent": "Simple writing helps readers. Long sentences with unnecessary complexity can make useful information harder to understand."
}
````

For file runs, upload one `.txt`, `.md`, `.html`, `.pdf`, or `.docx` file in the Apify Console input form.

### 📤 Output example

```json
{
	"content": {
		"sourceType": "text",
		"fileName": null,
		"fileExtension": null,
		"wordCount": 17,
		"chunksAnalyzed": 1
	},
	"summary": {
		"readabilityBand": "standard",
		"approximateGradeBand": "8-10",
		"averageSentenceLength": 8.5,
		"hardSentenceCount": 0,
		"veryHardSentenceCount": 0,
		"hardestSentence": "Long sentences with unnecessary complexity can make useful information harder to understand.",
		"scoreDrivers": [
			{
				"driver": "Average sentence length",
				"value": "8.5 words",
				"impact": "helps readability"
			}
		]
	},
	"readability": {
		"fleschReadingEase": 63.8,
		"fleschKincaidGradeLevel": 8.2,
		"gunningFogIndex": 10.6,
		"smogIndex": 9.4,
		"powersSumnerKearl": 7.8,
		"forcast": 9.1,
		"colemanLiauIndex": 9.7,
		"automatedReadabilityIndex": 8.9,
		"daleChallReadabilityScore": 7.1,
		"spacheReadabilityScore": 6.4,
		"linsearWriteFormula": 8.5
	},
	"textStats": {
		"letterCount": 96,
		"wordCount": 17,
		"uniqueWordCount": 17,
		"sentenceCount": 2,
		"syllableCount": 27,
		"totalSyllables": 27,
		"averageSyllablesPerWord": 1.59,
		"longWordCount": 1,
		"paragraphCount": 1,
		"longestSentence": "Long sentences with unnecessary complexity can make useful information harder to understand.",
		"readingTimeSeconds": 6,
		"speakingTimeSeconds": 8,
		"writingTimeSeconds": 43
	},
	"sentences": [
		{
			"index": 1,
			"sentence": "Simple writing helps readers.",
			"cleanedSentence": "Simple writing helps readers.",
			"wordCount": 4,
			"isHard": false,
			"isVeryHard": false,
			"longWords": [],
			"manySyllableWords": [],
			"adverbs": []
		}
	]
}
```

### 💳 Pricing

This Actor uses pay-per-event pricing. It charges one `word-analyzed` event for each word successfully analyzed after text or file extraction. Failed inputs, unsupported files, and empty extracted documents do not emit dataset rows or charge analyzed-word events.

### ⚠️ Limits and caveats

- PDF support is for text-based PDFs. Scanned or image-only PDFs need OCR before readability analysis.
- The Actor analyzes one pasted text or one uploaded file per run.
- It does not fetch website URLs or crawl pages. Use a webpage text extractor first if your content lives on public web pages.
- It does not rewrite text, generate AI suggestions, judge tone, or score audience fit.
- Formula scores are deterministic readability metrics, not legal, medical, educational, or accessibility advice.

### ❓ FAQ

#### 📄 Can I analyze a PDF?

Yes, when the PDF contains selectable text. Scanned PDFs and image-only PDFs need OCR first.

#### 🧮 Does this Actor use AI?

No. It uses deterministic readability formulas and text statistics. It does not send your text to an LLM.

#### 🌐 Can I analyze a web page URL?

No. This Actor analyzes pasted text or uploaded files. Extract web page text first, then paste or upload the extracted text.

#### 📦 Why do I get one dataset row?

The product is a document-level readability audit. Sentence details are included inside the row so exports keep the full analysis together.

### 📝 Changelog

- 1.0: Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~readability-analyzer/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Other actors

- [Webpage Text Extractor ↗](https://apify.com/maximedupre/webpage-text-extractor) - Extract clean text from public web pages before readability analysis.
- [Profanity Checker ↗](https://apify.com/maximedupre/profanity-checker) - Check submitted text for blocked words and match evidence.
- [Unicode Text Inspector ↗](https://apify.com/maximedupre/unicode-text-inspector) - Find hidden Unicode characters, bidi controls, and homoglyphs in text.
- [YAML Validator & Converter ↗](https://apify.com/maximedupre/yaml-validator-converter) - Validate and convert YAML, JSON, and TOML documents.
- [XML JSON Converter ↗](https://apify.com/maximedupre/xml-json-converter) - Convert XML and JSON for API workflows and exports.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `textContent` (type: `string`):

Paste the text you want scored for readability.

## `fileUpload` (type: `string`):

Upload a .txt, .md, .html, .pdf, or .docx file when the content is already in a document.

## Actor input object example

```json
{
  "textContent": "Simple writing helps readers. Long sentences with unnecessary complexity can make useful information harder to understand.",
  "fileUpload": ""
}
```

# Actor output Schema

## `results` (type: `string`):

Open the dataset with one readability row for each analyzed text or file.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/readability-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/readability-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 '{}' |
apify call maximedupre/readability-analyzer --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Readability Analyzer",
        "description": "Analyze pasted text or uploaded TXT, Markdown, HTML, PDF, and DOCX files. Get readability scores, grade bands, sentence flags, word statistics, and score drivers in a clean Apify dataset.",
        "version": "1.0",
        "x-build-id": "SCr34BidIVIfhZuUO"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/maximedupre~readability-analyzer/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-maximedupre-readability-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/maximedupre~readability-analyzer/runs": {
            "post": {
                "operationId": "runs-sync-maximedupre-readability-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/maximedupre~readability-analyzer/run-sync": {
            "post": {
                "operationId": "run-sync-maximedupre-readability-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": {
                    "textContent": {
                        "title": "Text to analyze",
                        "type": "string",
                        "description": "Paste the text you want scored for readability.",
                        "default": "Simple writing helps readers. Long sentences with unnecessary complexity can make useful information harder to understand."
                    },
                    "fileUpload": {
                        "title": "File to analyze",
                        "type": "string",
                        "description": "Upload a .txt, .md, .html, .pdf, or .docx file when the content is already in a document.",
                        "default": ""
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
