Profanity filtering users can't bypass.
Send a comments:analyze request to the drop-in endpoint and read the response as your code will.
Send the request to see the response.
The scores land here as bars, and the JSON as the endpoint sends it: attributeScores, languages, detectedLanguages.
The scores are Unprofane's, in Google's format.
Each scored from 0 to 1, with span scores by sentence on request. Google’s experimental names read as the attribute they became.
| Attribute | What it scores | Also answers to |
|---|---|---|
TOXICITY | Rude, hostile or unreasonable enough to drive someone out of a conversation. | TOXICITY_EXPERIMENTAL |
SEVERE_TOXICITY | Very hateful or aggressive. Far less moved by mild swearing than TOXICITY. | SEVERE_TOXICITY_EXPERIMENTAL |
IDENTITY_ATTACK | Hateful or demeaning about a person for who they are: race, religion, gender, sexuality, disability. | IDENTITY_ATTACK_EXPERIMENTAL |
INSULT | Insulting, belittling or name-calling, aimed at a person or a group. | INSULT_EXPERIMENTAL |
PROFANITY | Swearing, curse words and other obscene language. | PROFANITY_EXPERIMENTALOBSCENE |
THREAT | Wishes or intends harm on a person or a group. | THREAT_EXPERIMENTAL |
SEXUALLY_EXPLICIT | Sexual acts, body parts or other lewd content. | SEXUALLY_EXPLICIT_EXPERIMENTALFLIRTATION |
Not served, and refused in Google’s words unless the request sets dropUnsupportedAttributes:
Change one line and keep your client. Each client below is its guide’s own tested code.
client = discovery.build("commentanalyzer","v1alpha1",developerKey=os.environ["UNPROFANE_KEY"], # up_test_YOUR_KEY on staging, up_live_YOUR_KEY in productionRemove: discoveryServiceUrl="https://commentanalyzer.googleapis.com/$discovery/rest?version=v1alpha1",Add: discoveryServiceUrl="https://api.unprofane.com/$discovery/rest?version=v1alpha1",static_discovery=False,)response = client.comments().analyze(body={"comment": {"text": "you are a clown"},"requestedAttributes": {"TOXICITY": {}},"languages": ["en"],"doNotStore": True,}).execute()1 line changes. Give discovery.build a discoveryServiceUrl on the Unprofane host and keep every call the same.
Tested with google-api-python-client 2.201.0, on every run of the snippet checks. The Python guide
const client = await google.discoverAPI(Remove: 'https://commentanalyzer.googleapis.com/$discovery/rest?version=v1alpha1',Add: 'https://api.unprofane.com/$discovery/rest?version=v1alpha1',);const res = await client.comments.analyze({key: process.env.UNPROFANE_KEY, // up_test_YOUR_KEY on staging, up_live_YOUR_KEY in productionresource: {comment: { text: 'you are a clown' },requestedAttributes: { TOXICITY: {} },languages: ['en'],doNotStore: true,},});1 line changes. Build the client with google.discoverAPI from the Unprofane discovery URL and keep the calls.
Tested with googleapis 185.0.0, on every run of the snippet checks. The Node.js guide
Toxic comment filter: OnRemove: API key: YOUR_GOOGLE_KEYAdd: API key: up_test_YOUR_KEYRemove: Custom endpoint: (empty)Add: Custom endpoint: https://api.unprofane.com/v1alpha1Toxicity model: TOXICITY (or empty)2 lines change. Set Coral’s Custom endpoint to https://api.unprofane.com/v1alpha1 and its API key to an Unprofane key. Coral adds comments:analyze and comments:suggestscore itself.
Tested with Coral 9.11.8 itself, run on October 13, 2026. The Coral Talk guide
Remove: GOOGLE_API_DOMAIN = "https://commentanalyzer.googleapis.com"Add: GOOGLE_API_DOMAIN = "https://api.unprofane.com"perspective_enabled: trueRemove: perspective_google_api_key: YOUR_GOOGLE_KEYAdd: perspective_google_api_key: up_test_YOUR_KEYperspective_toxicity_model: standard2 lines change. The discourse-perspective-api plugin hardcodes Google’s host and has no endpoint setting. Fork it, change one line, rebuild, and put an Unprofane key in perspective_google_api_key. A Discourse you cannot add plugins to cannot run the fork.
Tested with Discourse 2026.10.0-latest itself, run on October 13, 2026. The Discourse guide
Remove: curl -X POST "https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key=YOUR_GOOGLE_KEY" \Add: curl -X POST "https://api.unprofane.com/v1alpha1/comments:analyze?key=up_test_YOUR_KEY" \-H "Content-Type: application/json" \-d '{"comment": {"text": "you are a clown"},"requestedAttributes": {"TOXICITY": {}, "INSULT": {}},"languages": ["en"],"doNotStore": true}'1 line changes. The same POST body and the same response, on a different host, with the key as ?key= or a bearer header.
Tested with the request as printed, on every run of the snippet checks. The cURL guide