Skip to main content
Documentation
Learning Center

Master content moderation with comprehensive guides, tutorials, and API documentation

Quick Links

Text Analysis: Sentiment, Spam, and Language in One Call

Discuse text analysis scores a message for toxicity, spam, and language in a single POST https://api.discuse.com/api/v2/check request. Send your text in content.text, authenticate with the X-API-Key header, and read the per-check results back under results.

What does the text endpoint check?

One /api/v2/check call can run three text checks at once:

  • Sentiment: toxicity, profanity, threat, and insult scoring, plus a negative/toxic verdict.
  • Spam: promotional spam, scams, and bot-generated text, returned as a label plus a confidence score.
  • Language: the detected language code, with optional enforcement against an expected language.

Each check runs only when enabled, either in your project settings or via the per-request settings object.

How do I call the text endpoint?

curl -X POST https://api.discuse.com/api/v2/check \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "content": {
      "text": "This is an example message to analyze"
    },
    "settings": {
      "check_sentiment": true,
      "check_spam": true,
      "check_language": true
    }
  }'

content.text accepts up to 10,000 characters. The API key can be sent in the X-API-Key header or as api_key in the request body.

Response

{
  "has_violations": false,
  "cached": false,
  "message": "Content appears safe",
  "results": {
    "hits": false,
    "sentiment": {
      "hit": false,
      "is_negative": false,
      "is_toxic": false,
      "score": 0.04,
      "toxicity": 0.02,
      "toxic": 0.02,
      "profanity": 0.01,
      "threat": 0.00,
      "insult": 0.03
    },
    "spamfinder": {
      "text": "This is an example message to analyze",
      "label": "ham",
      "confidence": 0.12,
      "is_spam": false,
      "hit": false
    },
    "language": {
      "language": "en",
      "confidence": 0.98,
      "hit": false
    }
  },
  "usage": {
    "api_requests_used": 41,
    "api_requests_limit": 5000,
    "api_requests_remaining": 4959
  }
}

has_violations mirrors results.hits: it is true when any enabled check fires its hit flag. processing_time_ms is only present when timing is enabled in your project settings.

Sentiment analysis

The sentiment check returns both a verdict and per-dimension scores from 0.0 to 1.0.

Field Type Meaning
is_negative bool Message reads as negative
is_toxic bool Message crosses the toxicity threshold
score number Overall sentiment/severity score
toxicity number Toxicity confidence (0.0–1.0)
toxic number Toxicity confidence (legacy alias of toxicity)
profanity number Explicit-language confidence
threat number Threat-of-harm confidence
insult number Personal-attack confidence
hit bool True when the message violates the sentiment thresholds
message string Optional explanation

How do I interpret a sentiment score?

A score is the model's confidence that the dimension applies:

  • 0.0 – 0.3: low, generally safe.
  • 0.3 – 0.6: moderate, may warrant review.
  • 0.6 – 0.8: high, likely problematic.
  • 0.8 – 1.0: very high, almost certainly violating.

Example: toxic content

Request:

{
  "content": {
    "text": "You're the worst person I've ever met. I hate everything about you."
  },
  "settings": { "check_sentiment": true }
}

Response:

{
  "has_violations": true,
  "results": {
    "hits": true,
    "sentiment": {
      "hit": true,
      "is_negative": true,
      "is_toxic": true,
      "score": 0.91,
      "toxicity": 0.89,
      "toxic": 0.89,
      "profanity": 0.15,
      "threat": 0.22,
      "insult": 0.95
    }
  }
}

Spam detection

The spam check classifies text and returns a single label with a confidence score. It catches the patterns that evade keyword blocklists: promotional spam, scams and phishing, and bot-generated text.

Example: spam content

Request:

{
  "content": {
    "text": "CONGRATULATIONS! You've won $10,000! Click here to claim: www.fake-prize.com"
  },
  "settings": { "check_spam": true }
}

Response:

{
  "has_violations": true,
  "results": {
    "hits": true,
    "spamfinder": {
      "text": "CONGRATULATIONS! You've won $10,000! Click here to claim: www.fake-prize.com",
      "label": "spam",
      "confidence": 0.97,
      "is_spam": true,
      "hit": true
    }
  }
}

is_spam is the raw model verdict (the model labelled the text as spam). hit is the threshold-aware decision: it is true only when is_spam is true and confidence clears your project's spam threshold. Gate moderation on hit, not on is_spam. See the Spam Detection guide for details.

Language detection

Set check_language to detect the language code of content.text. The result is in results.language.language (for example "en", "fr", "es").

Request:

{
  "content": { "text": "Bonjour, comment allez-vous aujourd'hui?" },
  "settings": { "check_language": true }
}

Response:

{
  "results": {
    "language": {
      "language": "fr",
      "confidence": 0.99,
      "hit": false
    }
  }
}

To flag content that is not in your expected language, set expected_language. When the detected language differs, language.hit is true and expected/detected are populated:

{
  "content": { "text": "Hola, cómo estás?" },
  "settings": { "check_language": true, "expected_language": "en" }
}
{
  "results": {
    "language": {
      "language": "es",
      "detected": "es",
      "expected": "en",
      "confidence": 0.95,
      "hit": true
    }
  }
}

See Language Detection for the full language list and enforcement patterns.

Which checks can I toggle?

The optional settings object overrides your project defaults for a single request. The text-relevant toggles are:

Setting Type Effect
check_sentiment bool Run sentiment analysis
check_spam bool Run spam detection
check_language bool Run language detection
check_badwords bool Run the badwords blocklist
expected_language string Language code to enforce (e.g. "en")
{
  "content": { "text": "Your message here" },
  "settings": {
    "check_sentiment": true,
    "check_spam": true,
    "check_language": true,
    "expected_language": "en"
  }
}

Usage limits

Sentiment, spam, and language detection draw from the per-plan sentiment-analysis quota:

Plan Sentiment Analyses/Month
Basic 1,000
Gold 5,000
Platinum 15,000
Ultimate 30,000

Cached responses do not count against your quota. The usage object in every response reports api_requests_used, api_requests_limit, and api_requests_remaining.

Best practices

Set thresholds per platform

Apply different sentiment cutoffs for different audiences:

const THRESHOLDS = {
  kids:    { toxicity: 0.3, profanity: 0.2, threat: 0.2, insult: 0.3 },
  general: { toxicity: 0.5, profanity: 0.5, threat: 0.4, insult: 0.5 },
  adult:   { toxicity: 0.7, profanity: 0.8, threat: 0.5, insult: 0.7 }
};

Account for context

Clinical, journalistic, and fiction content can trip toxicity and profanity scores legitimately. Combine automated scoring with human review for borderline cases:

const sentiment = result.results.sentiment;
if (sentiment.toxicity > 0.9) {
  await removeContent(contentId);       // high confidence: auto-remove
} else if (sentiment.toxicity > 0.5) {
  await queueForReview(contentId);      // borderline: human review
} else {
  await approveContent(contentId);
}

Integration examples

JavaScript

async function analyzeText(text) {
  const response = await fetch('https://api.discuse.com/api/v2/check', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': process.env.DISCUSE_API_KEY
    },
    body: JSON.stringify({
      content: { text },
      settings: { check_sentiment: true, check_spam: true, check_language: true }
    })
  });

  return response.json();
}

const result = await analyzeText('Hello, how are you?');
console.log(result.has_violations); // false

Python

import os
import requests

def analyze_text(text):
    response = requests.post(
        'https://api.discuse.com/api/v2/check',
        headers={
            'Content-Type': 'application/json',
            'X-API-Key': os.environ['DISCUSE_API_KEY']
        },
        json={
            'content': {'text': text},
            'settings': {
                'check_sentiment': True,
                'check_spam': True,
                'check_language': True
            }
        }
    )
    return response.json()

result = analyze_text('Hello, how are you?')
print(result['has_violations'])  # False

Ready to implement text analysis? See the Quick Start Guide for step-by-step setup.

Written by the Discuse Team · Last updated June 2026

Related Articles

Image NSFW Detection

Automatically detect and filter inappropriate images and adult content

Spam Detection

AI-powered spam filtering for text and messages

File Antivirus Scanning

Protect your platform from malware, viruses, and malicious files