Bases
Base flags on your server and their owners.
Every base flag on your server and who owns it — the paginated list, and a single base by its flag id.
Identifying a base
The detail endpoint takes a numeric {id} path segment — the base's flag id. It must be a
positive integer with no leading zeros (pattern ^[1-9]\d*$); values such as 0 and 007
are rejected with 400 validation_error.
GET /v1/bases
GET /v1/bases/5Authorization
| Scope | Grants |
|---|---|
bases:read | Both base endpoints — list and detail. |
Each base owner carries a discord_id (null when that owner isn't linked to Discord). A key
missing the scope gets 403 insufficient_scope.
GET /v1/bases
The base list, paginated. Optional filters:
| Query | Meaning |
|---|---|
owner_steam_id | Bases owned by this Steam64 (digits only). |
owner_discord_id | Bases owned by the player linked to this Discord id (digits only). Resolves at request time; an unlinked id matches nothing (empty page, never a 404). |
owner_name | Exact owner character-name match (the mod filter grammar has no substring/contains operator). |
min_elements / max_elements | Bound the placed-element count. |
min_health / max_health | Bound the average element health, on a 0.0–1.0 scale (e.g. 0.5 = 50 %). |
search | Free-text search. Cannot be combined with any structured filter above (400 validation_error). |
limit | Page size, 10–100 (default 50). |
cursor | Opaque cursor from a previous response's next_cursor. |
Supplying both owner_steam_id and owner_discord_id is a 400 validation_error.
Returns a collection envelope. total is the count of bases matching the query (across all pages):
{
"data": [
{
"flag_id": 5, "base_id": 2,
"owner": { "profile_id": 7, "name": "Bob", "steam_id": "76561198000000000", "discord_id": "123456789012345678" },
"max_elements": 100, "element_count": 40, "avg_health": 0.875,
"position": { "x": 1.5, "y": 2.5, "z": 3.5 }
}
],
"has_more": false,
"next_cursor": null,
"total": 1
}Field notes
owner is the nested identity object { profile_id, name, steam_id, discord_id }; discord_id
is null when that owner isn't linked. avg_health and every position axis are fractional
numbers — avg_health is 0.0–1.0 in the body (the min_health/max_health filters take
the same 0.0–1.0 scale).
GET /v1/bases/{id}
A single base by its flag id. Returns the same object as one list row. 404 not_found when no
base carries that flag id.
Caching
Every base read sends an ETag and Cache-Control: private with a short max-age (15 s); send
the ETag back as If-None-Match to get a 304 Not Modified.
Errors
Standard error envelope. The ones you're most likely to hit:
| Code | Status | When |
|---|---|---|
insufficient_scope | 403 | The key lacks bases:read. |
not_found | 404 | No base matches the {id}. |
validation_error | 400 | An {id} that isn't a positive integer without leading zeros (^[1-9]\d*$), ?search= combined with a structured filter, both owner ids together, or a non-digit owner_steam_id/owner_discord_id. |
server_unavailable | 503 | The game server is offline or unreachable. |
gateway_timeout | 504 | The server did not respond in time. |