Skip to content

Real-time chat moderation for Unity games

Send each message to Chat Guard before you deliver it. Back come six calibrated verdict probabilities, a severity, who the message targets and a recommended action, computed from thresholds your studio tunes. If the model is unreachable, a local dictionary filter answers instead of an error.

Free tier: 50,000 model verdicts per rolling 30 days. Sign in with Google or GitHub.

ChatServer.csUnity 2021.3 LTS and newer
using ChatGuard.Unity;

// On the server, when a player submits a line.
void OnPlayerMessage(string playerId, string text)
{
    ChatGuardSdk.Moderate(text, playerId, result =>
    {
        if (result.ShouldDeliver)   // allow or flag
            Show(text);
    });
}
Response from POST /v1/moderatehidden from other players
{  "action": "hide",  "severity": 1.815,  "verdicts": {    "insult": { "p": 0.91 }, "threat": { "p": 0.03 },    "hate": { "p": 0.05 }, "sexual": { "p": 0.01 },    "spam": { "p": 0.02 }, "trading": { "p": 0.0 }  },  "target": { "choice": "other_user", "confidence": 0.84 },  "degraded": false}

How it works

One request per message, one field to act on. The rest of the response is there when your policy needs more than allow or block.

  1. Send the message

    Your game server, or a client build carrying a publishable key, posts each chat line to POST /v1/moderate with an opaque player id and optional channel context, before anyone else sees it.

  2. Get typed verdicts and an action

    The response carries calibrated probabilities for insult, threat, hate, sexual, spam and trading, a severity from 0 to 3, who the message targets, and a recommended action: allow, flag, hide or block.

  3. Tune thresholds and rules

    Set per-project thresholds in the dashboard, add allow, block and context rules, read the verdict log and report false positives. Probabilities are calibrated, so 0.8 means right four times out of five.

What you get back, and what never leaves your control

Built for the way multiplayer chat actually fails: rude players, a model that is occasionally unreachable, clients you cannot trust, and privacy rules you have to keep.

Six calibrated categories
Insult, threat, hate, sexual, spam and account trading, each as a probability you can threshold. Because they are calibrated, a 0.8 is right about four times out of five, and the defaults are a sensible starting policy.
Severity and target
A severity from 0 to 3 and who the message is aimed at, with a confidence, so trash talk about the match and a line aimed at another player do not have to be treated the same.
Local fallback when the model is unavailable
If the model is down, rate limited or you are over quota, the answer comes from a dictionary filter with degraded: true instead of an error. The Unity package ships the same word lists and keeps working offline.
Publishable client keys with per-player limits
No authoritative server? Ship a cg_pub_ key in the client build. It can only moderate and read quota, requires a player id, and gets a per-key and a per-player rate limit, so one modified client cannot drain your budget.
Privacy by design
By default the service stores a hash of the normalized message, the verdicts and an opaque player id. No message text, no thread context, no player IP addresses, no device identifiers.
Evidence logging opt-in and per-player erasure
Paid projects can opt in to keep message text for a retention period they choose, so moderators can review context. One API call or dashboard action erases everything stored about a player id.

Works with your stack

The Unity package uses only UnityWebRequest, has no third-party dependencies and runs on Unity 2021.3 LTS and newer, WebGL included. Every other server speaks to the same HTTP API.

  • Netcode for GameObjectsmoderate in the ServerRpc, fan out with a ClientRpc
  • Mirrorsame pattern with [Command] and [ClientRpc]
  • Photon Fusionmoderate on the state authority before replicating
  • Photon PUNno trusted server, so route messages through the relay
  • Any server over HTTPone POST per message from C#, TypeScript, Python, Go or Java

Package Manager, Add package from git URL:

https://github.com/chatguard-dev/chat-guard.git?path=/unity

Pricing

Metered per model verdict. Block-rule hits, degraded answers, test keys and repeated request ids are free. Every organization starts on Free and upgrades from the dashboard.

Free

Free

50,000 model verdicts per 30 days

  • One language profile
  • Built-in rules only
  • No evidence logs
  • Community support
  • Degrades to the local filter above the limit

Indie

$29per month

1,000,000 model verdicts per 30 days

  • All languages
  • Custom allow, block and context rules
  • Evidence logs, up to 90 days
  • Email support
  • Overage $0.08 per 1,000 model verdicts

Studio

$199per month

10,000,000 model verdicts per 30 days

  • All languages
  • Custom allow, block and context rules
  • Evidence logs, up to 365 days
  • Evidence export, DPA, priority support
  • Overage $0.08 per 1,000 model verdicts

Payments and invoices are handled by Polar.sh, our merchant of record. Plan changes and cancellations take effect at the end of the current period.

Questions studios ask first

How fast is it?
Typically a few hundred milliseconds end to end, and every response reports its own latency_ms. In Unity the callback runs on the main thread when the answer arrives, so it can touch UI and networking directly; the package uses no threads or Tasks, which is why it also works on WebGL.
What counts toward the quota?
A request counts at most once, and only when it receives a model verdict: a fresh model evaluation or a hit in the 10-minute verdict cache. Block-rule hits, degraded answers, test keys, idempotent replays of a request_id and rejected requests are never counted or billed.
What happens when the model is down?
The response still arrives, from the local dictionary filter, with degraded: true and a degraded_reason of quota, upstream, upstream_rate_limit or timeout. Local verdicts are 0 or 1. Many studios apply a lighter policy in that state, for example hide instead of block.
Where does the key live?
Server keys (cg_live_) belong on your game server or on a relay you control, never in a client build. Publishable keys (cg_pub_) are made for client builds: moderate and quota only, player id required, per-key and per-player rate limits, and results computed on a player's device are advisory. Test keys (cg_test_) are for the Editor and CI: not metered, 1,000 requests per day.
GDPR and data retention?
Chat Guard is the data processor and your studio is the controller. By default the service keeps the message hash, verdicts, an opaque player id and operational metadata for 90 days, and never the text. Evidence logging is opt-in per project with a retention you choose up to the plan maximum, and expired rows are hard-deleted. Message text is sent to the model provider for inference only. Players can be erased by id through the API or the dashboard; the privacy page lists every sub-processor.