TL;DR: Two things change when you swap from Perspective to Respectify’s compatible endpoint: the URL and the auth header. Everything else — your request body, attribute names, response parsing, thresholds — stays the same.
Google’s Perspective API is shutting down. If you have a running integration, you need to move. This post skips the theory and shows you the exact changes in TypeScript, Python, and PHP.
For the full migration story — what maps to what, how to handle spans, when to upgrade to full moderation — read the migration guide.
What changes (and what doesn’t)
Changes:
- Base URL:
https://commentanalyzer.googleapis.com→https://app.respectify.org - Path:
/v1alpha1/comments:analyze→/v0.2/perspective-compat/analyse - Auth: query-string
?key=YOUR_KEY→Authorization: Bearer YOUR_KEYheader - You’ll need a
Respectify-Emailheader alongside the bearer token
Stays the same:
- Request body shape (
comment.text,requestedAttributes,languages) - Response structure (
attributeScores,summaryScore,spanScores) - Your thresholds and downstream logic
- Your
suggestScorecalls (different path, same shape)
Before you start
Sign up and get your API key from the dashboard. Add two environment variables:
RESPECTIFY_API_KEY=your-api-key
RESPECTIFY_EMAIL=you@example.com
TypeScript / JavaScript
Before (Perspective)
const response = 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: commentText },
requestedAttributes: { TOXICITY: {}, INSULT: {} },
}),
}
);
const data = await response.json();
const toxicityScore = data.attributeScores.TOXICITY.summaryScore.value;
After (Respectify)
const response = await fetch("https://app.respectify.org/v0.2/perspective-compat/analyse", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.RESPECTIFY_API_KEY}`,
"Respectify-Email": process.env.RESPECTIFY_EMAIL,
},
body: JSON.stringify({
comment: { text: commentText },
requestedAttributes: { TOXICITY: {}, INSULT: {} },
}),
});
const data = await response.json();
const toxicityScore = data.attributeScores.TOXICITY.summaryScore.value; // unchanged
Or use the TypeScript SDK to skip the raw fetch:
import { RespectifyClient } from "@respectify/client";
const client = new RespectifyClient({
apiKey: process.env.RESPECTIFY_API_KEY,
email: process.env.RESPECTIFY_EMAIL,
});
const result = await client.perspectiveCompat.analyse({
comment: { text: commentText },
requestedAttributes: { TOXICITY: {}, INSULT: {} },
});
const toxicityScore = result.attributeScores.TOXICITY.summaryScore.value;
Python
Before (Perspective)
import httpx
response = httpx.post(
f"https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze",
params={"key": os.environ["PERSPECTIVE_API_KEY"]},
json={
"comment": {"text": comment_text},
"requestedAttributes": {"TOXICITY": {}, "INSULT": {}},
},
)
data = response.json()
toxicity_score = data["attributeScores"]["TOXICITY"]["summaryScore"]["value"]
After (Respectify)
import httpx
response = httpx.post(
"https://app.respectify.org/v0.2/perspective-compat/analyse",
headers={
"Authorization": f"Bearer {os.environ['RESPECTIFY_API_KEY']}",
"Respectify-Email": os.environ["RESPECTIFY_EMAIL"],
},
json={
"comment": {"text": comment_text},
"requestedAttributes": {"TOXICITY": {}, "INSULT": {}},
},
)
data = response.json()
toxicity_score = data["attributeScores"]["TOXICITY"]["summaryScore"]["value"] # unchanged
PHP
Before (Perspective)
$response = $client->post(
"https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key={$_ENV['PERSPECTIVE_API_KEY']}",
[
'json' => [
'comment' => ['text' => $commentText],
'requestedAttributes' => ['TOXICITY' => new stdClass(), 'INSULT' => new stdClass()],
],
]
);
$data = json_decode($response->getBody(), true);
$toxicityScore = $data['attributeScores']['TOXICITY']['summaryScore']['value'];
After (Respectify)
$response = $client->post(
'https://app.respectify.org/v0.2/perspective-compat/analyse',
[
'headers' => [
'Authorization' => 'Bearer ' . $_ENV['RESPECTIFY_API_KEY'],
'Respectify-Email' => $_ENV['RESPECTIFY_EMAIL'],
],
'json' => [
'comment' => ['text' => $commentText],
'requestedAttributes' => ['TOXICITY' => new stdClass(), 'INSULT' => new stdClass()],
],
]
);
$data = json_decode($response->getBody(), true);
$toxicityScore = $data['attributeScores']['TOXICITY']['summaryScore']['value']; // unchanged
Handling suggestScore
If your integration sends score corrections via Perspective’s suggestscore endpoint, the same pattern applies:
| Perspective | Respectify |
|---|---|
POST /v1alpha1/comments:suggestscore?key=... | POST /v0.2/perspective-compat/suggestscore |
| Query-string key | Bearer token + email header |
| Same request body | Same request body |
Note: feedback sent to suggestscore is retained by Respectify to improve the service. Don’t send content you aren’t comfortable storing.
Validate before going live
Run both endpoints in parallel on a sample of real comments and compare scores for your key attributes. Expect close alignment on TOXICITY and INSULT. Some Perspective attributes don’t have direct equivalents — check the attribute mapping docs if you use anything beyond the common set.
Once scores look right in staging, swap production. Your thresholds, queues, and admin tools need no changes.
What’s next
The compatibility endpoint gets you migrated. When you’re ready to go further, Respectify can stop bad comments before they post — and explain to the commenter why, so they have a chance to revise. That’s configurable per site and doesn’t require touching the code you just migrated.
Powered by Respectify
Comments are analyzed in real time for spam and respectfulness before they appear. Leave a comment to see Respectify in action.
Comments (…)
Loading comments…
No comments yet. Be the first to comment!
Leave a Comment
Your comment will be reviewed by Respectify before it appears.