Players
Rosters, live presence, full profiles, inventory, and moderation for the players on your server.
Everything about the players on your server — the roster, who is online right now, a full profile (stats, skills, bases, vehicles, survival), inventory, and moderation state. A separate scope unlocks moderation history and IP data.
Identifying a player
Every per-player endpoint takes a {ref} path segment that accepts either identifier:
- a Steam64 id —
76561198000000000 - a Discord id, prefixed —
discord:123456789012345678
GET /v1/players/76561198000000000
GET /v1/players/discord:123456789012345678Steam64 is the canonical, immutable key. A Discord id is itself stable, but its link to
a player is mutable, so a discord: ref resolves to the currently-linked player at request
time (404 not_found if none is linked). You can also look a player up on the list endpoint
with ?steam_id= or ?discord_id=.
Authorization
| Scope | Grants |
|---|---|
players:read | The list, live presence, profile, inventory, and moderation state. |
players:read_sensitive | Moderation history and IP data (/violations, /ips). |
Both steam_id and discord_id are returned in the roster and profile
responses under the base players:read scope; the live snapshot (/players/online)
carries only steam_id. A key missing the required scope gets 403 insufficient_scope.
GET /v1/players
The player roster, paginated. Optional filters:
| Query | Meaning |
|---|---|
steam_id | Exact match on Steam64. |
discord_id | Exact match on the linked Discord id. |
online | true / false — only online / offline players. |
search | Free-text name search. Cannot be combined with a structured filter above (400 validation_error). |
limit | Page size, 10–100 (default 50). |
cursor | Opaque cursor from a previous response's next_cursor. |
Returns a collection envelope:
{
"data": [
{
"steam_id": "76561198000000000",
"discord_id": "123456789012345678",
"user_profile_id": 7,
"steam_name": "Bob",
"char_name": "Bobby",
"online": true,
"squad": { "id": 4, "name": "Alpha", "rank": 1 },
"money": 500, "gold": 3, "coins": 9, "fame_points": 12.5,
"attributes": { "strength": 2.35, "constitution": 3.1, "dexterity": 4, "intelligence": 5.25 },
"play_time": 3600, "is_admin": false,
"last_seen": "2024-01-01 12:00:00", "created_at": "2023-01-01 10:00:00"
}
],
"total": 1,
"has_more": false,
"next_cursor": null
}total is the count of players matching the query (across all pages).
GET /v1/players/online
A live snapshot of everyone online right now — positions, ping, stance, and live currency.
Filter to one player with ?steam_id= or ?discord_id=. Not paginated (the online set is
bounded); served with a short max-age so a poller does not hammer the game server.
{
"online": 1,
"data": [
{
"steam_id": "76561198000000000", "name": "Bob", "ping": 30,
"position": { "x": 1, "y": 2, "z": 3 },
"alive": true, "conscious": true, "immortal": false, "super_jump": false,
"is_admin": false, "money": 0, "gold": 0, "fame_points": 0,
"stance": "stand", "item_in_hands": null
}
]
}GET /v1/players/{ref}
The full profile: everything on the roster row plus warden_stats (kills, deaths,
streaks, totals, login streak, timestamps), skills, bases, vehicles, and
a typed survival block. money is the player's bank balance.
Field notes
Attributes, fame_points, and skill level are fractional numbers. total_kills,
total_deaths, and login_streak are null on servers running an older mod build that
does not yet report them. The profile includes discord_id; it excludes IP history —
that lives behind the sensitive scope at /ips — and any other Discord-account detail.
GET /v1/players/{ref}/inventory
The player's full, nested inventory — each item may carry contents (recursively) for
containers. A subtree the mod stopped expanding at its depth cap is flagged
contents_truncated: true.
{ "items": [ { "id": 1, "class": "Weapon", "name": "Rifle", "icon": "…", "health": 100, "max_health": 100, "weight": 3.5, "is_container": false, "is_weapon": true, "contents_truncated": false, "contents": [] } ] }GET /v1/players/{ref}/moderation
Current ban and mute state. The player (subject) and banned_by (moderator) are
identity objects that carry both steam_id and discord_id — discord_id is null when
that person is not Discord-linked. banned_by is null when the player is not banned; a
legacy/system entry with no moderator Steam id surfaces its label as name (with
steam_id: null).
{
"player": { "steam_id": "76561198000000000", "discord_id": "123456789012345678" },
"ban": { "banned": true, "reason": "cheating", "permanent": false, "expires_at": "2023-11-14T22:13:20.000Z", "banned_at": "2023-11-03T…", "banned_by": { "steam_id": "76561198000000001", "discord_id": "223…", "name": null } },
"mute": { "muted": false, "permanent": false, "muted_at": null, "duration_minutes": null, "channels": [] }
}To change ban/mute state, see Moderation
(players:ban / players:mute).
GET /v1/players/{ref}/violations
Requires players:read_sensitive. The paginated moderation history (bans, mutes, and
trap events), newest first, with the issuing moderator. Paginate with limit (1–100) and
the cursor. Never cached (Cache-Control: private, no-store). issued_by is an identity
object carrying the moderator's steam_id, discord_id (null when unlinked), and name.
{
"data": [ { "id": 11, "type": "ban", "action": "applied", "source": "mod", "reason": "…", "issued_by": { "steam_id": "76561198000000001", "discord_id": "223…", "name": "Admin" }, "applied_at": "2023-11-03T…", "expires_at": "2023-11-14T…", "duration_sec": 3600, "metadata": { "channel": "Global" } } ],
"has_more": false,
"next_cursor": null
}GET /v1/players/{ref}/ips
Requires players:read_sensitive. The player's IP history, newest first; current_ip
is the most recent. Never cached.
{ "current_ip": "…", "history": [ { "ip": "…", "first_seen": "2023-11-03T…", "last_seen": "2023-11-14T…" } ] }Caching
The list, live snapshot, profile, inventory, and moderation reads send an ETag and a
short Cache-Control: private, max-age; send the ETag back as If-None-Match to get a
304 Not Modified (the live snapshot's ETag matches when nothing has moved within its
window). The sensitive reads (/violations, /ips) are no-store.
Errors
Standard error envelope. The ones you're most likely to hit:
| Code | Status | When |
|---|---|---|
insufficient_scope | 403 | The key lacks players:read (or players:read_sensitive for /violations, /ips). |
not_found | 404 | No player matches the {ref} (unlinked Discord id, or unknown profile). |
validation_error | 400 | ?search= combined with a structured filter, or a bad query value. |
server_unavailable | 503 | The game server is offline or unreachable. |
gateway_timeout | 504 | The server did not respond in time. |