3.6 Device Management
Section 3 — Player Management
3.6 Device Management
Scope
Covers player-facing device management: listing registered devices, renaming them, marking
them as trusted, blocking them, and removing them. All endpoints require a player JWT
with auth_type=player and scope=player.
For how devices are registered at login time, see DEVICE_REGISTRATION.md (Section 2.2.1).
Overview
Once a device is registered at login, players can manage it through the device management
endpoints at GET/PATCH/DELETE /api/player/devices. Common use cases:
- Reviewing which devices have accessed the account
- Naming devices for easy identification ("My PlayStation", "Living Room PC")
- Trusting known devices so client apps can offer faster flows
- Blocking a device that is suspected compromised or no longer in the player's control
- Removing stale or unrecognised device records
All operations are scoped to the authenticated player. A player cannot view or modify another player's devices.
Authentication
All endpoints require Authorization: Bearer <player_jwt> with a scope=player token.
Game keys and API keys are not accepted.
Endpoints
List Devices
GET /api/player/devices
Authorization: Bearer <player_jwt>Returns all devices registered to the authenticated player. The response includes a
currentDeviceId field identifying which device was used for the current session (if known),
and each device item carries an isCurrentDevice flag.
Response: PlayerDevicesListResponse
totalCount int
currentDeviceId Guid? — device used in this session, if available
devices[]
id Guid
platform string — GamePlatform enum value
platformDisplayName string — human-readable name (e.g. "PlayStation 5")
platformCategory string — category (e.g. "PlayStation", "PC", "Mobile")
deviceName string? — player-assigned display name
hardwareModel string? — e.g. "PlayStation 5 Digital Edition"
osVersion string?
isTrusted bool
isBlocked bool
isCurrentDevice bool
firstSeenAt DateTime
lastSeenAt DateTime
loginCount intGet Device
GET /api/player/devices/{deviceId}
Authorization: Bearer <player_jwt>Returns a single PlayerDeviceResponse (same shape as list item). Returns 404 if the
device does not exist or belongs to a different player.
Update Device
PATCH /api/player/devices/{deviceId}
Authorization: Bearer <player_jwt>
Content-Type: application/jsonUpdates player-controlled fields. All fields are optional.
Request: UpdateDeviceRequest
| Field | Type | Max Length | Notes |
|---|---|---|---|
deviceName | string? | 64 chars | Player-assigned display name |
isTrusted | bool? | — | Mark or unmark the device as trusted |
Response: Updated PlayerDeviceResponse. Returns 404 if the device does not exist or
belongs to a different player.
Remove Device
DELETE /api/player/devices/{deviceId}
Authorization: Bearer <player_jwt>Permanently deletes the device record. The device will re-register automatically if the player logs in again from the same hardware (fingerprint match creates a new record).
Response: 204 No Content. Returns 404 if the device does not exist or belongs to a different player.
Block Device
POST /api/player/devices/{deviceId}/block
Authorization: Bearer <player_jwt>Sets isBlocked = true. A blocked device is rejected at login — any login attempt
originating from this fingerprint will fail regardless of auth provider or credentials.
Blocking does not invalidate any existing active sessions from that device. It only prevents future logins.
Response: 204 No Content. Returns 404 if the device does not exist or belongs to a different player.
Unblock Device
POST /api/player/devices/{deviceId}/unblock
Authorization: Bearer <player_jwt>Sets isBlocked = false. The device can be used to log in again immediately.
Response: 204 No Content. Returns 404 if the device does not exist or belongs to a different player.
Device Summary
GET /api/player/devices/summary
Authorization: Bearer <player_jwt>Lightweight aggregate across all of the player's devices.
Response: DeviceSummaryResponse
totalDevices int
trustedDevices int
devicesByCategory Dictionary<string, int> — count per platform category
lastLoginAt DateTime? — most recent login across all devicesTrust vs Block
isTrusted = true | isBlocked = true | |
|---|---|---|
| Set by | Player (via PATCH) | Player (via POST /block) |
| Effect on login | None — informational only | Rejected at the login check |
| Effect on existing sessions | None | None (existing sessions remain valid) |
| Use case | Signal to client apps (e.g. skip extra verification) | Lock out a suspected compromised device |
| Can coexist | Yes — a device can be both trusted and blocked | Block takes precedence |
Trust is not enforced server-side. It is a flag that client applications and game servers can read to adjust their own behaviour. The platform itself does not grant any elevated permissions based on trust status.
Error Reference
| Code | Meaning |
|---|---|
| 401 | Missing or invalid player JWT |
| 403 | Authenticated token is not a player token with player scope |
| 404 | Device not found or belongs to a different player |
Code References
- Controller:
GamersLabRestAPI/Game/Sessions/Controllers/PlayerDeviceController.cs - Service interface:
GamersLabRestAPI/Game/Sessions/Services/IPlayerDeviceService.cs - Service implementation:
GamersLabRestAPI/Game/Sessions/Services/PlayerDeviceService.cs - Repository:
GamersLabRestAPI/Game/Sessions/Repositories/PlayerDeviceRepository.cs - DTOs:
GamersLabRestAPI/Game/Sessions/DTOs/PlayerDeviceDTOs.csUpdateDeviceRequest,PlayerDeviceResponse,PlayerDevicesListResponse,DeviceSummaryResponse