Unprofane

Profanity checker

Find swear words, slurs and disguised profanity in any text, and copy it censored.

Censor as
0 / 5,000

Insults, slurs and threats blocked; swearing held for a person to look at.

Try

Check text in your app, with one call

Disguised words are still found

Each trick is undone before the words are read, and named in the answer. Pick one to try it.

Caught, by trick: the Scunthorpe Test, rules alone, 2026-10-20

Why a word list is not enough

A list misses the disguised word, and refuses the innocent one that happens to contain it.

  1. Moving to Scunthorpe next month

    The list finds a slur inside a town.

    Blocks it

    allow

  2. f.u.c.k off, nobody wants you here

    Four dots and the list sees no word.

    Misses it

    block

  3. ƒυ¢к off

    A hooked f, a Greek u, a cent sign and a Cyrillic k.

    Misses it

    review

  4. I know where you live

    A threat in ordinary words.

    Misses it

    block

Out of 4

1 innocent blocked3 missed

1 innocent let through3 caught

Try one with a swear inside

Measured in public

More abuse caught than Perspective or OpenAI, each allowed the same share of false alarms.

89.0%

of toxic text caught, with 7.0% of clean text flagged

  • Unprofane89.0%
  • Google Perspective API58.4%
  • OpenAI moderation40.8%
The head to head, the private test set, 2026-09-28

The same check, in your app

One request returns the verdict, each word as read, the trick that hid it and a censored copy.

Get your API key

100 checks a day, no card

curl -X POST https://api.unprofane.com/v1/check \
  -H "Authorization: Bearer up_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"what a b i t c h move","context":"comment"}'
Response200
{
  "allowed": false,
  "action": "block",
  "severity": "strong",
  "evasion": [
    "separator",
    "concatenation"
  ],
  "matches": [
    {
      "text": "b i t c h",
      "normalized": "bitch",
      "category": "insult"
    }
  ],
  "censored": "what a ********* move"
}

The profanity checker, answered

Is the profanity checker free?
Yes, with no sign-up. It runs the engine the Unprofane API runs; to check text from your own app, a test key is free, needs no card and answers 100 checks a day.
What does the profanity checker find?
Swear words, insults, slurs, sexual language and threats, in 17 languages, typed plainly or hidden with leetspeak, look-alike letters, spacing or invisible characters. Each word comes back with what it reads as, how strong it is and the trick that hid it, and the text comes back censored.
How does the checker find disguised words?
It undoes each disguise before it reads the words: digits and symbols read as the letters they stand for, look-alike letters from other alphabets as Latin ones, invisible characters and spacing taken out, stretched letters shortened. The rules were measured undoing 13 kinds of disguise on the Scunthorpe Test (run of 2026-10-20), and the answer names each one it found. It names misspellings, spoonerisms, and puns too, which the test has no items for yet.
Does it block Scunthorpe?
No. It reads words, not strings of letters, so a town, a surname or an ordinary word with a swear inside it is let through. On the Scunthorpe Test's 549 innocent words and sentences that contain a profane string, the rules alone flagged 0.0% (run of 2026-10-20). The Scunthorpe problem, explained.
Where does a profanity check go in an app?
Anywhere a person types something another person will read: usernames at sign-up, chat lines and comments as they are sent, custom text before a shirt or a ring is made. The API takes a context, so each is read for what it is, and the kids policy blocks mild words and rude text too.

More free tools