Count paragraphs
Count the paragraphs in a text by its blank lines: three short paragraphs about alpha, beta and gamma give a total of 3. Lines that are only wrapped, with no empty line between them, stay one paragraph. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
A paragraph counter turns free-form prose into a single integer you can trust in editors, CMS pipelines, and homework checks. Paste any non-empty string; the tool detects blank-line breaks—one or more empty or whitespace-only lines between blocks—and returns how many non-empty paragraphs remain after discarding pure blank regions. Single newlines inside a block stay in the same paragraph so hard-wrapped lines from email or chat do not inflate the total. Writers, teachers, QA scripts, and content APIs need that same deterministic blank-line rule without opening a full word processor.
How blank-line paragraph counting works
In plain text, a paragraph is conventionally a block of non-empty content separated from the next block by at least one blank line. This counter follows that everyday definition rather than guessing sentence boundaries or HTML tags. First the input is checked: missing text, a non-string value, or a string that is empty after trimming whitespace is rejected.
Newlines are normalized so Windows CRLF, old Mac CR, and Unix LF all become a single LF form before splitting. The splitter then looks for one or more consecutive lines that are empty or contain only spaces or tabs; those runs are the breaks. Each remaining block is trimmed of outer blank edges; if anything non-whitespace remains, it counts as one paragraph.
Leading blank lines, trailing blank lines, and double or triple spacing between blocks never create empty paragraphs, so a document that starts with two blank lines still begins counting at the first real block. A single long block with only hard wraps (newline but no blank line) is one paragraph even when it spans many visual lines. That matches how most style guides and Markdown editors treat prose when authors separate ideas with a blank line.
When you need word counts or sentence counts, use dedicated tools; this landing is only about blank-line paragraph totals.
Practical tips, limits, and when to use this tool
Use this capability when the search intent is count paragraphs, paragraph counter, or blank-line paragraph total online. Paste a draft essay, convert once, and show students or editors the paragraph total next to a length target. Keep intentional single-spaced hard wraps in mind: lines joined only by a single newline stay one paragraph, which is correct for reflowed plain text and wrong only if you meant each visual line to be its own paragraph—in that case insert blank lines first or use a line counter instead.
HTML and Markdown source with tags still counts blank lines in the raw string; strip markup first if you want prose-only blocks. This landing is not a sentence counter, not a word-count tool, not a PDF page or word stats capability, and not an NLP topic segmenter that invents breaks without blank lines. Prefer a word or character counter when you need those metrics; prefer this capability when humans already separated ideas with blank lines and you only need the total.
When teaching writing structure, compare the same text with and without blank lines so learners see how spacing defines paragraph boundaries in plain text.
What you can do with it
Essay and homework length checks
Students paste draft prose; teachers or LMS scripts confirm the paragraph total against assignment rules before submission.
FAQ
How does the tool decide where a paragraph ends?
It splits on blank-line breaks: one or more consecutive empty or whitespace-only lines after newline normalization. Single newlines inside a block stay in the same paragraph.
Do multiple blank lines create empty paragraphs?
No. Leading, trailing, and repeated blank lines are ignored for counting; only non-empty content blocks increase the total.
Is the paragraph counter free?
The browser tool is free and runs locally.
Does a hard-wrapped paragraph count as several?
No. A single line break inside a block keeps it as one paragraph, so text wrapped by an email or chat app does not inflate the total. Only a blank line starts a new paragraph.
Does a line with only spaces count as a blank line?
Yes. A line that contains nothing but spaces or tabs works as a break, exactly like an empty line, so invisible spaces left in a draft do not merge two paragraphs.
Related tools
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/str/paragraph-count \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"First paragraph.\n\nSecond paragraph."}'const res = await fetch("https://api.kit.forhosting.com/str/paragraph-count", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "First paragraph.\n\nSecond paragraph."
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/str/paragraph-count",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "First paragraph.\n\nSecond paragraph."
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/str/paragraph-count", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"First paragraph.\\n\\nSecond paragraph."}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"First paragraph.\n\nSecond paragraph."}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/str/paragraph-count", 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": "First paragraph.\n\nSecond paragraph."
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "str.paragraph_count",
"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 | 100000 |
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. |
Technical notes
Empty or whitespace-only input is rejected with a clear invalid_input error so automation never treats a blank paste as zero success.
How to call the API and what the response contains
Prefer sending the raw document body rather than pre-collapsing newlines when you want true blank-line semantics; collapsing everything to one line would force a single paragraph. Pipelines that process essays, release notes, or multi-block emails can branch on count before further analysis. Send a JSON body with a required string field text (aliases input, value, string, s, content, and body). The value must be a non-empty string after whitespace is trimmed and must not exceed one hundred thousand characters so a single request cannot exhaust Worker or browser memory on huge paste dumps. On success the response echoes input as the original string you sent, text as the trimmed working string, paragraph_count and count as the same integer total, paragraphs as an ordered array of the non-empty blocks after blank-line splitting, and message as a short English summary that reports how many paragraphs were counted. Failed validation—missing text, a non-string value, an oversize payload, or empty content after trim—returns invalid_input and is never charged. Pricing is a flat $0.002 per successful request with unit item and zero marginal unit price. When integrating, assert on paragraph_count for the total, optionally compare paragraphs length to that total, and treat invalid_input as a client bug for blank form submissions rather than a billing event.
Practical tips, limits, and when to use this tool
Round-trip checks for tests are easy: feed two short lines separated by a blank line and expect paragraph_count two with two array entries; feed one unbroken block and expect one; deliberately send empty string or spaces to confirm invalid_input and the message that asks for a non-empty string. Failed tasks that return invalid_input do not consume prepaid balance, which keeps form validation and CI negative tests cheap.
Integration use cases
CMS and release-note pipelines
Normalize multi-block release notes or blog drafts and assert paragraph_count before publishing or translating each block.
Unit tests for text processors
Generate known-good multi-paragraph fixtures and empty-input rejections for editors, email parsers, and markdown pipelines.
Technical questions
What happens on empty input?
Missing text, non-string values, or strings that are empty after trimming return invalid_input and are never charged.
Does this count words or sentences?
No. It only returns paragraph_count (and count), the paragraphs array, and a short message. Use other tools for words or sentences.