Bans and Anti-Gaming
Two layers keep a queue fair: per-room anti-gaming rules that throttle join abuse, and a ban registry that keeps specific members out.
Rejoin cooldown
A cooldown stops leave-and-rejoin cycling for a better position. Set it
at room creation (or later via update); 0 disables it:
snug waiting-room create -r launch-day -c 100 --anti-gaming-rejoin-cooldown 60Verified: join, leave, then an immediate rejoin fails until the cooldown elapses:
{
"status": 429,
"msg": "Please wait 60 seconds before rejoining",
"error": "RATE_LIMITED"
}Join rate limit
Caps join attempts per member within a sliding window:
snug waiting-room create -r launch-day -c 100 \
--anti-gaming-rate-limit-max 2 --anti-gaming-rate-limit-window 60Verified: with a max of 2 per 60 seconds, the third join attempt inside
the window fails with 429 RATE_LIMITED -
Too many join attempts. Try again in 60 seconds. Both knobs take 0
to disable.
The service also watches request patterns - rapid join/leave cycling and suspiciously regular request timing - and can auto-ban members it flags; the thresholds are internal and not per-room configurable.
Rejecting with a ban
reject removes members from the queue; adding -b <seconds> also bans
them from rejoining:
snug waiting-room reject -r launch-day -m user-3 -R "abuse" -b 3600Verified: the rejected member's next join attempt fails with
403 FORBIDDEN - Banned until 2026-08-28T15:16:02+00:00.
The ban registry (admin)
Explicit bans are managed separately from rejection. All ban commands
require a platform admin token, except member-bans, which a member may
also call for themselves.
snug waiting-room ban -r launch-day -m user-4 -R "bot" -d 86400 # omit -d for permanent
snug waiting-room bans -r launch-day --include-expired
snug waiting-room ban-details -r launch-day -m user-4
snug waiting-room unban -r launch-day -m user-4
snug waiting-room member-bans -m user-4 # room IDs this member is banned fromAn explicit ban records the full audit trail; captured live:
{
"room_id": "launch-day",
"member_id": "user-4",
"reason": "bot",
"banned_by": "docs-wave-admin",
"banned_at": "2026-08-28T14:16:12.838659Z",
"banned_until": "2026-08-28T16:16:12.838659Z"
}Two verified gotchas:
- A ban created via
reject -bblocks joins and appears in the room'sbanslist (member ID and expiry only), but it has no registry record:ban-detailson it comes back empty. Usebanwhen you need an auditable reason and actor. - Bans are per-room.
member-bansaggregates the rooms a member is banned from; there is no global ban.
Expired bans stop blocking joins immediately and are swept from the registry in the background (hourly by default; see the CONFIG reference). The exact endpoints are in the Waiting Room API reference.