Inclusive Language API
The Inclusive Language endpoint finds non-inclusive or biased wording in a text: gendered defaults ("chairman", "he" for an unknown person), ableist idioms ("crazy", "tone-deaf"), ageist framing ("digital natives"), outdated or loaded terms for groups, and classist or appearance-based language. Each issue comes back with a category, a severity, a short explanation, a neutral replacement and — for all but the rare passage that can't be located — its exact character offsets, so you can underline it in an editor or rewrite it automatically.
The check targets wording, not topics. A text that discusses discrimination, or quotes a term in order to explain or criticize it, is not flagged. Every issue is grounded: the model quotes the passage it flagged, and if that passage doesn't occur in your text, the issue is dropped. The text is checked exactly as sent (HTML isn't stripped and whitespace isn't normalized), so the offsets line up with your own copy of the document.
Sample Code
- cURL
- JavaScript
- Python
curl -X POST https://api.sapling.ai/api/v1/inclusive \
-H "Content-Type: application/json" \
-d '{"key":"<api-key>", "text":"The chairman said the plan was crazy, so we need a young, energetic team."}'
import axios from 'axios';
async function run(text) {
try {
const response = await axios.post(
'https://api.sapling.ai/api/v1/inclusive',
{
key: '<api-key>',
text,
},
);
const {status, data} = response;
console.log({status});
console.log(JSON.stringify(data, null, 4));
} catch (err) {
const msg = err.response?.data?.msg || err.message;
console.log({err: msg});
}
}
run('The chairman said the plan was crazy, so we need a young, energetic team.');
import requests
from pprint import pprint
response = requests.post(
"https://api.sapling.ai/api/v1/inclusive",
json={
"key": "<api-key>",
"text": "The chairman said the plan was crazy, so we need a young, energetic team.",
}
)
if 200 <= response.status_code < 300:
pprint(response.json())
else:
print('Error: ', response.status_code, response.text)
Sample Response
{
"issues": [
{
"category": "age",
"severity": "medium",
"text": "young, energetic team",
"start": 51,
"end": 72,
"note": "Frames youth as a requirement, implying older workers are less capable.",
"suggestion": "energetic team"
},
{
"category": "gender",
"severity": "low",
"text": "The chairman",
"start": 0,
"end": 12,
"note": "Gendered job title used as the default; gender-neutral alternatives are available.",
"suggestion": "The chair"
},
{
"category": "disability",
"severity": "low",
"text": "crazy",
"start": 31,
"end": 36,
"note": "Uses a mental-health term as a casual pejorative for 'unreasonable'.",
"suggestion": "unworkable"
}
],
"categories": ["gender", "race_ethnicity", "disability", "age", "lgbtq", "religion",
"socioeconomic", "appearance"],
"inclusive": false
}
Batch Requests
To check many short texts in one request (a queue of job postings or a set of product descriptions,
say), send texts (a list of 1–10 strings) instead of text. The same categories apply to every
item, and the combined length of all items can be up to 10,000 characters, the same cap as a single
text. Provide exactly one of text and texts.
curl -X POST https://api.sapling.ai/api/v1/inclusive \
-H "Content-Type: application/json" \
-d '{"key":"<api-key>", "texts": ["Hey guys, the demo is at 3pm.", "Thanks for the quick review."], "categories": ["gender"]}'
The batch response is {"results": [...]} with one entry per input, in input order. Each entry has
the single-response shape shown above, and its offsets index that item's own text:
{
"results": [
{
"issues": [
{"category": "gender", "severity": "low", "text": "guys", "start": 4, "end": 8,
"note": "Masculine term used to address a mixed group.", "suggestion": "everyone"}
],
"categories": ["gender"],
"inclusive": false
},
{"issues": [], "categories": ["gender"], "inclusive": true}
]
}
Each item is billed individually (a batch of N costs the same as N single requests). If any item
fails, the whole request returns a 502 and nothing is billed. The items that succeeded are already
cached, so a retry only re-runs the failures.
Request Parameters
POST to https://api.sapling.ai/api/v1/inclusive
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 check, up to 10,000 characters. It is checked exactly as sent, so the returned offsets line
up with your original. Provide exactly one of text and texts.
texts: List[String]
Batch form (see Batch Requests): 1–10 texts to check in one request, each treated
exactly like text above, with a combined length of up to 10,000 characters. An empty item, or an item
containing a NUL character, returns a 400 naming its index.
categories: List[String]
Optional list of categories to check. Defaults to all of them. Supported values:
| Category | What it covers |
|---|---|
gender | Gendered defaults and generics ("chairman", "manpower"), gender stereotypes, unnecessary gender marking ("female engineer") |
race_ethnicity | Racial or ethnic stereotypes, outdated or derogatory terms for groups, idioms with racist origins ("blacklist", "grandfathered") |
disability | Ableist idioms ("crazy", "lame", "tone-deaf"), defining people by a condition ("wheelchair-bound"), casual use of mental-health terms ("so OCD") |
age | Ageist assumptions or framing ("digital native", "young and energetic team") |
lgbtq | Heteronormative or cisnormative assumptions and outdated terms ("sexual preference", "transgendered") |
religion | Religious stereotypes, assuming a shared faith or holiday |
socioeconomic | Classist framing ("ghetto", "trashy") and stigmatizing terms |
appearance | Body shaming, weight stigma, irrelevant judgments about appearance |
Response Parameters
issues: List
The flagged passages, most severe first. Each item has:
category: one of the categories listed above.severity:highfor slurs or plainly derogatory language,mediumfor stereotypes or exclusionary framing,lowfor dated or gendered defaults that most readers wouldn't notice.text: the flagged passage, exactly as it appears in the input.start,end: character offsets into the input text, such thattext[start:end]is the passage, ornullin the rare case the passage can't be located.note: a brief, neutral explanation of why the wording may exclude or offend.suggestion: a replacement for the passage that keeps its meaning (an empty string if the passage should simply be removed).
At most 20 issues are returned per text.
categories: List[String]
The categories that were checked.
inclusive: Boolean
true when no issues were found.
Notes
- Offsets count Unicode code points (Python
strindexing), not UTF-16 code units or bytes. In JavaScript, useArray.from(text)if the input may contain characters outside the Basic Multilingual Plane. - Results are cached, so repeating a request with the same text and categories is fast. The order you
list
categoriesin doesn't matter. - A model or upstream failure returns a
502and is not billed. Retry rather than changing the request. - Also available as the
sapling_inclusivetool on the Sapling MCP server and asclient.inclusive()in the JavaScript client. - For house-style rules you define yourself (brand voice, terminology, formatting), see the Style Guide API. For toxicity and other unsafe content, see the Content Safety API.