Azure Content Moderator Alternative — Profanity Filter avatar

Azure Content Moderator Alternative — Profanity Filter

Pricing

from $1.00 / 1,000 text screeneds

Go to Apify Store
Azure Content Moderator Alternative — Profanity Filter

Azure Content Moderator Alternative — Profanity Filter

Azure Content Moderator alternative and drop-in profanity filter + PII detector for the text screen API. Accepts POST /contentmoderator/moderate/v1.0/ProcessText/Screen and returns the same Terms, PII, Classification and Status JSON. Content Safety is a different API. $1 per 1,000 texts.

Pricing

from $1.00 / 1,000 text screeneds

Rating

0.0

(0)

Developer

drop-in apis

drop-in apis

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

3 hours ago

Last modified

Share

Azure Content Moderator Alternative — Profanity Filter & PII Detector

Azure Content Moderator alternative, drop-in profanity filter and PII detector for text: this Actor accepts POST /contentmoderator/moderate/v1.0/ProcessText/Screen and returns the same Terms, PII, Classification and Status JSON. Microsoft retires Content Moderator on 15 March 2027 (overview; the lifecycle page says 1 April 2027).

At a glance: $1.00 per 1,000 screened texts (failed requests are not charged) · about 20–80 ms per screen on a warm Standby instance · up to 1,024 characters per text · text only (no image or video moderation). Try it with no code: click Start with the prefilled input (batch mode), or send one request to the Standby endpoint.

Last updated: 2026-10-02 · Full migration guide: https://alidaram99.github.io/api-alternatives/azure-content-moderator-alternative/

Microsoft's successor, Azure AI Content Safety, uses a different URL, auth and JSON (severity levels instead of Terms, PII and Category1/2/3). With this Actor you point your existing code at a new endpoint and keep everything else.

  • ✅ Same route, query parameters (language, classify, PII, autocorrect, listId) and body formats (text/plain, text/html, text/xml, text/markdown)
  • ✅ Same response field names, casing and order. Terms: null when nothing is found, like Azure
  • ✅ Built-in profanity list in 24 languages, with correct Index / OriginalIndex offsets
  • ✅ PII detection: email, IPv4/IPv6, US/UK phone, US SSN, US street address
  • ✅ English classification (Category1/2/3 plus ReviewRecommended), as in Azure
  • ✅ $1 per 1,000 screens; errors are free
  • 🔒 Nothing is stored or logged. Text is screened in memory inside the Actor and no third-party AI API is called.

Migrate in one minute

Your endpoint is the Actor's Standby URL. You'll find it on the Actor's Standby tab, for example https://<username>--content-moderator-compat.apify.actor. Authenticate with your Apify API token, either as ?token=… or as Authorization: Bearer …. The Ocp-Apim-Subscription-Key header is accepted and ignored.

curl / any REST client

# Before
curl -X POST "https://westus.api.cognitive.microsoft.com/contentmoderator/moderate/v1.0/ProcessText/Screen?language=eng&classify=True&PII=True" \
-H "Ocp-Apim-Subscription-Key: $AZURE_KEY" -H "Content-Type: text/plain" \
--data-binary 'Is this a crap email abcdef@abcd.com, phone: 6657789887, IP: 255.255.255.255, 1 Microsoft Way, Redmond, WA 98052'
# After: same path, query and body
curl -s -X POST "https://<username>--content-moderator-compat.apify.actor/contentmoderator/moderate/v1.0/ProcessText/Screen?language=eng&classify=True&PII=True&token=$APIFY_TOKEN" \
-H 'Content-Type: text/plain' \
--data-binary 'Is this a crap email abcdef@abcd.com, phone: 6657789887, IP: 255.255.255.255, 1 Microsoft Way, Redmond, WA 98052'

C# (HttpClient, .NET 6+)

using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
var baseUrl = "https://<username>--content-moderator-compat.apify.actor";
var token = Environment.GetEnvironmentVariable("APIFY_TOKEN")!;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var content = new StringContent("Is this a crap email abcdef@abcd.com?", Encoding.UTF8, "text/plain");
var response = await http.PostAsync(
$"{baseUrl}/contentmoderator/moderate/v1.0/ProcessText/Screen?language=eng&classify=True&PII=True", content);
response.EnsureSuccessStatusCode();
using var json = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
var root = json.RootElement;
Console.WriteLine($"Status {root.GetProperty("Status").GetProperty("Code").GetInt32()}, " +
$"Category3 {root.GetProperty("Classification").GetProperty("Category3").GetProperty("Score").GetDouble():F3}, " +
$"first term '{root.GetProperty("Terms")[0].GetProperty("Term").GetString()}'");
// Status 3000, Category3 0.971, first term 'crap'

If you use the old Microsoft.Azure.CognitiveServices.ContentModerator SDK, set client.Endpoint to the Standby URL and pass ServiceClientCredentials that add the Authorization: Bearer header. That SDK path has not been tested; the HttpClient code above has.

Python (requests)

import os
import requests
BASE = "https://<username>--content-moderator-compat.apify.actor"
APIFY_TOKEN = os.environ["APIFY_TOKEN"]
r = requests.post(
f"{BASE}/contentmoderator/moderate/v1.0/ProcessText/Screen",
params={"language": "eng", "classify": "True", "PII": "True"},
headers={"Content-Type": "text/plain", "Authorization": f"Bearer {APIFY_TOKEN}"},
data="This is crap, email me at someone@example.com".encode("utf-8"),
)
screen = r.json()
print(screen["Status"]["Code"], screen["Classification"]["Category3"]["Score"],
[t["Term"] for t in screen["Terms"] or []], [e["Text"] for e in screen["PII"]["Email"]])
# 3000 0.98 ['crap'] ['someone@example.com']

If you use the azure-cognitiveservices-vision-contentmoderator SDK, pass msrest.authentication.BasicTokenAuthentication({"access_token": APIFY_TOKEN}) as the credentials and set endpoint to the Standby URL. (That SDK path has not been tested; the requests code above has.)

Node.js

const BASE = 'https://<username>--content-moderator-compat.apify.actor';
const res = await fetch(`${BASE}/contentmoderator/moderate/v1.0/ProcessText/Screen?language=eng&classify=True`, {
method: 'POST',
headers: { 'Content-Type': 'text/plain', Authorization: `Bearer ${process.env.APIFY_TOKEN}` },
body: 'You are a worthless idiot',
});
const screen = await res.json();
console.log(screen.Status.Code, screen.Classification.ReviewRecommended, screen.Classification.Category3.Score);
// 3000 true 0.997

Response example (real output)

{
"OriginalText": "Is this a crap email abcdef@abcd.com, phone: 6657789887, IP: 255.255.255.255, 1 Microsoft Way, Redmond, WA 98052",
"NormalizedText": "Is this a crap email abcdef@ abcd. com, phone: 6657789887, IP: 255. 255. 255. 255, 1 Microsoft Way, Redmond, WA 98052",
"Misrepresentation": null,
"PII": {
"Email": [{ "Detected": "abcdef@abcd.com", "SubType": "Regular", "Text": "abcdef@abcd.com", "Index": 21 }],
"SSN": [],
"IPA": [{ "SubType": "IPV4", "Text": "255.255.255.255", "Index": 61 }],
"Phone": [{ "CountryCode": "US", "Text": "6657789887", "Index": 45 }],
"Address": [{ "Text": "1 Microsoft Way, Redmond, WA 98052", "Index": 78 }]
},
"Classification": {
"ReviewRecommended": true,
"Category1": { "Score": 0.0023 },
"Category2": { "Score": 0.2708 },
"Category3": { "Score": 0.9562 }
},
"Language": "eng",
"Terms": [{ "Index": 10, "OriginalIndex": 10, "ListId": 0, "Term": "crap" }],
"Status": { "Code": 3000, "Description": "OK", "Exception": null },
"TrackingId": "c110a5a9-3659-4fff-b2ce-fcac1f4ae9a9"
}

This is Microsoft's own documented example sentence. NormalizedText, the Terms offsets and every PII index are identical to Microsoft's published response.

Compatibility matrix

FeatureStatus
Route, HTTP method, query parameters (case-insensitive), content types, 1,024-character limitIdentical
Response field names, casing, order, Status, Misrepresentation: null, Terms: null when clean, TrackingIdIdentical
NormalizedText (space inserted after punctuation, as Azure does)Identical on Microsoft's documented examples; may differ on unusual inputs
Terms with Index (into NormalizedText) and OriginalIndex (into OriginalText), ListId: 0Same format. The word list is our own, so matches can differ from Azure's private list
PII (Email, IPA, Phone, Address, SSN) with Azure's sub-field namesSame format. Patterns are deliberately strict: phones are US/UK, addresses US with state and ZIP, SSNs valid ddd-dd-dddd only
Classification Category1 (sexually explicit), Category3 (offensive)Approximate. Open model, different scores from Azure's
Classification Category2 (sexually suggestive)Approximate proxy: max(Category1, 0.3 × obscene). Flirty but clean text is not detected
ReviewRecommendedTrue when any category is ≥ 0.5. Azure's internal thresholds are not published
Classification for non-English textOmitted, as in Azure (English only)
autocorrect=trueAccepted. AutoCorrectedText is returned but no spelling correction is applied (same as NormalizedText)
listId (custom term lists)Not supported. Custom lists live in your Azure resource. The built-in list is applied, and the response carries an X-Compat-Warning header
Image and video moderation, term/image list management, the human review toolNot supported (text screening only)

How it compares

OptionSame ProcessText/Screen request and JSON?PriceNotes
This ActorYes: change the endpoint, add an Apify token$1 per 1,000 textsCategory scores approximate; custom term lists (listId) not supported
Azure Content ModeratorIt is the originalAzure pricingRetires 15 Mar 2027
Azure AI Content SafetyNo: different request and JSON (severity levels per harm category)Azure pricingMicrosoft's recommended successor; rewrite and re-tune
Standalone profanity or PII APIsNoVariesCover only part of the Screen response

Pricing

$1.00 per 1,000 screened texts (pay-per-event text-screened). Requests that fail validation (empty, too long, wrong content type) are not charged. Apify also adds its standard small per-start fee to each run, and you don't pay for idle time in Standby mode. Set a maximum total charge per run; once it is reached the API returns 429 {"Error":{"Code":"TooManyRequests",…}}.

Batch mode (no code)

Run the Actor normally with a list of texts and get one dataset row per text. Each row has the category scores, terms and PII, plus the full Content Moderator response. You can export it as CSV, Excel or JSON.

{ "texts": ["Thanks for your order, it ships tomorrow.", "This is crap, you idiot. Email me at someone@example.com"], "PII": true }

How scores are computed

  • Category1 = Detoxify sexual_explicit.
  • Category3 = the maximum of toxicity, obscene, insult, threat and identity_attack.
  • Category2 = max(Category1, 0.3 × obscene).

Detoxify is Apache-2.0 Detoxify (unbiased-toxic-roberta, quantized ONNX, running on CPU inside the Actor). Clear-cut offensive text scores 0.95–0.99 on Category3, and benign text scores below 0.01. Scores are not identical to Azure's. If you rely on precise thresholds, re-check them on a sample of your own texts with batch mode before switching traffic.

Language is auto-detected and returned as an ISO 639-3 code. Latin-script text shorter than 40 characters is treated as English. For short non-English texts, pass language=spa, language=deu and so on so that the right profanity list is used.

Latency

On a warm instance, a screen takes about 20–80 ms and the instance handles about 15+ requests/s. After about 5 minutes without requests the instance sleeps, and the next request waits a few seconds while it starts.

Limits

  • Text only: image and video moderation, term/image list management and the human review tool are not supported.
  • Up to 1,024 characters per text, as in Azure's own Screen API; longer text returns HTTP 400.
  • Custom term lists (listId) are not supported; the built-in term list is applied and the response carries an X-Compat-Warning header.
  • Category scores are independent Detoxify estimates, not identical to Azure's; re-check any threshold on a sample of your own texts (batch mode makes that easy) before switching traffic.
  • After about 5 minutes without requests the Standby instance sleeps, and the next request waits a few seconds while it starts.

FAQ

What replaces Azure Content Moderator without rewriting my code?

This endpoint. It takes the same ProcessText/Screen path, query parameters and raw-text body, and returns the same JSON. $1 per 1,000 successful screens.

Is this a profanity filter?

Yes, among other things. The built-in Terms list covers profanity in 24 languages (the same categories Azure Content Moderator shipped), with the correct Index/OriginalIndex character offsets so you can redact in place. Pass classify=True/PII=True too for the Category1/2/3 classification and PII detection in the same call.

When does Azure Content Moderator retire?

15 March 2027 according to Microsoft's product overview; the lifecycle page says 1 April 2027. Plan for 15 March.

Is Azure AI Content Safety a drop-in replacement?

No. It uses different fields (severity levels for Hate, Sexual, SelfHarm and Violence) and a different request. Use it if you can change your parser and re-tune; use this Actor if you can't yet.

Does it detect email, phone and address (PII)?

Yes. PII follows the Content Moderator shape: Email, IPA (IPv4/IPv6), Phone (US/UK), Address (US with state and ZIP) and SSN. Patterns are deliberately strict.

Are Category1, Category2 and Category3 the same numbers as Azure?

They are the same fields, computed by an open model. Category2 (suggestive) is a documented proxy. ReviewRecommended is true when any category is ≥ 0.5. Re-check thresholds on your own texts.

Are custom term lists (listId) supported?

No. Custom lists live inside your Azure resource. The built-in list (ListId 0) is always applied, and the response carries an X-Compat-Warning header when you pass a custom listId.

What does a ProcessText/Screen call cost?

$0.001 per screened text ($1 per 1,000). Requests that fail validation are not charged.

Is my text stored?

No. Nothing is written to disk or logged; text is screened in memory and discarded.

What about short non-English texts?

Latin-script text under 40 characters is treated as English. Pass language=spa, language=deu and so on to use the right profanity list.

Is this affiliated with Microsoft?

No. It is an independent, compatible implementation of the public Content Moderator v1.0 text screening interface.