# The Profanity API - Complete Documentation > Multi-layered content moderation API that combines fast pattern matching with AI-powered semantic analysis. Catches profanity, harassment, and toxic content with context-aware intelligence. ## Authentication All requests require a Bearer token: ``` Authorization: Bearer pf_live_xxxxxxxxxxxxxxxxxxxx ``` Get your API key at https://the-profanity-api.com/dashboard --- ## POST /v1/check Analyze text for profanity, harassment, and toxic content. ### Request Body | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | Yes | — | Text to analyze (max 1,250 characters) | | mode | string | No | "smart" | Detection depth: "instant", "fast", "balanced", "strict", "smart" | | context | string | No | "chat" | Content context for interpretation | | contextDescription | string | No | — | Custom context for LLM analysis (max 500 chars) | | allowlist | string[] | No | — | Words to ignore (max 50 items) | | blocklist | string[] | No | — | Words to flag immediately (max 50 items) | | includeLayersDetails | boolean | No | false | Include per-layer breakdown in response | ### Response | Field | Type | Description | |-------|------|-------------| | flagged | boolean | Whether the content should be flagged/blocked | | score | number | Confidence score (0.0–1.0). Higher = more likely profane | | intent | string | Classified intent (only in smart/strict modes) | | source | string | Which layer made the decision | | detections | array | Matched words/phrases with positions (if includeLayersDetails=true) | | layers | object | Per-layer timing and results (if includeLayersDetails=true) | | latencyMs | number | Total request time in milliseconds | | mode | string | The mode that was used | --- ## Modes Modes control which detection layers run. Choose based on your latency budget and accuracy needs. | Mode | Layers | Latency | Use Case | |------|--------|---------|----------| | instant | L0 → L1 | ~15ms | Live chat, gaming, autocomplete, username validation | | fast | L0 → L2 | ~200ms | Comments, forms, bios—real-time with semantic coverage | | balanced | L0 → L3 | ~400ms | Social posts, forums, user-generated content | | strict | L0 → L4 | ~800ms | Child safety, workplace, zero tolerance | | smart | L0 → L3, L4 if needed | ~200-800ms | Best accuracy per dollar—LLM only when ambiguous | ### Smart Mode Logic - Skips LLM when confidence > 0.85 (clearly profane) or < 0.3 (clearly clean) - Runs LLM only on ambiguous cases (~20-30% of requests) - Same accuracy as strict, lower average cost and latency --- ## Contexts Contexts control how content is interpreted. Same words get different treatment based on context. ### Lenient Contexts (higher threshold, more forgiving) | Context | Description | Example allowed | |---------|-------------|-----------------| | gaming | Game chat, competitive play, trash talk | "I'll destroy you", "get rekt" | | creative | Fiction, roleplay, storytelling | Character dialogue, narrative violence | | educational | Academic discussion, teaching | Historical slurs in context, case studies | | medical | Clinical terminology, health discussions | "breast cancer", "rectal exam" | | legal | Court documents, policy, crime discussion | Case descriptions, witness statements | ### Standard Contexts (balanced defaults) | Context | Description | |---------|-------------| | chat | Real-time messaging, DMs | | comment | Public comments, replies | | review | Product and service reviews | | bio | User profiles, about sections | ### Strict Contexts (lower threshold, flags more) | Context | Description | |---------|-------------| | professional | Workplace communications, Slack, email | | child_safe | Children's platforms—zero tolerance | | username | Display names—strictest on slurs | ### Context Impact Example Text: "I'll destroy you" | Context | Result | Reason | |---------|--------|--------| | gaming | ✅ Clean | Competitive banter | | creative | ✅ Clean | Character dialogue | | comment | ⚠️ Review | Ambiguous intent | | professional | ❌ Flag | Workplace threat | --- ## Intents Intent classification tells you WHY something was flagged. Requires Layer 4 (LLM) to run. ### Safe Intents (usually allow) | Intent | Description | Example | |--------|-------------|---------| | safe | Clean content with no issues | Normal conversation | | joking | Friendly banter, humor, trash talk | "lol noob", "you absolute walnut" | | venting_situational | Frustration at things/situations | "fuck this traffic", "stupid bug" | | quoting | Referencing others' words | "He said go to hell" | | educational | Academic discussion | Historical analysis, research | | professional | Medical/legal/technical terminology | Clinical terms, legal language | ### Context-Dependent Intents (may need review) | Intent | Description | Example | |--------|-------------|---------| | venting_targeted | Frustration at specific individuals | "my boss is an idiot" | | passive_aggressive | Indirect hostility, sarcasm | "you're SO smart" | ### Harmful Intents (usually flag) | Intent | Description | Example | |--------|-------------|---------| | abusive | Direct harassment, slurs, personal attacks | "fuck you", "you're worthless" | | threatening | Explicit or veiled threats of harm | "I know where you live" | | discriminatory | Bias against groups (race, gender, etc.) | Slurs, stereotyping | | sexual | Sexual content, innuendo, harassment | Unsolicited advances | ### Unknown Intent | Intent | Description | |--------|-------------| | unknown | Could not determine, or mode didn't include intent detection | --- ## Detection Layers The API processes text through up to five detection layers. Each layer catches different types of content. | Layer | Name | Strategy | Latency | |-------|------|----------|---------| | L0 | Blocklist | Your custom blocked terms, O(1) hash lookups | <1ms | | L1 | Static Dictionary | 1,500 terms + leetspeak variants (Orama) | ~5ms | | L2 | Semantic Dictionary | 384d vector similarity on words | ~100ms | | L3 | Phrase Detection | 768d vectors, 50k hate/abuse phrases | ~150ms | | L4 | LLM Analysis | Intent classification (Groq llama-3.1-8b) | ~300ms | ### Layer Capabilities **L0 - Blocklist** - Your custom terms, wildcards (ass* catches asshole) - Homoglyph normalization (₳ → a, Ø → o) - Immediate short-circuit on match **L1 - Static Dictionary** - Curated 1,500-word profanity dictionary - Leetspeak decoding (3→e, 1→l, 0→o, @→a) - Tokenization prevents Scunthorpe-style false positives **L2 - Semantic Dictionary** - Same dictionary as L1, embedded as 384d vectors - Catches creative misspellings (phuck, shiit, fuk) - Similarity threshold configurable (default 0.8) **L3 - Phrase Detection** - 50k hate speech and abuse patterns - 768d embeddings for phrase-level semantics - Catches "kys", "drink bleach", veiled threats **L4 - LLM Analysis** - Full intent classification with reasoning - Context-aware interpretation - Only runs when earlier layers are ambiguous (smart mode) ### Detection Source Values The `source` field in the response indicates which layer made the final decision: | Value | Layer | Description | |-------|-------|-------------| | blocklist | L0 | User-defined blocklist match | | static | L1 | Static dictionary match | | dictionary | L2 | Semantic word match | | semantic | L3 | Semantic phrase match | | llm | L4 | LLM intent analysis | | clean | — | No issues found | --- ## Example Requests ### Minimal Request ```bash curl -X POST https://the-profanity-api.com/api/v1/check \ -H "Authorization: Bearer pf_live_xxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "text": "Hello, how are you?" }' ``` ### Response ```json { "flagged": false, "score": 0.0, "intent": "safe", "source": "clean", "latencyMs": 203, "mode": "smart" } ``` ### Full Request with Layer Details ```bash curl -X POST https://the-profanity-api.com/api/v1/check \ -H "Authorization: Bearer pf_live_xxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "text": "What the h3ll is wrong with this ₣₳₲₲Ø₮?", "mode": "smart", "context": "comment", "contextDescription": "User comment on a news article", "includeLayersDetails": true }' ``` ### Response ```json { "flagged": true, "score": 0.94, "intent": "abusive", "source": "semantic", "detections": [ { "text": "h3ll", "position": { "start": 9, "end": 13 }, "confidence": 0.92, "detectionSource": "static" }, { "text": "₣₳₲₲Ø₮", "position": { "start": 34, "end": 40 }, "confidence": 0.96, "detectionSource": "dictionary" } ], "layers": { "blocklist": { "ran": true, "durationMs": 0, "matchCount": 0 }, "static": { "ran": true, "durationMs": 2, "matchCount": 1 }, "dictionary": { "ran": true, "durationMs": 147, "matchCount": 1, "topScore": 0.96 }, "semantic": { "ran": true, "durationMs": 162, "matchCount": 0, "topScore": 0.72 }, "llm": null }, "latencyMs": 312, "mode": "smart" } ``` ### Gaming Context Example ```bash curl -X POST https://the-profanity-api.com/api/v1/check \ -H "Authorization: Bearer pf_live_xxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "text": "Get rekt noob! I destroyed you!", "mode": "smart", "context": "gaming" }' ``` ### Response ```json { "flagged": false, "score": 0.12, "intent": "joking", "source": "clean", "latencyMs": 245, "mode": "smart" } ``` --- ## Error Responses ```json { "error": { "code": "error_code", "message": "Human-readable description" } } ``` | Code | Status | Description | |------|--------|-------------| | invalid_api_key | 401 | API key is missing, invalid, or revoked | | invalid_request | 400 | Request body validation failed | | text_too_long | 400 | Text exceeds 1,250 character limit | | rate_limited | 429 | Too many requests—slow down | | insufficient_credits | 402 | Account has insufficient credits | | internal_error | 500 | Something went wrong on our end | --- ## Rate Limit Headers | Header | Description | |--------|-------------| | X-RateLimit-Limit | Requests allowed per minute | | X-RateLimit-Remaining | Requests remaining in current window | | X-RateLimit-Reset | Unix timestamp when limit resets | --- ## Pricing - **$0.006** per request (L0-L3 layers) - **+$0.002** surcharge when L4 (LLM) runs - **300 free requests** per month - No rate limits on paid plans --- ## Quick Reference ### Best Practices 1. **Start with smart mode** — Gets LLM accuracy only when needed 2. **Set context appropriately** — "gaming" vs "professional" makes a big difference 3. **Use contextDescription** — For platform-specific norms the presets don't cover 4. **Check the intent field** — Distinguish venting from attacking 5. **Use includeLayersDetails** — For debugging and tuning ### Common Patterns **Real-time chat (low latency)** ```json { "text": "...", "mode": "instant", "context": "chat" } ``` **User-generated content (balanced)** ```json { "text": "...", "mode": "smart", "context": "comment" } ``` **Child safety (maximum protection)** ```json { "text": "...", "mode": "strict", "context": "child_safe" } ``` **Code review comments (custom context)** ```json { "text": "...", "mode": "smart", "context": "professional", "contextDescription": "Code review between senior engineers. Direct feedback is expected." } ```