Skip to content

Migrate from Google Perspective API

Google is sunsetting the Perspective API on December 31, 2026. Sieve offers a compatibility endpoint that accepts Perspective API request format, so you can migrate by changing a single URL.

Sieve’s /v1/perspective/analyze endpoint accepts the same request format as the Perspective API. For many applications, migration is a one-line change.

const response = await fetch(
'https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key=YOUR_GOOGLE_KEY',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
comment: { text: 'This is a comment to analyze' },
requestedAttributes: {
TOXICITY: {},
SEVERE_TOXICITY: {},
IDENTITY_ATTACK: {},
INSULT: {},
PROFANITY: {},
THREAT: {},
},
}),
}
);
const response = await fetch(
'https://api.getsieve.dev/v1/perspective/analyze',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer mod_live_your_key',
},
body: JSON.stringify({
comment: { text: 'This is a comment to analyze' },
requestedAttributes: {
TOXICITY: {},
SEVERE_TOXICITY: {},
IDENTITY_ATTACK: {},
INSULT: {},
PROFANITY: {},
THREAT: {},
},
}),
}
);

What changed:

  1. The URL: commentanalyzer.googleapis.com/... to api.getsieve.dev/v1/perspective/analyze
  2. Authentication: Google API key in the URL to Sieve Bearer token in the header
  3. That’s it. The request body and response format are the same.

Sieve maps Perspective API attributes to its own categories:

Perspective AttributeSieve CategoryNotes
TOXICITYtoxicityDirect mapping
SEVERE_TOXICITYtoxicity (high threshold)Mapped to toxicity with higher score threshold
IDENTITY_ATTACKhate_speechBroader detection including non-identity-based hate
INSULTharassmentIncludes bullying and personal attacks
PROFANITYtoxicityRolled into toxicity scoring
THREATviolenceIncludes doxxing and swatting threats
SEXUALLY_EXPLICITsexualDirect mapping
FLIRTATIONsexual (lower scores)Mapped to sexual with reduced scores
// Before: Google Perspective API
const { google } = require('googleapis');
const client = await google.discoverAPI(
'https://commentanalyzer.googleapis.com/$discovery/rest?version=v1alpha1'
);
const result = await client.comments.analyze({
key: process.env.PERSPECTIVE_API_KEY,
resource: {
comment: { text: userComment },
requestedAttributes: { TOXICITY: {}, THREAT: {} },
},
});
const toxicityScore = result.data.attributeScores.TOXICITY.summaryScore.value;
// After: Sieve (compatibility endpoint)
const result = await fetch('https://api.getsieve.dev/v1/perspective/analyze', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.SIEVE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
comment: { text: userComment },
requestedAttributes: { TOXICITY: {}, THREAT: {} },
}),
}).then(r => r.json());
const toxicityScore = result.attributeScores.TOXICITY.summaryScore.value;
# Before: Google Perspective API
from googleapiclient import discovery
client = discovery.build(
"commentanalyzer", "v1alpha1",
developerKey=os.environ["PERSPECTIVE_API_KEY"],
)
result = client.comments().analyze(body={
"comment": {"text": user_comment},
"requestedAttributes": {"TOXICITY": {}, "THREAT": {}},
}).execute()
toxicity = result["attributeScores"]["TOXICITY"]["summaryScore"]["value"]
# After: Sieve (compatibility endpoint)
import requests
result = requests.post(
"https://api.getsieve.dev/v1/perspective/analyze",
headers={
"Authorization": f"Bearer {os.environ['SIEVE_API_KEY']}",
"Content-Type": "application/json",
},
json={
"comment": {"text": user_comment},
"requestedAttributes": {"TOXICITY": {}, "THREAT": {}},
},
).json()
toxicity = result["attributeScores"]["TOXICITY"]["summaryScore"]["value"]

While the compatibility endpoint returns scores in Perspective format, there are some differences to be aware of:

AspectPerspective APISieve
Score range0.0 - 1.00.0 - 1.0 (same)
Granularity6 attributes7 categories + sub-scores
Spam detectionNot availableBuilt-in spam/RMT detection
Context awarenessNoneContext multipliers (username, chat, forum)
Custom rulesNot availableWordlist, regex, allowlist rules
Latency200-500ms~180ms blended (60-70% resolved locally)
Gaming contextPoorGaming mode with banter awareness

While the compatibility endpoint gets you migrated quickly, switching to Sieve’s native API gives you access to all features:

Change the URL and auth. Verify scores are comparable. This takes minutes.

Move to POST /v1/moderate/text for new features: contexts, custom rules, and action recommendations (allow/flag/block).

Tag your content with the right context (forum_post, comment, username) for threshold tuning.

Add platform-specific allowlists and blocklists via the Custom Rules API.

// Native Sieve API (full features)
const result = await fetch('https://api.getsieve.dev/v1/moderate/text', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.SIEVE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
text: userComment,
context: 'comment',
username: authorUsername,
}),
}).then(r => r.json());
// Native response includes action recommendation
if (result.action === 'block') {
hideComment();
} else if (result.action === 'flag') {
queueForReview();
}