chatguard.dev/privacy

Privacy notes

Last updated 23 September 2026.

What changed: this page now covers the account data Chat Guard controls and your rights; names our email providers; describes the complete erasure of a player, the trimmed evidence thread, how retention changes and "Delete stored evidence now" affect stored messages, evidence export in parts, feedback notes and the Unity Hook's install id; says that TypeSafe gets thread lines under neutral stand-in labels, never the game's labels or any author id; lists the data Polar holds; gives the 7-day log retention; and corrects the Fly.io and TypeSafe locations.

Chat Guard is operated by Kirill Tolmachev pr Beograd (Belgrade, Serbia). For moderated messages, Chat Guard is the data processor and the game studio using the service is the controller. For the data of dashboard users, billing contacts and people who email us, Chat Guard is the controller (Data we control, and your rights). This page describes what the service stores and for how long. The processor commitments are in the data processing agreement, which forms part of the terms on every plan.

Playing a game that uses Chat Guard? The game's studio runs its chat and decides how it's moderated, so ask the game about your data. If you write to us instead, we pass your request on to the studio when we can tell which game it is (DPA section 8).

Chat Guard is a moderation proxy. Game servers send chat messages to POST /v1/moderate; the service returns verdicts and does not keep the message text unless a project opts in.

What is stored by default (per moderated message)

FieldPurposeRetention
SHA-256 of the normalized messagerepeat detection, verdict cache key90 days, or longer while the message's evidence is kept (below)
Verdict probabilities, severity, action, target confidencedashboard log, tuningsame
Opaque author id (as supplied by the game, or the Unity Hook's install id below; never a real name)per-player erasure and export, feedback reviewsame, or until erased
Degraded/cached flags, model version, latency, token count, channel type, key kindoperationssame
Timestamp, project id, request idcorrelation, idempotencysame

Erasing a player removes the author id, the message hash and the request id from their verdict rows (Erasure and access).

Not stored by default: message text, thread context, IP addresses of players (the API sees only the game server), device identifiers. Publishable client keys (cg_pub_) change nothing about what is stored: the required author.id is the same opaque field, and the per-player rate-limit buckets live in Redis as hashed ids for at most a few minutes. When clients call the API directly, the API does see player IP addresses in transit; they are not logged or stored.

Unity Hook install id. If a game uses the Unity package's Hook component without setting a player id, the package creates a random id once per installation, keeps it on the player's device (in the game's PlayerPrefs) and sends it as the author id, so the same installation always sends the same id. It isn't taken from the device, the player or any account, and names none of them, but it is a persistent pseudonymous id: it stays the same until the game's PlayerPrefs are cleared, and it is handled like any other author id, erasure and export included. Dedicated server builds don't create or send one.

Feedback. When a game reports a wrong call with POST /v1/feedback, its server sends the kind (false positive or false negative) and an optional note of up to 1,000 characters. Both are kept with the verdict and deleted with it; notes on an erased player's verdicts are cleared.

The normalized-text hash is unsalted, as specified; a short common message therefore has a predictable hash. It is treated as pseudonymous data, removed when the player is erased and otherwise purged with the verdict row.

Evidence logging (opt-in per project)

When a project owner or admin enables evidence logging (Indie, Studio and Enterprise plans), the raw message text is stored in evidence_log together with the thread context the model saw: at most the last 5 lines, each cut to 500 characters, with the author labels the game sent. It is kept for the configured retention period (1 day to the plan maximum: 90 days on Indie, 365 on Studio and Enterprise; default 30), and an hourly job hard-deletes rows once they expire.

  • Shortening the retention, or moving to a plan with a lower maximum, shortens it for messages already stored too; it never lengthens it. On a plan without evidence logging, stored messages are deleted by the hourly job, starting with its next run.
  • Turning evidence logging off stops storing new messages; stored ones expire on their dates.
  • "Delete stored evidence now" in the project settings (owners and admins, every plan) deletes all of a project's stored messages at once.

A verdict row older than 90 days is kept until the evidence for its message expires, so evidence always stays linked to its verdict. Studio and Enterprise projects can export evidence as JSON, in parts of up to 100,000 messages, oldest first.

Erasure and access

  • The dashboard's "Export a player" action (owners and admins, every plan) downloads everything a project stores for one author id as JSON: their verdicts with any feedback notes, their stored messages, and their lines in other players' stored threads.
  • DELETE /v1/evidence/{projectId}?author_opaque_id=… (with a server or test key of the project) and the dashboard's "Erase a player" action erase a player completely: their evidence rows are hard-deleted; the author id, message hash and request id are removed from their verdict rows, so the statistics that remain no longer carry anything that names the player; their lines are removed from other players' stored threads; and the notes of feedback on their verdicts are cleared.
  • Lines in stored threads are found by their author label, so a game should label each thread line with the same player id it sends as the author id (the Unity package's sample does).
  • Deleting a project (owners and admins, in its settings) deletes its keys, rules, verdicts, evidence, feedback and usage at once.
  • Organizations are deleted on request to support@chatguard.dev, within 30 days; the deletion cascades to their projects and members.

Caches (Redis, transient)

Verdict cache entries (10 minutes) hold probabilities keyed by hash; idempotency entries (10 minutes) hold the full response for a request_id, which contains no message text. Quota counters hold per-organization daily counts of messages checked by the model (a number, no message data) for 31 days. Verdict and evidence records pass through a Redis queue on their way to Postgres and are removed from it once written. For requests made with a Free organization's keys, the game's bundle id (the X-ChatGuard-App header, which names the game, not a player) is kept with the ids of the organizations that sent it for 30 days, to spot one game spread across several Free organizations.

Sub-processors

ProviderRoleLocationData
TypeSafe AI, Inc. (Jev)model inferenceUnited States (TypeSafe runs the model in AWS us-west-2)message text; the last 5 thread lines, labeled only with neutral stand-ins ("sender", "player 2" and so on), never with the game's labels or any author id; channel and author metadata; policy lines. Not used for training per TypeSafe's terms (TypeSafe offers zero data retention on its enterprise plans)
Polar.shpayments, merchant of recordPolar (EU/US)organization owner email, organization name, billing details entered at checkout, the IP address of the owner who starts checkout, organization id and slug, daily message counts of paid organizations
Fly.iohostingAmsterdam, Netherlands (processing and storage); requests enter through the Fly.io edge nearest the sender, where TLS ends, and are carried encrypted to Amsterdameverything above in transit and in process memory; server logs
Neon (Databricks)PostgresFrankfurtthe tables above
Upstashcache, counters, queueFrankfurtcaches and queued log rows (seconds)
Cloudflare, Inc. (Turnstile)check that a person, not a script, creates an organizationCloudflare's global networkthe dashboard user's IP address and browser signals while the check runs; no player data

Polar handles account and billing data only, and Cloudflare Turnstile only sees dashboard users while they create an organization. The other four process player data under the data processing agreement, which lists their transfer mechanisms (Annex III) and announces changes to them 30 days ahead (section 7). Message text and thread lines leave the EU when they are sent to TypeSafe for inference, under the EU standard contractual clauses.

Accounts

Dashboard users sign in with Google or GitHub; there are no passwords. For each account Chat Guard stores:

  • the verified email address, display name and avatar URL the provider shares;
  • the Google or GitHub account id, which ties later sign-ins to the account;
  • refresh tokens, stored hashed; each expires after 30 days.

When someone signs up with GitHub, the service also reads when their GitHub account was created, to turn away brand-new accounts; that date is not stored.

Organizations keep their name and slug, their members and roles, and invitations. An invitation holds the email address it was sent to: until that person signs in, it's all Chat Guard knows about them, and it stays until the invitation or membership is removed.

For paid plans, Chat Guard keeps the Polar customer id; the subscription record, with the customer details Polar sends (such as the billing email and name), while the organization exists; and Polar's webhook messages, which include the customer email, for 90 days. Card details are entered at Polar and never reach Chat Guard.

Email

Mail to support@chatguard.dev and sales@chatguard.dev is delivered through Cloudflare Email Routing to a Google (Gmail) mailbox and answered through Cloudflare Email Sending. Never send player data by email: use "Export a player" and "Erase a player" for players' requests, and refer to a specific message by its verdict or request id (DPA section 8). Our Discord server runs on Discord, under Discord's own terms; don't post keys or player data there either.

Logs and traces

Structured logs never contain message text. OpenTelemetry tracing is off in production, and no analytics, error-tracking or tracing service receives data from the service. Fly.io keeps the server logs for up to 7 days.

Data we control, and your rights

For the data of dashboard users, billing contacts and people who email us (Accounts and Email above), the controller is Kirill Tolmachev pr Beograd, Belgrade, Serbia. Contact: support@chatguard.dev. Account and organization data is stored in the EU (Neon, Frankfurt). Email is kept in a Google (Gmail) mailbox, and billing details at Polar. The providers named on this page handle this data, and some of them are based in the United States.

Why we use it

  • Contract, or the steps before one: signing you in; running your organizations, projects and memberships; billing through Polar; answering your email.
  • Legitimate interests: letting organizations invite the people they work with, and security and abuse prevention, such as the Cloudflare Turnstile check when an organization is created, the GitHub account-age check at sign-up, rate limits, and the operator's abuse alerts (which name organizations by id only).
  • Legal obligation: tax and accounting records, where the law requires them.

How long we keep it

  • Accounts: until you ask us to delete yours. Email support@chatguard.dev from the account's address and we delete it within 30 days, together with its memberships. Organizations are deleted only when their owners ask (Erasure and access).
  • Invitations: until the invitation or membership is removed.
  • Refresh tokens: 30 days.
  • Subscription record: while the organization exists.
  • Polar webhook messages: 90 days.
  • Server logs: up to 7 days on Fly.io.
  • Email: in the mailbox for as long as it takes to handle the request.
  • Tax and accounting records: as long as the law requires.

Deleted rows remain in the database provider's restore history for up to 7 days and in its encrypted backups until they expire.

Your rights

You can ask for a copy of your data (also in a machine-readable format), and for it to be corrected, deleted or restricted, and you can object to uses based on legitimate interests. Write to support@chatguard.dev from your account's address; we answer within 30 days. You can also complain to a supervisory authority: in Serbia, the Commissioner for Information of Public Importance and Personal Data Protection; in the EU, the authority where you live or work.

Cookies

Chat Guard sets only the cookies needed to sign you in: cg_refresh keeps you signed in and lapses after 30 days without a visit, and short-lived cookies (15 minutes at most) carry a Google or GitHub sign-in. There are no analytics, advertising or tracking cookies or scripts. The dashboard remembers your theme and a few display choices in your browser's local storage, which never leaves your browser.