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:
TypeDescriptionExamples
cheatGameplay manipulation or unfair advantageAimbot, wallhack, speed hack, item duplication
socialCommunity guideline violationsHarassment, 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:
ScopeReachRequired Scopes
gameSingle game onlybans:write
publisherAll games by the issuing publisherbans:write
globalAll games across the entire networkbans: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"
  }'
FieldRequiredDescription
device_idYesTarget device
ban_typeYescheat or social
scopeYesgame, publisher, or global
reason_codeYesApplication-defined reason (e.g., aimbot, harassment)
expires_atNoISO 8601 expiry timestamp. null = permanent.
detailsNoArbitrary JSON metadata stored with the ban
idempotency_keyNoPrevents 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"

Pagination

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

ValueReturns
active (default)Only active bans
inactiveOnly expired or revoked bans
allAll 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.