Bans are the core enforcement mechanism in Sentinel Network. They record violations against devices and feed into the reputation scoring system.
Ban Types
Every ban has a ban_type that categorizes the violation:
| Type | Description | Examples |
|---|
cheat | Gameplay manipulation or unfair advantage | Aimbot, wallhack, speed hack, item duplication |
social | Community guideline violations | Harassment, hate speech, toxicity, griefing |
Cheat and social bans are tracked independently — a device can have a clean cheat record but a poor social reputation, or vice versa.
Ban Scopes
Each ban has a scope that determines its reach:
| Scope | Reach | Required Scopes |
|---|
game | Single game only | bans:write |
publisher | All games by the issuing publisher | bans:write |
global | All games across the entire network | bans:write + bans:global |
Global bans require the bans:global scope in addition to bans:write. This is a safety measure to prevent accidental network-wide bans.
Scope Visibility
Publishers control which scopes they enforce via their policy configuration. A publisher can opt out of enforcing global bans while still contributing to the global reputation pool.
Creating a Ban
curl -s -X POST https://api.sentineltrustplay.io/v1/bans \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-H "X-Game-Id: $GAME" \
-d '{
"device_id": "dvc_abc123",
"ban_type": "cheat",
"scope": "game",
"reason_code": "aimbot",
"expires_at": "2025-12-31T23:59:59Z",
"details": {"match_id": "m_123", "confidence": 0.95},
"idempotency_key": "case-4521"
}'
| Field | Required | Description |
|---|
device_id | Yes | Target device |
ban_type | Yes | cheat or social |
scope | Yes | game, publisher, or global |
reason_code | Yes | Application-defined reason (e.g., aimbot, harassment) |
expires_at | No | ISO 8601 expiry timestamp. null = permanent. |
details | No | Arbitrary JSON metadata stored with the ban |
idempotency_key | No | Prevents duplicate bans (see below) |
Ban Lifecycle
Created ──→ Active ──→ Expired (automatic, if expires_at is set)
└──→ Revoked (manual, via /v1/bans/{id}/revoke)
- Active: The ban is currently enforced.
revoked_at is null and either expires_at is null or in the future.
- Expired: The current time has passed
expires_at. The ban becomes inactive automatically.
- Revoked: A publisher has explicitly revoked the ban.
revoked_at is set.
Inactive bans (expired or revoked) remain in the database for audit purposes and still appear when listing bans with status=inactive or status=all.
Idempotency
The idempotency_key field prevents duplicate bans from the same publisher and game combination. If a ban with the same key already exists:
- The existing ban is returned
- The response
status is "idempotent_ok" instead of "created"
- No new ban is inserted
This is useful when retrying requests after network failures.
Listing Bans
Bans are listed per device and per type using keyset pagination:
curl -s "https://api.sentineltrustplay.io/v1/device/dvc_abc123/bans/cheat?status=active&limit=50" \
-H "Authorization: Bearer $API_KEY" \
-H "X-Game-Id: $GAME"
The API uses keyset pagination based on ban_id:
- Results are ordered by
ban_id descending (newest first)
- Use the
cursor query parameter with the last ban_id from the previous page
- The response includes total
counts across all pages
# First page
GET /v1/device/dvc_abc123/bans/cheat?limit=10
# Next page (using last ban_id from previous response)
GET /v1/device/dvc_abc123/bans/cheat?limit=10&cursor=42
Status Filter
| Value | Returns |
|---|
active (default) | Only active bans |
inactive | Only expired or revoked bans |
all | All bans regardless of status |
Revoking a Ban
curl -s -X POST https://api.sentineltrustplay.io/v1/bans/1/revoke \
-H "Authorization: Bearer $API_KEY" \
-H "X-Game-Id: $GAME"
Revoking a ban marks it as inactive immediately and triggers a reputation score recalculation. See Reputation Updates for notes on propagation timing.