Perspective API alternative: migrate to Paxmod before December 31, 2026
Google's Perspective API stops working after December 31, 2026. Jigsaw closed new usage and quota requests in February 2026 and is not offering migration support. If your forum, comment section or game chat calls commentanalyzer.googleapis.com, that call will start failing on January 1.
Your migration choice splits into two paths: drop-in Perspective clones (same comments:analyze endpoint and attributeScores response) or a real-time chat moderation API built for gaming and live communities. If you need identical wire compatibility and only toxicity scoring, the drop-in class (Respectify, ExtraLenses, Moderation API) switches the endpoint URL and keeps your code. If you need game chat latency, PII detection, player context, images, and can change one function, Paxmod is the alternative this guide covers.
Perspective API shuts down after December 31, 2026
The service stays live until December 31, 2026. Usage and quota requests closed in February 2026. Google is not offering direct migration support. Use the remaining weeks to run Paxmod next to Perspective and compare scores on your real traffic before you cut over.
Two migration paths: drop-in clones vs real-time chat moderation
Drop-in Perspective clones
Same comments:analyze endpoint shape and attributeScores response. Change the URL, keep your integration.
- Respectify (near drop-in, toxicity + spam/coaching)
- ExtraLenses (self-hosted Docker, same JSON schema)
- Moderation API (moderationapi.com)
- Apify Perspective-Compat Actor
Real-time chat moderation API
Built for game chat with PII detection, player context, images, and under 500ms latency. Requires changing one function (this guide).
- Paxmod (Minecraft, Roblox, Unity)
- Personal information detection
- Player-aware conversation context
- Custom rules in plain English
Comparison: drop-in clones and Paxmod
| Solution | Type | Migration effort | Pricing | Best for |
|---|---|---|---|---|
| Respectify | Near drop-in cloud API | Change endpoint URL and auth header1 | $0.007 per comment (Perspective compat)2 | Existing Perspective integrations, comment moderation |
| ExtraLenses | Self-hosted Docker | Same request/response format, change URL3 | Self-hosted (infrastructure cost only) | On-premises deployments, data sovereignty |
| Google Cloud Natural Language | Google Cloud API | Different endpoint (moderateText), different response format | $0.0005 per 100 characters after 50k free units/month4 | Google Cloud customers, document moderation |
| Paxmod | Real-time chat API | Change one function: endpoint, auth, field mapping | From $29/month (50k messages), 14-day free trial | Game chat (Minecraft, Roblox, Unity), PII detection, images |
This guide covers migrating to Paxmod, the real-time chat moderation path. If you need wire-compatible attributeScores, use Respectify or ExtraLenses instead.
Migration to Paxmod at a glance
- Endpoint:
POST https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key=KEYbecomesPOST https://www.paxmod.com/api/v1/text - Auth:
?key=query parameter becomes anAuthorization: Bearer YOUR_API_KEYheader - Request:
comment.textbecomesmessage. Adduser_id(your player or user id) andcontext_id(channel, lobby or thread) if you have them - Attributes: you no longer list
requestedAttributesper request. You pick categories and thresholds per project in the Paxmod console - Response:
attributeScores.TOXICITY.summaryScore.valuebecomescontent_moderation.categories["Harassment"].score, or just checkresult === "flagged" - Max length: Paxmod accepts up to 5,000 characters per message (Perspective allowed 20 KB). Split longer text and check each part
Perspective attribute to Paxmod category mapping
| Perspective attribute | Paxmod category | Notes |
|---|---|---|
| TOXICITY | Harassment, Hate and Discrimination, Profanities | Take the highest of the three, or use the top-level result |
| SEVERE_TOXICITY | Threatening, Violence, Hate and Discrimination | Use the highest score |
| IDENTITY_ATTACK | Hate and Discrimination | Direct match |
| INSULT | Harassment | Harassment is a little broader than insult |
| THREAT | Threatening, Violence | Use the highest score |
| PROFANITY | Profanities | A dictionary matcher with lookalike-character handling. Test thresholds in the playground after migrating, since score scales differ from Perspective |
| SEXUALLY_EXPLICIT | Sexual | Direct match |
| FLIRTATION | No fixed category | Write it as an Advanced mode policy in plain English, for example "Flag romantic or sexual advances toward other players" |
Paxmod scores are not Perspective scores, so do not copy your Perspective thresholds across blindly. Each Paxmod category has its own threshold (default 0.5, flagged when the score is above it), set per project in the console.
Before and after code
curl, before (Perspective)
curl -X POST \
"https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key=$PERSPECTIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"comment": { "text": "you are trash, uninstall" },
"languages": ["en"],
"requestedAttributes": { "TOXICITY": {}, "INSULT": {}, "THREAT": {} }
}'curl, after (Paxmod)
curl -X POST "https://www.paxmod.com/api/v1/text" \
-H "Authorization: Bearer $PAXMOD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "you are trash, uninstall",
"user_id": "player_123",
"context_id": "lobby_7"
}'Node, before (Perspective)
const res = await fetch(
`https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key=${process.env.PERSPECTIVE_API_KEY}`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
comment: { text },
languages: ["en"],
requestedAttributes: { TOXICITY: {} },
}),
}
);
const data = await res.json();
const isToxic = data.attributeScores.TOXICITY.summaryScore.value > 0.8;Node, after (Paxmod)
const res = await fetch("https://www.paxmod.com/api/v1/text", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.PAXMOD_API_KEY}`,
},
body: JSON.stringify({ message: text, user_id: userId, context_id: channelId }),
});
const data = await res.json();
if (data.status === "error") throw new Error(data.error.code);
const isToxic = data.result === "flagged";
const harassment = data.content_moderation.categories["Harassment"]?.score ?? 0;Python, before (Perspective)
import os, requests
r = requests.post(
"https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze",
params={"key": os.environ["PERSPECTIVE_API_KEY"]},
json={
"comment": {"text": text},
"languages": ["en"],
"requestedAttributes": {"TOXICITY": {}},
},
timeout=5,
)
is_toxic = r.json()["attributeScores"]["TOXICITY"]["summaryScore"]["value"] > 0.8Python, after (Paxmod)
import os, requests
r = requests.post(
"https://www.paxmod.com/api/v1/text",
headers={"Authorization": f"Bearer {os.environ['PAXMOD_API_KEY']}"},
json={"message": text, "user_id": user_id, "context_id": channel_id},
timeout=5,
)
data = r.json()
is_toxic = data.get("result") == "flagged"
harassment = data.get("content_moderation", {}).get("categories", {}).get("Harassment", {}).get("score", 0)What the responses look like
Perspective (example)
{
"attributeScores": {
"TOXICITY": {
"spanScores": [
{
"begin": 0,
"end": 24,
"score": {
"value": 0.91,
"type": "PROBABILITY"
}
}
],
"summaryScore": {
"value": 0.91,
"type": "PROBABILITY"
}
}
},
"languages": ["en"],
"detectedLanguages": ["en"]
}Paxmod (example)
{
"status": "success",
"id": "5f0c2a8e-1d9b-4c47-9a51-3c1f6f2b7e10",
"service": "pax",
"request": {
"original_message": "you are trash, uninstall",
"processed_message": "you are trash, uninstall",
"timestamp": "2026-10-08T02:00:00.000Z"
},
"result": "flagged",
"reason": "Content flagged for Harassment",
"degraded": false,
"unavailable_categories": [],
"content_moderation": {
"flagged": true,
"categories": {
"Harassment": {
"flagged": true,
"threshold": 0.5,
"score": 0.93
},
"Threatening": {
"flagged": false,
"threshold": 0.5,
"score": 0.04
},
"Hate and Discrimination": {
"flagged": false,
"threshold": 0.5,
"score": 0.02
},
"Profanities": {
"flagged": false,
"threshold": 0.5,
"score": 0
},
"Personally Identifiable Information": {
"flagged": false,
"threshold": 0.5,
"score": 0.01
}
}
}
}result is flagged when any enabled category is above its threshold. reason names the categories.
degraded: true means an upstream classifier was briefly unavailable and the categories in unavailable_categories were not scored on that call.
Errors come back as {"status": "error", "error": {"code": "...", "message": "..."}}, for example INVALID_API_KEY (401), EMPTY_MESSAGE or MESSAGE_TOO_LONG (400).
How to migrate from Perspective API in 6 steps
- 1
Start a Paxmod trial
Sign up at paxmod.com, start the 14-day free trial (10,000 messages, every feature) and create a project. Copy its API key from the console.
- 2
Choose your categories
Turn on the Paxmod categories that match the Perspective attributes you used (see the mapping table). For game chat, the Gaming chat preset is a good start and includes personal information detection.
- 3
Swap the request
Point the call at
https://www.paxmod.com/api/v1/text, send the key asAuthorization: Bearer, and send the text asmessagewithuser_idandcontext_id. - 4
Swap the response parsing
Replace
attributeScores.X.summaryScore.valuewithcontent_moderation.categories[...].score, or act onresult === "flagged". - 5
Shadow-run and tune thresholds
Until December 31, send the same messages to both APIs, compare decisions on your real traffic and set each Paxmod category threshold in the console.
- 6
Cut over
Act on Paxmod's decision, then remove the Perspective key and code before January 1, 2027.
Game chat and Minecraft moderation: why Paxmod over drop-in clones
If you run a Minecraft server, Roblox game, Unity multiplayer, or other live gaming community, Paxmod is built for your use case. Drop-in Perspective clones score toxicity, but game chat needs PII detection, player context, and under 500ms latency. Paxmod is built for Minecraft, Roblox, and Unity game chat.
What Paxmod adds beyond toxicity scoring
- Personal information detection. Messages like "where do you live" are flagged under Personally Identifiable Information. Perspective has no attribute for this, and in kids' game chat it matters more than swearing.
- Player-aware. Send
user_idandcontext_idwith each message. Studio adds conversation context, which moderates a message against the player's recent history instead of in isolation. - Your own rules in plain English. Advanced mode checks messages against a policy you write, so you can cover things Perspective never had an attribute for.
- Harder to dodge. Text is normalised before scoring, including Unicode lookalike characters and hidden zero-width characters.
- Images too. Studio adds image moderation through the same API.
- COPPA-oriented setup and data residency in Canada or the EU on Enterprise.
Pricing
Perspective was free, and Paxmod is not. What you pay for is a supported API that stays up after January 1.
- Indie: $29/month, 50,000 message credits, then $0.40 per 1,000. For small games, Roblox and Minecraft servers, and Discord communities.
- Studio: $149/month, 500,000 message credits, then $0.25 per 1,000. Adds conversation context, image moderation, team seats and priority support.
- Enterprise: from $1,500/month on an annual contract.
- Every plan starts with a 14-day free trial: 10,000 messages and every feature. Card required.
Frequently Asked Questions
Is Perspective API shutting down?
Yes. Google's Jigsaw team is sunsetting Perspective API. It stays live until December 31, 2026 and stops working after that. Usage and quota requests closed in February 2026, and Google is not offering migration support.
Can I replace Perspective API without changing my request format?
No. Paxmod uses its own request and response format, so you change the endpoint, the auth header and the fields you read. For most integrations that is one function. This page has the full field mapping and before and after code in curl, Node and Python.
How do Perspective attributes map to Paxmod categories?
TOXICITY maps to Harassment, Hate and Discrimination and Profanities. SEVERE_TOXICITY maps to Threatening, Violence and Hate and Discrimination. IDENTITY_ATTACK maps to Hate and Discrimination, INSULT to Harassment, THREAT to Threatening and Violence, PROFANITY to Profanities and SEXUALLY_EXPLICIT to Sexual. FLIRTATION has no fixed category, so write it as an Advanced mode policy.
Can I reuse my Perspective thresholds?
Not directly. Paxmod scores come from different models, so a 0.8 in Perspective is not a 0.8 in Paxmod. Run both APIs on the same traffic while Perspective is still live, then set each Paxmod category threshold in the console. The default is 0.5.
How long does the migration take?
The code change is usually a single function: new URL, a Bearer header, a different field to read. Leave extra time to shadow-run both APIs and tune thresholds before December 31.
Does Paxmod work for game chat on Minecraft, Roblox and Unity?
Yes. Paxmod is built for Minecraft, Roblox, and Unity game chat. See the Minecraft, Roblox and Unity integration guides.
How much does Paxmod cost?
Plans start at $29/month with 50,000 message credits, and Studio is $149/month with 500,000. Every plan starts with a 14-day free trial with 10,000 messages and every feature.
What is the maximum message length?
5,000 characters per message. Perspective accepted up to 20 KB, so split longer comments or posts into parts and check each one.
Migrate before January 1
Start a 14-day free trial with 10,000 messages and every feature, and run Paxmod next to Perspective on your real traffic.
Related links
Perspective API for Minecraft servers
Switch your server chat to Paxmod before December 31
Roblox chat moderation
Layer Paxmod on TextFilter for grooming detection
Unity chat moderation
Real-time moderation for Unity multiplayer games
Game chat moderation
Built for live multiplayer game chat
OpenAI Moderation API alternative
When to move beyond OpenAI's free endpoint
Forum and community moderation
Real-time moderation for forums and UGC platforms