Skip to main content

Plain Language Simplification API

The simplify endpoint rewrites a text in plain language at a reading level you choose — for plain-language compliance (e.g. agencies covered by the US Plain Writing Act), healthcare patient communications, legal notices, customer support and education. The rewrite keeps all of the text's content, structure and language: nothing is summarized, dropped or translated. To shorten a text instead, see summarize.

The improvement is verifiable: when the text's language supports readability scoring, the response includes a deterministic before/after readability block (Flesch-Kincaid grade level and reading ease, the same formulas as the statistics endpoint), so you can see — and show your users — how far the rewrite actually moved the score.

Terms that must survive the rewrite (product names, defined legal terms) can be listed in preserve_terms; a rewrite that drops one is refused server-side rather than returned.

Sample Code​

curl -X POST https://api.sapling.ai/api/v1/simplify \
-H "Content-Type: application/json" \
-d '{"key":"<api-key>", "text":"The party of the first part shall remit payment within thirty (30) days of receipt of the invoice.", "reading_level": "plain", "preserve_terms": ["invoice"]}'

Sample Response​

{
"simplified": "You must pay within 30 days of getting the invoice.",
"reading_level": "plain",
"lang": "en",
"readability": {
"before": {"grade": 12.3, "ease": 42.1},
"after": {"grade": 5.8, "ease": 78.4}
}
}

Batch Requests​

To simplify many short texts — a set of notice paragraphs, a queue of support replies — in one request, send texts (a list of 1–10 strings) instead of text. The same reading_level, preserve_terms and lang (when provided) apply to every item, and the combined length of all items may be up to 5,000 characters (the same cap as a single text). Exactly one of text and texts must be provided.

curl -X POST https://api.sapling.ai/api/v1/simplify \
-H "Content-Type: application/json" \
-d '{"key":"<api-key>", "texts": ["The party of the first part shall remit payment.", "Utilize the aforementioned portal heretofore described."]}'

The batch response is {"results": [...]} with one entry per input, in input order; each entry has exactly the single-response shape above. With lang omitted, each item's language — and therefore its readability scores — is detected per item, so a batch may legitimately mix languages:

{
"results": [
{
"simplified": "You must pay.",
"reading_level": "plain",
"lang": "en",
"readability": {
"before": {"grade": 11.2, "ease": 47.9},
"after": {"grade": 2.1, "ease": 95.7}
}
},
{
"simplified": "Use the portal described above.",
"reading_level": "plain",
"lang": "en",
"readability": {
"before": {"grade": 14.8, "ease": 12.3},
"after": {"grade": 4.4, "ease": 83.2}
}
}
]
}

Items are billed individually (a batch of N costs the same as N single requests), and each item is cached the same way as a single request — batches and single calls share the cache. If any item fails to process, the whole request returns a 502 and nothing is billed; the items that did succeed are already cached, so a retry only re-runs the failures.

Request Parameters​

POST to https://api.sapling.ai/api/v1/simplify

key: String
32-character API key. Can also be supplied via the Authorization header as a bearer token; if both are provided, the key parameter takes precedence.

text: String
The text to simplify, up to 5,000 characters. Sent to the model exactly as submitted — markup and line structure are preserved, not stripped — and the rewrite gives you your document back with its structure intact. Empty or whitespace-only text returns a 400. The text is treated as untrusted data: instructions inside it are ignored and it is rewritten on its content alone. Provide exactly one of text and texts.

texts: List[String]
Batch form (see Batch Requests): 1–10 texts to simplify in one request, each treated exactly like text above, with a combined length of up to 5,000 characters. An empty or whitespace-only item returns a 400 naming its index. The response becomes {"results": [...]}, one entry per item in input order.

reading_level: String, optional — defaults to plain
The target audience:

  • plain (default): plain-language style for a general audience, in the spirit of plainlanguage.gov — short sentences, everyday words, active voice.
  • elementary: ~US grade 3–5.
  • middle_school: ~US grade 6–8.
  • high_school: ~US grade 9–10.

preserve_terms: List[String], optional
Up to 20 terms (each up to 100 characters) the rewrite must keep rather than paraphrase away — product names, trademarks, defined legal terms. Enforced structurally: a rewrite that drops a term the source contains is refused with a 502 rather than returned. Matching is case-insensitive with whitespace collapsed, so line re-wrapping does not count as dropping a term — but by the same token a change in casing alone (e.g. iPhone → Iphone) is not treated as a dropped term, so where the exact capitalization of a term matters, verify it in the returned text.

lang: String, optional — defaults to auto-detection
ISO 639-1 code (e.g. en) selecting the readability formula for the before/after scores. Omit to auto-detect (falls back to en); on the batch form, detection runs per item, so each result carries its own lang. This never changes the rewrite itself — the output always stays in the text's own language.

Response Parameters​

simplified: String
The rewritten text: same content, same language, same document structure, at the target reading level.

reading_level: String
The reading level that was applied.

lang: String
The language the readability scores were computed for — the value you passed, or the detected language when omitted.

readability: Object, optional
{"before": {"grade": ..., "ease": ...}, "after": {"grade": ..., "ease": ...}} — deterministic Flesch-Kincaid grade level and reading ease for the submitted text and the rewrite, computed over the prose (markup excluded) with the same formulas as the statistics endpoint. Omitted (never an error) when the language has no supported readability formula or the text has no scoreable prose.

Errors​

StatusMeaning
400Validation error — missing, empty or oversized text (or a texts item, named by index), both or neither of text/texts, an unknown reading_level, or invalid preserve_terms. The body is {"msg": "..."}.
401 / 403Missing or invalid API key.
429Rate limit exceeded or key over capacity.
502{"msg": "Unexpected error simplifying text."} — the rewriting model failed or the rewrite dropped a preserved term; safe to retry. Not billed and not cached (on the batch form the whole request is not billed, but items that already succeeded stay cached — see Batch Requests).

Tips​

  • Score first, rewrite second. The statistics endpoint returns the same readability scores on their own — use it to decide which documents need simplifying, then send only those here.
  • Pick the level for your audience, not the lowest one. plain is the right default for public, legal and healthcare communications; elementary trades more nuance away than most adult-facing content wants.
  • List your defined terms. In legal and healthcare text, capitalized defined terms ("Subscriber", "the Provider") and product names should go in preserve_terms so the rewrite can't paraphrase them away.
  • Check the delta. readability.after.grade tells you whether the text landed near your target; a document dense with unavoidable technical terms may need a glossary rather than a lower reading level.
  • Results are cached on Sapling's side for about three days, keyed on the text, reading level and preserve terms — re-running the same document returns the same rewrite; changing any of them re-generates.