Grammar Check API
Sapling's grammar check API takes a piece of text and returns grammar, spelling, and stylistic corrections as JSON edits — each with the sentence it belongs to, character offsets for the span to replace, a suggested replacement, and an error-type label. Because the endpoint returns edits rather than rewritten prose, your application decides how to render, filter, or apply them: inline underlines, a review queue, or a one-call auto-correct.
The endpoint is customizable through a dictionary and custom mappings. The Postman "Sample Code" does not require any coding.
| Grammar check API | At a glance |
|---|---|
| Endpoint | POST https://api.sapling.ai/api/v1/edits |
| Returns | JSON edits: sentence, offsets, replacement, error_type; optional applied_text |
| Input limits | Up to 100,000 characters per request; chunk above 4,000 to avoid timeouts |
| Languages | 14 languages plus autodetect; US/UK/AU/CA English and Simplified/Traditional Chinese varieties |
| SDKs | Python, JavaScript |
| Pricing | From $0.025 per 1,000 input characters, with volume discounts — see API Pricing |
As of November 2024, the default model is Sapling's Edits Large model, which catches 27% more errors with fewer false positives than the earlier 2024 Edits Small system. In December 2024, another model upgrade with improvements to spelling and punctuation as well as handling of financial, legal, programming, and technical documents was released.
Empirically, smaller models finetuned on customer-specific data outperform larger models. If you expect 100 million or more characters in usage volume per month, please contact us for how we can develop custom models. Sapling also has existing prebuilt models for applications such as healthcare/medicine.
Request Edits POST
Sample Code
- cURL
- JavaScript
- Python
- Python SDK
- JavaScript SDK
- Postman
curl -X POST https://api.sapling.ai/api/v1/edits \
-H "Content-Type: application/json" \
-d '{"key":"<api-key>", "text":"Hi, how are you doing.", "session_id": "test session"}'
You can also supply the API key via the Authorization header as a bearer token. If both the header and key field are sent, the key field takes precedence.
If you want to pretty-print JSON output so it's easier to read and you
have Python installed, you can pipe command line outputs into | python -m json.tool.
Example: echo "{\"text\": \"Some text\"}" | python -m json.tool
The results you get should match those from pasting the text on https://sapling.ai/grammar-check
If the results do not match, check that you're not adding additional newlines
or adding unnecessary character escaping (e.g. \\r or \\n) in your request.
import axios from 'axios';
async function run(text) {
try {
const response = await axios.post(
'https://api.sapling.ai/api/v1/edits',
{
"key": '<api-key>', // replace with your API key
"session_id": 'test session',
text,
},
);
const {status, data} = response;
console.log({status});
console.log(JSON.stringify(data, null, 4));
} catch (err) {
const { msg } = err.response.data;
console.log({err: msg});
}
}
run('Hi, how are you doing.'); // replace with the text you want to analyze
import requests
from pprint import pprint
try:
response = requests.post(
"https://api.sapling.ai/api/v1/edits",
json={
"key": "<api-key>",
"text": "Hi, how are you doing.",
"session_id": "test session"
}
)
if 200 <= response.status_code < 300:
resp_json = response.json()
edits = resp_json['edits']
pprint(edits)
else:
print("Error: ", str(response.status_code), response.text)
except Exception as e:
print("Error: ", e)
# pip: python -m pip install sapling-py
# uv: uv add sapling-py
from sapling import SaplingClient
from pprint import pprint
api_key ='<api-key>'
client = SaplingClient(api_key=api_key)
edits = client.edits('Hi, how are you doing.', session_id="test_session")
pprint(edits)
// npm install @saplingai/sapling-js
import { Client } from "@saplingai/sapling-js/client";
const apiKey = '<api-key>';
const client = new Client(apiKey);
client
.edits('Hi, how are you doing.')
.then(function (response) {
console.log(response.data);
})
Sample Response
{
"edits": [
{
"end": 22,
"error_type": "R:PUNCT",
"general_error_type": "Punctuation",
"id": "4bb963a4-cc19-523e-9bb2-9e6b5a270bfc",
"replacement": "doing?",
"sentence": "Hi, how are you doing.",
"sentence_start": 0,
"start": 16
}
]
}
Request Parameters
https://api.sapling.ai/api/v1/edits
HTTP method: POST
To avoid client side time-outs, we recommend breaking text longer than 4000 characters into chunks/paragraphs before sending to Sapling.
However, the endpoint will accept requests of up to 100,000 characters.
Sapling offers a chunking endpoint you can use here.
This endpoint will return HTTP Status 400 with feedback in the msg field if the request is invalid—e.g if the key is missing or incorrect.
The Edit API POST endpoint takes JSON parameters documented below:
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
Text to process for edits.
session_id: Optional String
Unique name or UUID of document or portion of text that is being checked. If not provided, defaults to current date in YYYYMMDD format.
user_id: Optional String
Use this along with the accept and reject endpoints to allow different users to maintain individual preferences.
lang: Optional String
Specifies language for grammar and spell checking.
Supported Languages
Specifies language for grammar and spell checking. Defaults to English, or the language specified in the dashboard.
Supported languages:
auto: Autodetect languagede: German (Deutsch)el: Greek (Ελληνικά)en: English (US/UK/CA/AU)es: Spanish (Español)fr: French (Français) (fr-frandfr-cacoming soon)it: Italian (Italiano)jp: Japanese (日本語)ko: Korean (한국어)nl: Dutch (Nederlands)pl: Polish (Polski)pt: Portuguese (Português) (pt-ptandpt-brcoming soon)sv: Swedish (Svenska)tl: Tagalogzh: Chinese (中文)
variety: Optional String
Supported Varieties
This option is currently available for: English, Chinese (中文). Specifies regional English/Chinese spelling options. The setting defaults to the configuration in the Sapling dashboard.
Supported varieties:
English:
us-variety: American Englishgb-variety: British Englishau-variety: Australian Englishca-variety: Canadian Englishnull-variety: Don’t suggest any changes based on English variety
Chinese (中文)
s-variety: Simplified Chineset-variety: Traditional Chinese
auto_apply: Optional Boolean
Default is false. If true, result with have extra field applied_text containing text with edits applied.
neural_spellcheck: Optional Boolean
Default is false. If true, system will also apply more aggressive spellcheck
to catch more spelling errors than the base system alone.
neural_spellcheck_mode: Optional String
Default is merge. Controls how neural spellcheck edits are merged with grammar edits
when neural_spellcheck is true. Possible values are:
merge: Removes spelling edits that overlap with grammar edits. Keeps all grammar edits and non-overlapping spelling edits.independent: Removes spelling edits only if they are exactly identical to a grammar edit. Allows spelling and grammar edits to coexist even if they target the same location, as long as they suggest different changes.prefer_spelling: Removes grammar edits that overlap with spelling edits. Keeps all spelling edits and non-overlapping grammar edits.
operations: Optional List of Strings
Default is []. Possible operations are described in the Postprocess documentation.
This will run postprocessing on outputs before returning results so you can enforce
stricter capitalization, punctuation, and whitespace removal.
ignore_edit_types: Optional List of Strings
Default is []. Possible types are:
articles_determiners: Do not suggestaortheand do not suggest removingaorthe.auxiliary_verbs: Do not suggest auxiliary verbs such asbe,can, orwill.capitalization: Do not suggest capitalizations.hyphens: Do not suggest hyphens such as inproduction ready->production-ready.punctuation: Do not suggest terminating punctuation such as.or?.whitespace: Do not suggest edits such as removing double spaces.
medical: Optional Boolean
Default is false. If true, the backend will apply Sapling's medical dictionary.
You can test the medical spellcheck system here.
team_id: Optional String (UUID or user_only)
- If
team_idis a UUID: apply user settings plus that specific team's settings (dictionary, custom mappings, etc.). Returns HTTP 403 if the team does not exist or the user is not a member of that team. - If
team_idisuser_only: apply only user settings (including user dictionary), with no team settings. - If omitted: apply user settings plus settings merged from all teams the user belongs to.
Response Parameters
The Edits POST endpoint returns JSON with parameters documented below:
edits: Array
Array of Edit objects for the text sent in the request.
Edit data structure:
{
"id": <str, UUID>, // Opaque edit id, used to give feedback
"sentence": <str>, // Unedited sentence
"sentence_start": <int>, // Offset of sentence from start of text
"start": <int>, // Offset of edit start relative to sentence
"end": <int>, // Offset of edit end relative to sentence
"replacement": <str>, // Suggested replacement
"error_type": <str>, // Error type, see "Error Categories"
"general_error_type": <str>, // See "Error Categories"
}
Tips
- Check the status code of the result and any error logs.
- Unless you're sending very large requests, the requests should rarely fail or time out, but you can follow these instructions to implement a retry mechanism.
- Use the accept/reject endpoints below if you would like Sapling to learn to stop making specific suggestions.
- Follow the guidelines for applying edits.
Accept Edit POST
Use this API endpoint to have Sapling adapt its system over time.
Each suggested edit has an edit UUID. You can pass this information back to Sapling to indicate the edit suggestion was helpful. For each unique edit in each document, use the accept or reject API endpoint only once in total.
Request Parameters
import requests
key = '<api-key>'
edit_id = '<EDIT_ID>'
url = f'https://api.sapling.ai/api/v1/edits/{edit_id}/accept'
data = {
'key': key,
'session_id': 'Test Document UUID',
}
try:
resp = requests.post(url, json=data)
if 200 <= resp.status_code < 300:
resp_json = resp.json()
assert resp.status_code == 201
else:
print("Error: ", str(resp.status_code), resp.text)
except Exception as e:
print("Error: ", e)
https://api.sapling.ai/api/v1/edits/<edit_id>/accept
HTTP method: POST
Note that the edit_id is part of the URL. The Accept API POST endpoint takes a variety of JSON parameters documented below:
edit_id: String (UUID)
ID of an Edit.
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.
session_id: Optional String
Unique name or UUID of document or portion of text that is being checked. If not provided, defaults to current date in YYYYMMDD format.
user_id: String
Pass this in to associate the accept event with a specific user. This allows different users to maintain different preferences.
Response Parameters
HTTP status code 201.
Reject Edit POST
Use this API endpoint to have Sapling not recommend the same edit anymore.
Each suggested edit has an edit UUID. You can pass this information back to Sapling to indicate the edit suggestion was not helpful. For each unique edit in each document, use the accept or reject API endpoint only once in total.
Request Parameters
import requests
key = '<api-key>'
edit_id = '<EDIT_ID>'
url = f'https://api.sapling.ai/api/v1/edits/{edit_id}/reject'
data = {
'key': key,
'session_id': 'Test Document UUID',
}
try:
resp = requests.post(url, json=data)
if 200 <= resp.status_code < 300:
resp_json = resp.json()
assert resp.status_code == 201
else:
print("Error: ", str(resp.status_code), resp.text)
except Exception as e:
print("Error: ", e)
https://api.sapling.ai/api/v1/edits/<edit_id>/reject
HTTP method: POST
Note that edit_id is part of the URL. The Reject API POST endpoint has JSON parameters documented below:
edit_id: String (UUID)
ID of an Edit.
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.
session_id: Optional String
Unique name or UUID of article or portion of text that is being checked. If not provided, defaults to current date in YYYYMMDD format.
user_id: String
Pass this in to associate the reject event with a specific user. This allows different users to maintain different preferences.
Response Parameters
HTTP status code 201.
A single call to the reject endpoint for a specific edit_hash and user prevents that edit
from being returned again (as long as data persistence is enabled).
Similar edits are suppressed for 24 hours based on their similarity hashes, though behavior is less predictable for non-identical text. If you encounter unexpected behavior, please provide the exact text and requests sent and we can investigate further.
Ignored edits are only available by querying the database due to the large number of possible events with even dozens of users.
However, ignore events are used to determine when multiple users reject the same edit
so that the unmodified string can be proposed as a dictionary entry;
this does not affect whether an individual user sees the edit again.
The thresholds for a dictionary entry default to 2 separate users ignoring
an edit each at least once with a ratio of at least 2 ignores to 1 accept.
Related grammar API endpoints
- Spellcheck — spelling only; faster and cheaper when you don't need grammar.
- Applying Edits — how to apply the returned offsets correctly.
- Error Categories — what each
error_typeandgeneral_error_typemeans. - Dictionary and Custom Mappings — exempt your own terms, or enforce your own corrections.
- Advanced Edits — simplification, confidence, and DEI suggestions beyond grammar.
- JavaScript SDK and Python SDK — wrappers, plus a drop-in grammar-checking UI for web apps.
- Comparison of grammar and spell check APIs — how Sapling's grammar API compares to the alternatives.
Frequently asked questions
What is a grammar check API?
A grammar check API is an HTTP endpoint that takes text as input and returns a list of suggested corrections rather than corrected prose. Sapling's grammar check API returns each correction as a JSON edit with the sentence it belongs to, character offsets for the span to replace, the suggested replacement, and an error-type label, so your application can render, filter, or apply corrections itself.
Which languages does the grammar API support?
Fourteen languages — Chinese, Dutch, English, French, German, Greek, Italian, Japanese, Korean,
Polish, Portuguese, Spanish, Swedish, and Tagalog — plus an auto setting that detects the
language. English additionally supports American, British, Australian, and Canadian spelling
varieties, and Chinese supports Simplified and Traditional.
How much text can I check in one request?
The endpoint accepts up to 100,000 characters per request, but we recommend splitting text longer than 4,000 characters into paragraphs or chunks to avoid client-side timeouts. The chunking endpoint can do that split for you.
Does the grammar API return the corrected text?
By default it returns edits, not rewritten text. Set auto_apply to true and the response
includes an applied_text field with every edit already applied. You can also apply edits yourself
from the offsets and replacements — see Applying Edits.
What is the difference between the grammar check API and the spellcheck endpoint?
The edits endpoint covers grammar, spelling, and stylistic corrections. The separate spellcheck endpoint only checks spelling, which makes it faster and cheaper when your application doesn't need grammar or phrase-level suggestions.
Can I stop the grammar API from suggesting certain edits?
Yes, in three ways: ignore_edit_types suppresses whole categories such as capitalization,
punctuation, or hyphens per request; a dictionary exempts specific terms
such as product names and jargon; and custom mappings enforce your own
preferred corrections. The reject endpoint above also teaches the system to stop making a
specific suggestion over time.
Is there a free tier for the grammar check API?
Yes. A new API key comes with a free quota of 50,000 characters per day and 250,000 characters per month — see Usage and Pricing. Paid usage is billed per input character with volume discounts, starting at $0.025 per 1,000 characters.