Google's Jigsaw is turning off Perspective API. It already stopped accepting new users earlier this year, and after December 31, 2026 it stops answering everyone else.

If you run comments, a forum or a chat with Perspective behind it, that's a few weeks from now. Coral's toxic comment filter, the Discourse plugin, Drupal modules and plenty of homemade scripts all call the same endpoint:

https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze 

This post shows how to point that call somewhere else without rewriting anything.

Disclosure: this is written by the team behind VigiMod, the API used in the examples. It's free during the beta.

The short version

VigiMod exposes the same path and accepts the same JSON. You change the host and the key:

- https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key=PERSPECTIVE_KEY + https://api.vigimod.com/v1alpha1/comments:analyze?key=VIGIMOD_KEY 

The request body stays the same, and the response has the same shape (attributeScores.<ATTRIBUTE>.summaryScore.value), so the code that reads it doesn't change either.

Before and after in Python

Before:

import requests r = requests.post( "https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze", params={"key": PERSPECTIVE_KEY}, json={ "comment": {"text": message}, "languages": ["en"], "requestedAttributes": {"TOXICITY": {}, "INSULT": {}, "THREAT": {}}, }, ) scores = {k: v["summaryScore"]["value"] for k, v in r.json()["attributeScores"].items()} flagged = scores["TOXICITY"] >= 0.8 

After:

import requests r = requests.post( "https://api.vigimod.com/v1alpha1/comments:analyze", # new host params={"key": VIGIMOD_KEY}, # new key json={ "comment": {"text": message}, "languages": ["en"], "requestedAttributes": {"TOXICITY": {}, "INSULT": {}, "THREAT": {}}, }, ) scores = {k: v["summaryScore"]["value"] for k, v in r.json()["attributeScores"].items()} flagged = scores["TOXICITY"] >= 0.8 

With curl

curl -s "https://api.vigimod.com/v1alpha1/comments:analyze?key=$VIGIMOD_KEY" \ -H "Content-Type: application/json" \ -d '{"comment": {"text": "you are an idiot"}, "requestedAttributes": {"TOXICITY": {}, "INSULT": {}}}' 
{ "attributeScores": { "TOXICITY": {"summaryScore": {"value": 1.0, "type": "PROBABILITY"}}, "INSULT": {"summaryScore": {"value": 0.9998, "type": "PROBABILITY"}} } } 

With Node.js

const r = await fetch( `https://api.vigimod.com/v1alpha1/comments:analyze?key=${process.env.VIGIMOD_KEY}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ comment: { text: message }, requestedAttributes: { TOXICITY: {}, PROFANITY: {} }, }), }, ); const { attributeScores } = await r.json(); const toxicity = attributeScores.TOXICITY.summaryScore.value; 

Coral, Discourse and Drupal

Coral. In Admin → Configure → Moderation, under the Toxic Comment Filter, set the Perspective endpoint to https://api.vigimod.com/v1alpha1 and paste your VigiMod key. If your Coral version has a timeout for the check (older versions use TALK_PERSPECTIVE_TIMEOUT, 300 ms by default), give it some room, around 1000 ms: when the answer arrives late, Coral skips the score.

Discourse. The official Perspective plugin calls Google's host directly and has no setting for it. In your copy of the plugin, replace commentanalyzer.googleapis.com with api.vigimod.com, and put the VigiMod key in perspective_google_api_key.

Drupal and everything else. Any module or script that lets you set the Perspective URL works as is. If the URL is hardcoded, it's one line.

Which attributes are supported

Perspective attribute Scored from
TOXICITY toxicity
SEVERE_TOXICITY hate and threats (a message that is only rude stays under 0.7)
IDENTITY_ATTACK hate
INSULT insults
THREAT threats
SEXUALLY_EXPLICIT sexual content
PROFANITY (and OBSCENE) swearing and vulgar language
FLIRTATION flirting and sexual advances
SPAM unsolicited advertising

The _EXPERIMENTAL names are accepted too. Attributes that aren't scored (ATTACK_ON_AUTHOR, INCOHERENT, INFLAMMATORY, LIKELY_TO_REJECT, UNSUBSTANTIAL and the bridging ones) return a 400 error that names them, rather than a made-up number.

What to check before switching

A few things behave differently, and it's better to know them up front:

  • The scores come from a different model. They're rescaled so that 0.7 is VigiMod's tuned threshold for each attribute, which means thresholds between 0.7 and 0.9 behave sensibly. Still, watch a few days of real comments before trusting your old numbers blindly.
  • context.entries is read by the model. The previous messages change the scores, so replies and quotes are judged together with what came before.
  • Long comments (over 1,000 characters) are scored in parts, up to 10,000 characters. Each part counts as one message for the rate limit, and spanScores gives you the score of each part.
  • Nothing is stored. Comments are scored and discarded. comments:suggestscore is accepted for compatibility, but the suggested scores aren't kept.
  • Languages: any language code is accepted. The model understands 26 languages and works best in English, Italian, Spanish, French, German and Portuguese.

Beyond Perspective

The compatible endpoint is the quick switch. The same key also works with VigiMod's own /moderate endpoint, which adds a few things Perspective never had:

  • custom rules written as plain sentences ("no selling accounts", "no spoilers"), each with its own score;
  • per-user spam detection;
  • policies that turn scores into actions (warn, timeout, ban), with a review queue for moderators and webhooks.

There's also a public benchmark on HateCheck and Multilingual HateCheck in six languages, with every prediction downloadable: vigimod.com/en/benchmark.

Getting a key

  1. Create a free account at vigimod.com and generate an API key.
  2. Swap the host and the key.
  3. Watch a few days of real traffic and adjust thresholds if needed.

The full migration guide, with the attribute table and per-tool settings, is at vigimod.com/en/perspective-api-alternative. Questions go to support@vigimod.com, or leave them in the comments here.