Adjust reading level
Every audience reads at a different level, and a single document rarely fits all of them. The Reading Level API takes a source text and a target CEFR band and returns a rewrite that preserves meaning while resetting vocabulary, sentence length and structure to match. Feed it a policy manual for a general public or a technical brief for language learners, and it comes back calibrated, not just simplified.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
Who actually needs this
Publishers building graded readers, HR teams writing onboarding material for a multilingual workforce, and edtech platforms that serve the same lesson to students at different proficiencies all run into the same wall: rewriting by hand for every level does not scale. This endpoint exists for that gap, turning one master text into a family of versions without hiring a rewriter for each rung of the ladder.
What the CEFR scale actually measures
The Common European Framework of Reference for Languages was built in the late 1990s to give teachers and institutions a shared vocabulary for proficiency, from A1 survival phrases to C2 near-native command of nuance and register. It has since become the default yardstick well beyond Europe, used by exam boards, immigration authorities and language apps alike. Targeting a CEFR band is therefore not a stylistic guess; it is a request against a well-documented, internationally recognized standard.
How the rewrite is built
Submit the source text and the desired level to POST /text/reading-level, and the task queues asynchronously with a task_id returned immediately. The engine analyzes sentence complexity, lexical frequency and idiom density in the original, then reconstructs the passage at the target band, keeping facts, names and intent intact. You get the result back through a signed webhook the moment it finishes, or by fetching a signed link that stays valid for 24 hours.
Where it slots into a pipeline
Because it is a plain HTTP endpoint with async delivery, the reading-level engine drops cleanly into a CMS publish hook, a course-authoring tool, or a batch job that regrades a whole content library overnight. Retries are automatic on transient failures, and a task that ultimately fails is never billed, so a scheduled overnight run can be trusted to report a clean bill or a clear error, nothing in between.
What to expect from the output
The rewrite is not a mechanical word-swap: it restructures clauses, adjusts connective words and trims or expands explanations so the result reads naturally at the requested level, not like a native speaker forcing themselves to sound simple. Longer or highly technical inputs take proportionally longer to process, which is exactly why the API is async instead of holding a connection open.
What you can do with it
Graded reader libraries
A language-learning app converts one news article into six versions, A1 through C2, so every subscriber reads the same current-events story at their own level.
Multilingual onboarding docs
An HR platform rewrites its compliance handbook to B1 English for staff who studied the language as a second one, cutting comprehension questions during training.
Accessible public communication
A city government simplifies benefits-program notices to A2/B1 so residents with limited formal education can act on them without a translator or caseworker.
Textbook adaptation at scale
A publisher batch-processes an entire chapter library overnight to produce a lower-level companion edition, instead of commissioning a manual rewrite per chapter.
FAQ
What levels does the reading level API support?
All six CEFR bands, A1, A2, B1, B2, C1 and C2, specified as the target parameter in the request.
Is there a free tier to test the API?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
How is the reading level rewrite priced?
$0.003 per request plus $0.0135 per 1,000 words processed, billed only for successful tasks.
Does it change the meaning of the text?
No, the engine preserves facts, names and intent; it adjusts vocabulary, sentence length and structure, not the underlying content.
How do I get the result back?
Either a signed webhook call the moment the task finishes, or a signed download link that stays valid for 24 hours; after that the data is deleted.
What happens if a task fails?
The system retries automatically up to three times; if it still fails you get a clear error and you are never charged for it.
Can I process a whole book or long document at once?
Yes, the endpoint is asynchronous specifically so longer inputs can be queued and processed without holding a connection open; larger texts simply take longer to return.
Is my content used to train models?
No, submitted text is used only to produce your result and is deleted after the retention window, never used for training.
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, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/text/reading-level \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"…"}'const res = await fetch("https://api.kit.forhosting.com/text/reading-level", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/text/reading-level",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/text/reading-level", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/text/reading-level", 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": "…"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "text.reading_level",
"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_tokens | 20000 |
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. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |