LanguageTool API
Free grammar and spell checking API with no key: detect spelling, grammar and style errors in 25+ languages with suggested corrections. Tested GET and POST.
Endpoint tested and returned HTTP 200 on 2026-08-19
What is the LanguageTool API?
LanguageTool is a free, key-free grammar and spell checking API supporting more than 25 languages. It returns detected errors with their position, rule category and suggested replacements.
LanguageTool is the open-source engine behind a great many writing assistants, and its public API is usable without a key. Send text and a language code, and get back structured matches with character offsets and suggested corrections.
The check endpoint is a POST with form-encoded parameters, not JSON — a detail that catches people out. Each match includes an `offset` and `length` into the original string, which is what lets you highlight errors in place rather than just listing them.
Quick facts
- Base URL
https://api.languagetool.org/v2- Authentication
- The public API needs no key at a limited rate. Paid plans and self-hosting remove the limits.
- Rate limit
- About 20 requests per minute and 75KB of text per minute per IP on the free public API.
- Pricing
- Free public tier; paid plans and free self-hosting available.
- CORS
- Enabled — callable directly from browser JavaScript
- Official docs
- Read the docs
How to use the LanguageTool API
Every request below was executed against the live API on 2026-08-19, and the response shown is the real body it returned — not an illustration.
1. List supported languages
GET https://api.languagetool.org/v2/languages
curl 'https://api.languagetool.org/v2/languages'const res = await fetch("https://api.languagetool.org/v2/languages");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);import requests
res = requests.get("https://api.languagetool.org/v2/languages", timeout=20)
res.raise_for_status()
print(res.json())[
{
"name": "Arabic",
"code": "ar",
"longCode": "ar"
},
{
"name": "Asturian",
"code": "ast",
"longCode": "ast-ES"
},
{
"name": "Belarusian",
"code": "be",
"longCode": "be-BY"
},
{
"name": "Breton",
"code": "br",
"longCode": "br-FR"
},
{
"name": "Catalan",
"code": "ca",
"longCode": "ca-ES"
},
{
"name": "Catalan (Valencian)",
"code": "ca",
"longCode": "ca-ES-valencia"
},
{
"name": "Catalan (Balearic)",
"code": "ca",
"longCode": "ca-ES-balear"
},
{
"name": "Danish",
"code": "da",
"longCode": "da-DK"
},
{
"name": "German",
"code": "de",
"longCode": "de"
},
{
"name": "German (Germany)",
"code": "de",
"longCode": "de-DE"
},
{
"name": "German (Austria)",
"code": "de",
"longCode": "de-AT"
},
{
"name": "German (Swiss)",
"code": "de",
"longCode": "de-CH"
},
{
"name": "Simple German",
"code": "de-DE-x-simple-language",
"longCode": "de-DE-x-simple-language"
},
{
"name": "Greek",
"code": "el",
"longCode": "el-GR"
},
{
"name": "English",
"code": "en",
"longCode": "en"
},
{
"name": "English (US)",
"code": "en",
"longCode": "en-US"
},
{
"name": "English (GB)",
"code": "en",
"longCode": "en-GB"
},
{
"name": "English (Australian)",
"code": "en",
"longCode": "en-AU"
},
{
"name": "English (Canadian)",
"code": "en",
"longCode": "en-CA"
},
{
"name": "English (New Zealand)",
"code": "en",2. Check text for grammar errors with a POST request
POST https://api.languagetool.org/v2/check
curl -X POST 'https://api.languagetool.org/v2/check' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'text=This%20are%20a%20test&language=en-US'const res = await fetch("https://api.languagetool.org/v2/check", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: JSON.stringify(text=This%20are%20a%20test&language=en-US),
});
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);import requests
headers = {
"Content-Type": "application/x-www-form-urlencoded",
}
payload = text=This%20are%20a%20test&language=en-US
res = requests.post("https://api.languagetool.org/v2/check", headers=headers, json=payload, timeout=20)
res.raise_for_status()
print(res.json()){
"software": {
"name": "LanguageTool",
"version": "6.9-SNAPSHOT",
"buildDate": "2026-08-19 17:50:03 +0000",
"apiVersion": 1,
"premium": true,
"premiumHint": "You might be missing errors only the Premium version can find. Contact us at support<at>languagetoolplus.com.",
"status": ""
},
"warnings": {
"incompleteResults": false
},
"language": {
"name": "English (US)",
"code": "en-US",
"detectedLanguage": {
"name": "English (US)",
"code": "en-US",
"confidence": 0.99977934,
"source": "ngram"
}
},
"matches": [
{
"message": "The singular demonstrative pronoun ‘this’ does not agree with the plural verb ‘are’. Did you mean “these”?",
"shortMessage": "Grammatical problem: use ‘these’",
"replacements": [
{
"value": "These"
}
],
"offset": 0,
"length": 4,
"context": {
"text": "This are a test",
"offset": 0,
"length": 4
},
"sentence": "This are a test",
"type": {
"typeName": "Other"
},
"rule": {
"id": "THIS_NNS",
"subId": "5",
"sourceFile": "grammar.xml",
"description": "'this' vs. 'these'",
"issueType": "grammar",
"category": {
"id": "GRAMMAR",
"name": "Grammar"
},
"isPremium": false,
"confidence": 0.64
},
"ignoreForIncompleteSentence": false,
"contextForSureMatch": 1
},
{
"message": "The verb ‘are’ is plural. Did you mean: “is”? Did you use a verbParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
text | string | Required | The text to check, on the POST /check endpoint. This are a test |
language | string | Required | Language code, or `auto` to detect. en-US |
enabledOnly | boolean | Optional | Only run explicitly enabled rules. false |
disabledRules | string | Optional | Comma-separated rule ids to skip. WHITESPACE_RULE |
Response fields
(languages) name / code / longCodestring- Supported language names and codes.
matches[].messagestring- Human-readable explanation of the problem.
matches[].offset / lengthinteger- Character position and span of the error in your text.
matches[].replacementsarray- Suggested corrections, best first.
matches[].rule.categoryobject- Error category such as Grammar or Typos.
softwareobject- Engine name and version.
What you can build with the LanguageTool API
- Add grammar and spell checking to a text editor or CMS
- Validate user-generated content before publishing
- Build a writing assistant with inline error highlighting
- Check multilingual content with one API
Common errors and how to fix them
400 on the check endpoint
Parameters must be form-encoded, not JSON.
Fix: POST with Content-Type: application/x-www-form-urlencoded and text=...&language=...
429
Free tier limit exceeded.
Fix: Around 20 requests per minute and 75KB per minute. Batch text into fewer, larger requests, or self-host.
Offsets misaligned
Offsets are character positions in the original text.
Fix: Apply replacements from the end backwards so earlier offsets stay valid.
LanguageTool API — frequently asked questions
Is the LanguageTool API free?
Yes, the public API works with no key at roughly 20 requests per minute. Paid plans raise the limits, and the engine is open source so you can self-host without limits.
Why does my check request fail with a 400?
The /check endpoint expects form-encoded parameters, not a JSON body. Set Content-Type to application/x-www-form-urlencoded.
How do I apply the suggested corrections?
Each match gives an offset and length into your original text plus ranked replacements. Apply them from the end of the string backwards so earlier offsets remain valid.
How many languages are supported?
More than 25, including English variants, German, French, Spanish, Portuguese, Dutch and Russian. Request /v2/languages for the current list.
Tools that pair with this API
Word Counter
Count words, characters, sentences, paragraphs and estimated reading time instantly. Free online word counter for essays, blogs and social media.
Character Counter
Count characters with and without spaces in real time and check limits for Twitter/X, Instagram captions, meta descriptions and SMS messages.
Text Compare
Compare two texts online free and highlight every difference. A private text comparison tool that finds matches and changes right in your browser.
LanguageTool is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 2026-08-19; always check the official documentation before relying on this API in production, as terms and limits can change.