Word count by paragraph
Word count by paragraph reveals pacing and balance that a single document total cannot show.
Run — free
Paste text with paragraphs separated by blank lines, and the tool reports each paragraph's word count, the total, and the average. It also flags paragraphs that sit far above or below that average, giving editors, students, marketers, and technical writers a quick way to find sections that may need attention without uploading a file or manually counting words.
Prepare text so paragraph boundaries are clear
Paste plain text into the input and leave at least one completely blank line between paragraphs. A normal line break inside a paragraph does not create a new paragraph, so wrapped prose and deliberate line breaks remain together. Spaces or tabs on a blank separator line are accepted. Leading and trailing whitespace is removed before analysis, and repeated blank lines still represent one boundary. The counter recognizes sequences of letters and numbers as words and keeps common internal apostrophes and hyphens together, so terms such as “writer's” and “well-paced” count as one word. Punctuation by itself does not increase a count. Paragraphs containing symbols but no words can still appear with a count of zero when they occur between valid boundaries. If the entire input is empty or whitespace only, the request fails because there are no paragraphs to analyze. This explicit structure makes results repeatable across drafts and avoids guessing whether every visual line is intended to be a separate paragraph.
Understand the average and the flags
The tool first counts every paragraph, adds those counts to produce the document total, and divides that total by the number of paragraphs. The displayed average is rounded to two decimal places, while classification uses the unrounded value. A paragraph is flagged as far above average only when its count is greater than 150 percent of the mean. It is flagged as far below average only when its count is less than 50 percent of the mean. Values exactly on either boundary remain within average, which keeps the rule predictable. These flags are signals, not writing judgments. Dialogue, headings, transitions, examples, and conclusions naturally have different shapes, and a zero-word or very short paragraph may be intentional. Use the result to direct attention, then read the surrounding passage before editing. Because every classification is based on the current document, adding or removing text can shift the average and consequently change more than one flag on the next run.
Turn the report into a practical revision pass
Start with paragraphs marked far above average and check whether each one carries several ideas that would be clearer as separate units. Look for a topic change, a long example, or a transition that can become a natural split. Next, inspect paragraphs marked far below average. A short paragraph may create useful emphasis, but it may also be an unsupported claim, a stranded sentence, or a fragment that belongs with a neighbor. After revising, run the complete text again rather than comparing isolated counts, because the average describes the current set of paragraphs. The numbered output preserves source order, making it easy to locate each result even though the response does not repeat potentially sensitive text. Teams can also call the API in editorial checks, content pipelines, or learning tools for $0.002 per request. The algorithm is deterministic, uses no model or network service, and returns the same report whenever the input is unchanged.
What you can do with it
Balance an article draft
Find dense sections that may need splitting and unusually brief sections that may need support.
Review student writing
Give learners an objective map of paragraph length before discussing structure, evidence, and pacing.
Automate editorial checks
Add deterministic paragraph counts and outlier flags to a publishing or quality-assurance workflow.
FAQ
What separates one paragraph from another?
One or more blank lines separate paragraphs. A single line break without a blank line stays inside the same paragraph.
When is a paragraph flagged as far above average?
Its word count must be greater than 150 percent of the unrounded document average.
When is a paragraph flagged as far below average?
Its word count must be less than 50 percent of the unrounded document average.
Does punctuation count as a word?
No. The counter counts letter and number sequences, retaining common internal apostrophes and hyphens within a word.
How much does the API cost?
Each API request costs $0.002. The browser version can run locally for free.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/write/word-count-by-paragraph \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"A short opening paragraph.\n\nThis second paragraph contains several more words so its length can be compared with the opening."}'const res = await fetch("https://api.kit.forhosting.com/write/word-count-by-paragraph", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "A short opening paragraph.\n\nThis second paragraph contains several more words so its length can be compared with the opening."
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/write/word-count-by-paragraph",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "A short opening paragraph.\n\nThis second paragraph contains several more words so its length can be compared with the opening."
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/write/word-count-by-paragraph", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"A short opening paragraph.\\n\\nThis second paragraph contains several more words so its length can be compared with the opening."}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"A short opening paragraph.\n\nThis second paragraph contains several more words so its length can be compared with the opening."}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/write/word-count-by-paragraph", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "A short opening paragraph.\n\nThis second paragraph contains several more words so its length can be compared with the opening."
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "write.word_count_by_paragraph",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_chars | 1000000 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |