# Platform Moderation

## Get ban status for a user

> Returns whether the specified user address currently has an active platform-level\
> ban. If banned, the full ban record is included in the response.\
> \
> This endpoint is \*\*public\*\* — no authentication required. It is intended for\
> clients to check their own ban status before attempting to connect.<br>

```json
{"openapi":"3.0.0","info":{"title":"Comms Gatekeeper API","version":"1.0.0"},"servers":[{"url":"https://comms-gatekeeper.decentraland.org","description":"Production server"},{"url":"https://comms-gatekeeper.decentraland.zone","description":"Development server"}],"security":[],"paths":{"/users/{address}/bans":{"get":{"operationId":"getBanStatus","summary":"Get ban status for a user","description":"Returns whether the specified user address currently has an active platform-level\nban. If banned, the full ban record is included in the response.\n\nThis endpoint is **public** — no authentication required. It is intended for\nclients to check their own ban status before attempting to connect.\n","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"description":"Ethereum address to check"}],"responses":{"200":{"description":"Ban status retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"isBanned":{"type":"boolean"},"ban":{"type":"object","properties":{"id":{"type":"string","description":"Unique ban record identifier"},"bannedAddress":{"type":"string","description":"Ethereum address of the banned user"},"bannedBy":{"type":"string","description":"Ethereum address of the moderator who issued the ban"},"reason":{"type":"string","description":"Internal reason for the ban"},"customMessage":{"type":"string","nullable":true,"description":"Optional message shown to the player on rejection"},"bannedAt":{"type":"string","format":"date-time","description":"When the ban was issued"},"expiresAt":{"type":"string","format":"date-time","nullable":true,"description":"When the ban expires. Null for permanent bans."},"liftedAt":{"type":"string","format":"date-time","nullable":true,"description":"When the ban was manually lifted, if applicable"},"liftedBy":{"type":"string","nullable":true,"description":"Ethereum address of the moderator who lifted the ban"},"createdAt":{"type":"string","format":"date-time","description":"Record creation timestamp"}}}}}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}}},"tags":["Platform Moderation"]}}}}
```

## Ban a player (platform-wide)

> Issues a platform-level ban for the specified user address. A platform-banned\
> user will be rejected at token issuance time and cannot enter any Genesis City\
> scene or island room until the ban expires or is lifted.\
> \
> Requires Signed Fetch authentication plus a valid moderator role, verified\
> server-side via \`moderatorAuthMiddleware\`.\
> \
> The ban can be permanent (no \`duration\`) or timed. An optional \`customMessage\`\
> is surfaced to the player at rejection time.<br>

```json
{"openapi":"3.0.0","info":{"title":"Comms Gatekeeper API","version":"1.0.0"},"servers":[{"url":"https://comms-gatekeeper.decentraland.org","description":"Production server"},{"url":"https://comms-gatekeeper.decentraland.zone","description":"Development server"}],"security":[{"SignedFetch":[]}],"components":{"securitySchemes":{"SignedFetch":{"type":"apiKey","in":"header","name":"x-identity","description":"Signed Fetch authentication for scene-based requests.\nRequires a chain of identity headers:\n- x-identity-auth-chain-0: Signer information\n- x-identity-auth-chain-1: Ephemeral key information  \n- x-identity-auth-chain-2: Signed entity information\n- x-identity-timestamp: Request timestamp\n- x-identity-metadata: Request metadata\nUsed for authentication from decentraland-kernel-scene.\n"}}},"paths":{"/users/{address}/bans":{"post":{"operationId":"banPlayer","summary":"Ban a player (platform-wide)","description":"Issues a platform-level ban for the specified user address. A platform-banned\nuser will be rejected at token issuance time and cannot enter any Genesis City\nscene or island room until the ban expires or is lifted.\n\nRequires Signed Fetch authentication plus a valid moderator role, verified\nserver-side via `moderatorAuthMiddleware`.\n\nThe ban can be permanent (no `duration`) or timed. An optional `customMessage`\nis surfaced to the player at rejection time.\n","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"description":"Ethereum address of the user to ban"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","minLength":1,"description":"Reason for the ban (internal, logged)"},"duration":{"type":"number","minimum":0,"exclusiveMinimum":true,"description":"Ban duration in seconds. Must be positive. Omit for a permanent ban."},"customMessage":{"type":"string","description":"Optional message shown to the player on rejection"}}}}}},"responses":{"201":{"description":"Ban created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","description":"Unique ban record identifier"},"bannedAddress":{"type":"string","description":"Ethereum address of the banned user"},"bannedBy":{"type":"string","description":"Ethereum address of the moderator who issued the ban"},"reason":{"type":"string","description":"Internal reason for the ban"},"customMessage":{"type":"string","nullable":true,"description":"Optional message shown to the player on rejection"},"bannedAt":{"type":"string","format":"date-time","description":"When the ban was issued"},"expiresAt":{"type":"string","format":"date-time","nullable":true,"description":"When the ban expires. Null for permanent bans."},"liftedAt":{"type":"string","format":"date-time","nullable":true,"description":"When the ban was manually lifted, if applicable"},"liftedBy":{"type":"string","nullable":true,"description":"Ethereum address of the moderator who lifted the ban"},"createdAt":{"type":"string","format":"date-time","description":"Record creation timestamp"}}}}}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"401":{"description":"Unauthorized — invalid Signed Fetch or missing moderator role","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"403":{"description":"Forbidden — caller does not have the moderator role","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}}},"tags":["Platform Moderation"]}}}}
```

## Lift a platform-wide ban

> Removes the active platform-level ban for the specified user address. The user\
> will be able to obtain LiveKit tokens again on their next connection attempt.\
> \
> Requires Signed Fetch authentication plus a valid moderator role.<br>

```json
{"openapi":"3.0.0","info":{"title":"Comms Gatekeeper API","version":"1.0.0"},"servers":[{"url":"https://comms-gatekeeper.decentraland.org","description":"Production server"},{"url":"https://comms-gatekeeper.decentraland.zone","description":"Development server"}],"security":[{"SignedFetch":[]}],"components":{"securitySchemes":{"SignedFetch":{"type":"apiKey","in":"header","name":"x-identity","description":"Signed Fetch authentication for scene-based requests.\nRequires a chain of identity headers:\n- x-identity-auth-chain-0: Signer information\n- x-identity-auth-chain-1: Ephemeral key information  \n- x-identity-auth-chain-2: Signed entity information\n- x-identity-timestamp: Request timestamp\n- x-identity-metadata: Request metadata\nUsed for authentication from decentraland-kernel-scene.\n"}}},"paths":{"/users/{address}/bans":{"delete":{"operationId":"liftBan","summary":"Lift a platform-wide ban","description":"Removes the active platform-level ban for the specified user address. The user\nwill be able to obtain LiveKit tokens again on their next connection attempt.\n\nRequires Signed Fetch authentication plus a valid moderator role.\n","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"description":"Ethereum address of the user whose ban to lift"}],"responses":{"204":{"description":"Ban lifted successfully"},"401":{"description":"Unauthorized — invalid Signed Fetch or missing moderator role","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"403":{"description":"Forbidden — caller does not have the moderator role","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"404":{"description":"No active ban found for this address","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}}},"tags":["Platform Moderation"]}}}}
```

## Get warnings for a user

> Returns all warnings on record for the specified user address.\
> \
> Requires Signed Fetch authentication plus a valid moderator role.<br>

```json
{"openapi":"3.0.0","info":{"title":"Comms Gatekeeper API","version":"1.0.0"},"servers":[{"url":"https://comms-gatekeeper.decentraland.org","description":"Production server"},{"url":"https://comms-gatekeeper.decentraland.zone","description":"Development server"}],"security":[{"SignedFetch":[]}],"components":{"securitySchemes":{"SignedFetch":{"type":"apiKey","in":"header","name":"x-identity","description":"Signed Fetch authentication for scene-based requests.\nRequires a chain of identity headers:\n- x-identity-auth-chain-0: Signer information\n- x-identity-auth-chain-1: Ephemeral key information  \n- x-identity-auth-chain-2: Signed entity information\n- x-identity-timestamp: Request timestamp\n- x-identity-metadata: Request metadata\nUsed for authentication from decentraland-kernel-scene.\n"}}},"paths":{"/users/{address}/warnings":{"get":{"operationId":"getWarnings","summary":"Get warnings for a user","description":"Returns all warnings on record for the specified user address.\n\nRequires Signed Fetch authentication plus a valid moderator role.\n","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"description":"Ethereum address to look up"}],"responses":{"200":{"description":"Warnings retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Unique warning record identifier"},"warnedAddress":{"type":"string","description":"Ethereum address of the warned user"},"warnedBy":{"type":"string","description":"Ethereum address of the moderator who issued the warning"},"reason":{"type":"string","description":"Reason for the warning"},"warnedAt":{"type":"string","format":"date-time","description":"When the warning was issued"},"createdAt":{"type":"string","format":"date-time","description":"Record creation timestamp"}}}}}}}}},"401":{"description":"Unauthorized — invalid Signed Fetch or missing moderator role","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"403":{"description":"Forbidden — caller does not have the moderator role","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}}},"tags":["Platform Moderation"]}}}}
```

## Issue a warning to a player

> Records a formal warning for the specified user. Warnings are part of a\
> graduated moderation system and can inform future ban decisions.\
> \
> Requires Signed Fetch authentication plus a valid moderator role.<br>

```json
{"openapi":"3.0.0","info":{"title":"Comms Gatekeeper API","version":"1.0.0"},"servers":[{"url":"https://comms-gatekeeper.decentraland.org","description":"Production server"},{"url":"https://comms-gatekeeper.decentraland.zone","description":"Development server"}],"security":[{"SignedFetch":[]}],"components":{"securitySchemes":{"SignedFetch":{"type":"apiKey","in":"header","name":"x-identity","description":"Signed Fetch authentication for scene-based requests.\nRequires a chain of identity headers:\n- x-identity-auth-chain-0: Signer information\n- x-identity-auth-chain-1: Ephemeral key information  \n- x-identity-auth-chain-2: Signed entity information\n- x-identity-timestamp: Request timestamp\n- x-identity-metadata: Request metadata\nUsed for authentication from decentraland-kernel-scene.\n"}}},"paths":{"/users/{address}/warnings":{"post":{"operationId":"warnPlayer","summary":"Issue a warning to a player","description":"Records a formal warning for the specified user. Warnings are part of a\ngraduated moderation system and can inform future ban decisions.\n\nRequires Signed Fetch authentication plus a valid moderator role.\n","parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"description":"Ethereum address of the user to warn"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","minLength":1,"description":"Reason for the warning"}}}}}},"responses":{"201":{"description":"Warning issued successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","description":"Unique warning record identifier"},"warnedAddress":{"type":"string","description":"Ethereum address of the warned user"},"warnedBy":{"type":"string","description":"Ethereum address of the moderator who issued the warning"},"reason":{"type":"string","description":"Reason for the warning"},"warnedAt":{"type":"string","format":"date-time","description":"When the warning was issued"},"createdAt":{"type":"string","format":"date-time","description":"Record creation timestamp"}}}}}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"401":{"description":"Unauthorized — invalid Signed Fetch or missing moderator role","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"403":{"description":"Forbidden — caller does not have the moderator role","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}}},"tags":["Platform Moderation"]}}}}
```

## List all active platform bans

> Returns a list of all currently active platform-level bans.\
> \
> Requires Signed Fetch authentication plus a valid moderator role. Not paginated —\
> intended for moderator tooling that needs a full snapshot.<br>

```json
{"openapi":"3.0.0","info":{"title":"Comms Gatekeeper API","version":"1.0.0"},"servers":[{"url":"https://comms-gatekeeper.decentraland.org","description":"Production server"},{"url":"https://comms-gatekeeper.decentraland.zone","description":"Development server"}],"security":[{"SignedFetch":[]}],"components":{"securitySchemes":{"SignedFetch":{"type":"apiKey","in":"header","name":"x-identity","description":"Signed Fetch authentication for scene-based requests.\nRequires a chain of identity headers:\n- x-identity-auth-chain-0: Signer information\n- x-identity-auth-chain-1: Ephemeral key information  \n- x-identity-auth-chain-2: Signed entity information\n- x-identity-timestamp: Request timestamp\n- x-identity-metadata: Request metadata\nUsed for authentication from decentraland-kernel-scene.\n"}}},"paths":{"/bans":{"get":{"operationId":"listBans","summary":"List all active platform bans","description":"Returns a list of all currently active platform-level bans.\n\nRequires Signed Fetch authentication plus a valid moderator role. Not paginated —\nintended for moderator tooling that needs a full snapshot.\n","responses":{"200":{"description":"Bans retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Unique ban record identifier"},"bannedAddress":{"type":"string","description":"Ethereum address of the banned user"},"bannedBy":{"type":"string","description":"Ethereum address of the moderator who issued the ban"},"reason":{"type":"string","description":"Internal reason for the ban"},"customMessage":{"type":"string","nullable":true,"description":"Optional message shown to the player on rejection"},"bannedAt":{"type":"string","format":"date-time","description":"When the ban was issued"},"expiresAt":{"type":"string","format":"date-time","nullable":true,"description":"When the ban expires. Null for permanent bans."},"liftedAt":{"type":"string","format":"date-time","nullable":true,"description":"When the ban was manually lifted, if applicable"},"liftedBy":{"type":"string","nullable":true,"description":"Ethereum address of the moderator who lifted the ban"},"createdAt":{"type":"string","format":"date-time","description":"Record creation timestamp"}}}}}}}}},"401":{"description":"Unauthorized — invalid Signed Fetch or missing moderator role","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"403":{"description":"Forbidden — caller does not have the moderator role","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}}},"tags":["Platform Moderation"]}}}}
```

## Check if a user is banned from a world parcel

> Service-to-service endpoint used by Worlds Content Server to verify whether\
> a user is banned from a specific world parcel before issuing a LiveKit token.\
> \
> Requires Bearer token authentication (\`COMMS\_GATEKEEPER\_AUTH\_TOKEN\`). Not\
> intended for direct client use.<br>

```json
{"openapi":"3.0.0","info":{"title":"Comms Gatekeeper API","version":"1.0.0"},"servers":[{"url":"https://comms-gatekeeper.decentraland.org","description":"Production server"},{"url":"https://comms-gatekeeper.decentraland.zone","description":"Development server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"Bearer token authentication for service-to-service communication.\n"}}},"paths":{"/worlds/{worldName}/parcels/{baseParcel}/users/{address}/ban-status":{"get":{"operationId":"getWorldBanStatus","summary":"Check if a user is banned from a world parcel","description":"Service-to-service endpoint used by Worlds Content Server to verify whether\na user is banned from a specific world parcel before issuing a LiveKit token.\n\nRequires Bearer token authentication (`COMMS_GATEKEEPER_AUTH_TOKEN`). Not\nintended for direct client use.\n","parameters":[{"name":"worldName","in":"path","required":true,"schema":{"type":"string"},"description":"World identifier"},{"name":"baseParcel","in":"path","required":true,"schema":{"type":"string"},"description":"Base parcel position (e.g. \"0,0\")"},{"name":"address","in":"path","required":true,"schema":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"},"description":"Ethereum address of the user to check"}],"responses":{"200":{"description":"Ban status retrieved","content":{"application/json":{"schema":{"type":"object","required":["isBanned"],"properties":{"isBanned":{"type":"boolean","description":"true if the user is banned from this world parcel"}}}}}},"401":{"description":"Unauthorized — invalid or missing Bearer token","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message describing what went wrong"}}}}}}},"tags":["Platform Moderation"]}}}}
```
