# Risk and chat > Fraud signals over your own data, and the moderated room your players talk in. Source: https://casinoapipro.com/docs/risk-and-chat Two things that sit between your players and your balance: signals about unusual activity, and the room they talk in. ## Risk signals are rules, not a model > **This is deterministic scoring over your own data. It is not machine learning.** > > We say so here because you may have to explain it to a regulator, and because a queue you cannot reproduce is one you cannot defend. Every signal is a threshold over numbers you can query yourself. If you want the underlying rounds, they are all in [reporting](/docs/reports). | Name | Type | Meaning | | --- | --- | --- | | `VELOCITY` | signal | Rounds arriving faster than a person can plausibly play them. | | `STAKE_ESCALATION` | signal | A stake far outside this player's own median — not a fixed amount, because 500 is unremarkable for one player and a takeover for another. | | `WIN_RATE_ANOMALY` | signal | Realised return well above the game's, over enough rounds to be worth a look. | | `LARGE_PAYOUT` | signal | One payout big enough to warrant a human glance. | | `BONUS_ABUSE` | signal | Free bets or rain claimed at a rate that suggests farming. | | `MULTI_ACCOUNT` | signal | Several accounts from one address. Shared connections are ordinary, so this is low by default. | | `WALLET_FAILURES` | signal | A burst of wallet failures: your integration faulting, or somebody probing it. | ## What it will and will not do - It never moves money and never blocks a player. A false positive that freezes a real balance costs more than most of the fraud it would catch. Acting is your decision. - It never delays a bet. Scoring runs after settlement and its failures are logged and dropped — a slow risk query must not look like a declined stake. - Events deduplicate and only escalate. A bot at ten rounds a second is one row holding the worst observation, not a firehose. > **A win-rate anomaly is not evidence of anything** > > Variance over a few hundred rounds is enormous. It is a prompt to look at the rounds — each of which is individually replayable from its seed — and that replay, not the signal, is where a dispute is actually settled. Dismissals are recorded in your audit log with who and when. "Who decided this was fine" is the question an investigation opens with. Available on Growth and above. ## In-game chat A shared room per game, rendered inside the game frame. Everything below is driven from your own servers — you do not need the console for any of it. ### Turning it off `PATCH /v1/catalogue/{gameId}` — auth: operator-api Send `{ "chat_enabled": false }`. Off is a legitimate setting: an operator who cannot supervise a room should not have one, and some markets will not permit player-to-player messaging at all. It is per game rather than account-wide, so a crash table can have a room while everything else does not. > **It takes effect on the next connection** > > A player already sitting at the table keeps their room until they reconnect. If you need somebody silenced right now, that is a mute, which is checked on every message. ## What the filter removes, before anyone sees it Links, email addresses, phone numbers and messenger handles are stripped from every message as it arrives. A player being talked into moving off-platform is a player being set up to be defrauded, and that conversation is the one thing a casino chat room reliably attracts. > **Ordering matters, and it bit us** > > The link rule originally ran before the email rule, so `joe@evil.com` had its domain stripped and leaked the rest. Email is matched first now. Mentioned because it is the kind of bug that looks like it works right up until it does not. ### Your own word list `GET /v1/chat/blocklist` — auth: operator-api `PUT /v1/chat/blocklist` — auth: operator-api The filter above stops at the mechanical on purpose. Past that point what counts as unacceptable is a decision about your market and your brand — one operator needs a competitor's name gone, another needs religious terms left alone — and it is not a rule we can make on your behalf. So the list is yours: up to 200 words, each up to 40 characters. | Name | Type | Meaning | | --- | --- | --- | | `Whole words only` | rule | Case-insensitive and boundary-matched, so `rival` does not touch `arrival`. Phrases work. | | `Masked, not withheld` | rule | The word becomes `···` and the sentence survives — proportionate for a list whose reasoning is yours rather than ours. | | `Evasion is withheld` | rule | A message spelling one of your words as `r1valbet` does not land at all. Writing it that way proves the sender knew. | | `PUT replaces` | rule | Send the whole list every time. One word replaces the list with that word. | > **We audit the count, never the words** > > A blocklist names what you consider unacceptable, which can be a sensitive fact about the market you are in. The audit trail records that it changed and by how much. Keep the list short. A withheld message tells the sender only that it did not send — it cannot name your word without handing your list to anyone willing to probe for it. So every word you add is one an honest player can trip with nothing to learn from, and they will simply believe the room ate their message. The rules above earn that silence by being published; a private list cannot, and pays for each entry in players who do not know what they did. Which makes the useful question not "what would we rather not read" but "what is worth a player being confused by". The mechanical abuse is already gone before you start. What is left is usually smaller than it first appears — and sometimes it is not a word problem at all: a complaint that keeps recurring in the room is a complaint about something, and filtering it is the one response guaranteed not to fix it. ### How long chat is kept `GET /v1/chat/retention` — auth: operator-api `PUT /v1/chat/retention` — auth: operator-api `POST /v1/chat/clear` — auth: operator-api Chat is what your players typed, and you decide how long it is kept: 24, 48 or 72 hours, 7, 14, 30 or 90 days. If you never choose, it is `720` hours (30 days). Messages are removed within the hour after they pass the window, and choosing a shorter window applies immediately rather than at the next pass. | Name | Type | Meaning | | --- | --- | --- | | `hours` | integer | null | One of `24`, `48`, `72`, `168`, `336`, `720`, `2160`, or `null` for the platform default. Anything else is refused. | | `messages_held` | integer | How many messages you hold right now, so the setting can be read against what it is governing. | | `held_for_open_reports` | integer | Messages kept past the window because a player reported them and nobody has reviewed the report yet. | `POST /v1/chat/clear` removes messages now — all of them, or only those older than `older_than_hours`, optionally in one `game_id`. Players in the room see the cleared lines disappear rather than keeping them until they reload. > **A reported message outlives the timer** > > Neither the window nor a clear removes a message with an open report. Deleting it would destroy the evidence for exactly the decision the report is waiting on — and a clear must not be a way to make a complaint disappear before it is read. Once the report is reviewed, the message ages out like any other. ### What the sender is told A message the filter withholds sends a `chat_rejected` frame back to that player and nobody else, carrying their own text so your client can put it back in the box rather than making them retype it. | Name | Type | Meaning | | --- | --- | --- | | `contact_details` | reason | A link, address, phone number or messenger handle was all the message contained. These rules are published, so naming them helps an honest player rephrase. | | `not_delivered` | reason | Everything else. A slur and a word on _your_ list are deliberately indistinguishable — a rejection that said which would let a player recover your blocklist one message at a time. | > **A mute stays silent, and that is different** > > A mute is a decision a person made; telling somebody they are muted turns it into an argument with your staff. A withheld message is a rule firing, and if the rule misfires the sender needs to know — otherwise the message vanishes from their side, they assume it sent, and there is nothing for anyone to report. An operator asked us which of those this was. It was the wrong one until 18 September 2026. ## Moderation `GET /v1/dashboard/chat/messages` — auth: dashboard Everything said in your rooms, filterable to just what the filter acted on with `?flagged=true`. Messages listed here have already been shown in their filtered form — removing one takes it out of the record, muting stops the next one. `POST /v1/chat/messages/{messageId}/remove` — auth: operator-api `messageId` is the `id` the room delivered with the message, so a client can offer a remove button without a lookup. Removal is recorded rather than destructive: the message stays in your review history marked removed. `POST /v1/chat/mutes` — auth: operator-api A mute stops somebody talking; it does not stop them playing. Empty duration mutes indefinitely, `0` unmutes. `player_id` takes your own id for the player. Both are audited with the actor and reason. ## What your players reported `POST /v1/game/chat/report` — auth: game-launcher `GET /v1/chat/reports` — auth: operator-api `PATCH /v1/chat/reports/{reportId}` — auth: operator-api The filter removes what is mechanical. Everything past that is a judgement call, a judgement call needs a person, and a person needs to be told — so a player reports a message from inside the game and it lands in your queue, open first and oldest complaint first. Each report carries the message, what the filter had already done to it, `message.id` for removal and `message.author_id` for a mute, so you can act on one without another request. Marking a report reviewed records that somebody looked; it does not remove anything or mute anybody, because those stay deliberate acts with their own audit entries. > **A report is not a vote** > > One per player per message, and the player is told only that it was received — never how many others reported it or what you decided. A room moderated by whoever is most organised is not a moderated room.