Job posting inclusive language checker
A job posting can unintentionally discourage qualified applicants when familiar phrases imply a preferred gender, age, background, ability, or personality type.
Run — free
This checker compares your posting with the flagged-language list you provide, identifies every literal occurrence, and pairs each match with your chosen neutral alternative. Results include the exact wording and its line, column, and character position, making review straightforward even in a long advert. The check is deterministic: it does not invent concerns, rewrite the role, or send text to a model.
Build a review list that matches your hiring policy
Inclusive-language guidance differs among organizations, jurisdictions, roles, and audiences, so the checker does not impose a hidden universal dictionary. Supply a list of terms your recruiting or legal team commonly flags and pair every term with an approved neutral alternative. A list might connect “salesman” to “sales representative,” “chairman” to “chair,” or “digital native” to “digitally proficient professional.” Literal phrases are accepted as well as single words, and matching ignores capitalization while preserving the exact text found in the posting. Keep alternatives specific enough to retain the role’s real requirements. Replacing “young” with “early-career,” for example, may still be inappropriate if age is not relevant; “developing skills in” or a direct statement of required experience can be clearer. Treat the supplied list as maintained editorial policy rather than an exhaustive verdict about inclusion. Review it periodically with people who understand employment law, accessibility, and the candidates you hope to reach. This design makes each result explainable: every flag traces directly to a term and alternative that your team chose before running the check.
Read occurrences in their original context
Paste the complete job posting, including the title, responsibilities, requirements, benefits, and application instructions. The result reports whether the posting passed the supplied check, how many terms were examined, how many distinct flagged terms appeared, and the total number of occurrences. Each occurrence contains the configured term, the exact capitalization that appeared, its proposed neutral alternative, a zero-based character index, and one-based line and column numbers. Whole-word boundaries are respected when a term begins or ends with a letter or number, preventing a short entry such as “man” from being flagged inside an unrelated longer word. The checker deliberately reports rather than automatically replacing text. Context can change meaning, overlapping phrases can compete, and a mechanically substituted alternative may make a sentence ungrammatical. Open the posting at the reported location, read the surrounding sentence, and decide whether the alternative preserves the intended responsibility or qualification. Re-run the same list after editing; a pass means only that none of those configured terms remains, not that every possible barrier has been removed.
Use the check as one step in a broader review
Language scanning is most useful inside a repeatable publishing workflow. Run it when a recruiter finishes a draft, again after a hiring manager revises requirements, and once more before the advert is published. Store the flagged-term list with your editorial standards so different teams receive consistent findings. The browser version is useful for individual drafts, while the API at $0.002 per request can check postings in an applicant-tracking export or content approval pipeline. No network service, language model, random choice, or current date influences the result, so identical input produces identical output. That consistency supports testing and audit trails, but it does not replace human judgment. Review unnecessary degree requirements, rigid years-of-experience thresholds, accessibility of the application process, compensation clarity, working-location expectations, and whether essential duties are separated from preferences. Also ask people with different lived experiences to read the finished advert. The checker can reliably locate vocabulary on a known list; people remain responsible for tone, context, legal compliance, and whether the opportunity itself is genuinely accessible.
What you can do with it
Review a recruiter’s draft
Locate every configured phrase before the posting enters hiring-manager approval, with positions that make edits quick.
Enforce an editorial language list
Apply the same organization-approved terms and alternatives across postings written by different teams.
Check content before publication
Add a deterministic inclusive-language step to an automated job-board or applicant-tracking workflow.
FAQ
Does the checker include its own list of biased terms?
No. You provide the flagged terms and neutral alternatives, so the check follows your organization’s reviewed guidance.
Is matching case-sensitive?
No. Capitalization is ignored for matching, while the exact matched spelling is preserved in each occurrence.
Will it replace words automatically?
No. It reports a neutral alternative for each occurrence, but a person should confirm that the replacement fits the sentence and context.
What does a passing result mean?
It means none of the supplied flagged terms occurred as a whole word or phrase. It is not a certification that the posting is fully inclusive or legally compliant.
Can it find a phrase more than once?
Yes. Every non-overlapping occurrence is returned with its character index, line, and column.
What does the API cost?
The API costs $0.002 per request. The same deterministic check can also run free in the browser.
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, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/biz/job-posting-readability-check \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"We need a confident salesman and a young digital native to manage our growing customer list.","flagged_terms":[{"term":"salesman","alternative":"sales representative"},{"term":"young","alternative":"early-career"},{"term":"digital native","alternative":"digitally proficient professional"}]}'const res = await fetch("https://api.kit.forhosting.com/biz/job-posting-readability-check", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "We need a confident salesman and a young digital native to manage our growing customer list.",
"flagged_terms": [
{
"term": "salesman",
"alternative": "sales representative"
},
{
"term": "young",
"alternative": "early-career"
},
{
"term": "digital native",
"alternative": "digitally proficient professional"
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/biz/job-posting-readability-check",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "We need a confident salesman and a young digital native to manage our growing customer list.",
"flagged_terms": [
{
"term": "salesman",
"alternative": "sales representative"
},
{
"term": "young",
"alternative": "early-career"
},
{
"term": "digital native",
"alternative": "digitally proficient professional"
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/biz/job-posting-readability-check", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"We need a confident salesman and a young digital native to manage our growing customer list.","flagged_terms":[{"term":"salesman","alternative":"sales representative"},{"term":"young","alternative":"early-career"},{"term":"digital native","alternative":"digitally proficient professional"}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"We need a confident salesman and a young digital native to manage our growing customer list.","flagged_terms":[{"term":"salesman","alternative":"sales representative"},{"term":"young","alternative":"early-career"},{"term":"digital native","alternative":"digitally proficient professional"}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/biz/job-posting-readability-check", 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": "We need a confident salesman and a young digital native to manage our growing customer list.",
"flagged_terms": [
{
"term": "salesman",
"alternative": "sales representative"
},
{
"term": "young",
"alternative": "early-career"
},
{
"term": "digital native",
"alternative": "digitally proficient professional"
}
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "biz.job_posting_readability_check",
"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_text_chars | 200000 |
max_flagged_terms | 500 |
max_term_chars | 200 |
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. |