Skip to content

Alderon Server REST API ​

HTTP/JSON administration API for a Path of Titans dedicated server — a resource-oriented alternative to Source RCON. Enable it with -EnableServerApi and set [AlderonServerAPI] Port + ApiKey in Game.ini.

Base URL: http://<host>:<port>/v1/api — 77 endpoints, OpenAPI 3.2.0 served at GET /openapi.json.

Conventions ​

Auth ​

Every request needs Authorization: Bearer <ApiKey>. The API is fail-closed: a missing/wrong key returns 401. Each endpoint requires one permission (listed per-endpoint below, via GET /permissions, and as x-permission in OpenAPI). The default ApiKey has full access; ReadOnlyApiKeys hold only read. Define finer keys in [AlderonServerAPI] by assigning a role or an explicit permission list:

+ApiRole=(Name="Moderator", Permissions="read,players,bans,whitelist,chat,reports")
+ApiKeyDef=(Key="d41d8cd98f00b204e9800998ecf8427ee2c1f0a9b7d3c6584f21ba90de7c3315", Role="Moderator")
+ApiKeyDef=(Key="9b1c7e42a5f80d36c4e19af27b0d58e63a7c21fd48b6e095c3d7a1f2b8604e75", Permissions="read,rcon")
Keys must be at least MinApiKeyLength characters (default 64) or the server refuses them at startup and logs which were too short — the key is the only thing protecting full server administration and it is reachable over the network. Generate them: openssl rand -hex 32. Permission tokens: read, players, bans, whitelist, admins, chat, world, settings, config, maintenance, reports, rcon, database (* = full). A key missing an endpoint's permission gets 403. Note reads are not all read: /config, /webhooks, /database and /backups need their own token even for a GET.

Transport ​

Plain HTTP. Intended for localhost / a private network, or behind a TLS-terminating reverse proxy. Do not expose it directly to the internet.

Response envelope ​

Responses are JSON objects with a success boolean. Reads put their payload under a named key (e.g. players); actions return a human string under response. Errors use the matching HTTP status and a body of {success:false, error, code}, where code is a stable machine-readable slug (bad_request, unauthorized, forbidden, not_found, rate_limited, server_error).

Rate limits & safety ​

Requests are rate-limited (a 429 includes a Retry-After header), the client IP can be allowlisted, and admin actions require an admin-scoped key.

Content-Length ​

Requests with a body must send Content-Type: application/json and an explicit Content-Length — the server rejects chunked transfer encoding (411). Bodyless POST/PUT/DELETE should send Content-Length: 0.

Encoding ​

Query values are x-www-form-urlencoded — both %20 and + decode to a space, so reason=a+b and reason=a%20b are equivalent.

Player IDs (agid) ​

Path params named {agid} accept either the dashed Alderon display id (525-053-709) or the raw 9-digit id (525053709) — targeted actions and GET /players/{agid} both normalize the input.

Discovery ​

GET / ​

readonly — Endpoint index

Response — endpoints[] (method, path, scope, summary) + openapi link.

GET /openapi.json ​

readonly — OpenAPI 3.2 description of this API

Response — A tool-consumable OpenAPI 3.2.0 document — path params, request bodies, typed error responses (shared Error schema), tags, operationIds, and bearer security. Point Swagger UI / Postman / a code generator at it.

3.2 specifically, not 3.0/3.1: it is the first version with query as a first-class operation key, so it is the only one that can describe QUERY /events at all. Earlier versions have a closed set of operation keys and would silently omit that endpoint. Tooling that only understands 3.0/3.1 may reject the document or skip the query operation.

GET /healthz ​

readonly — Lightweight liveness probe (for monitoring)

Response — status: "ok" + uptimeSeconds. Cheap — no game-thread work.

GET /readyz ​

readonly — Readiness probe: is the server joinable yet?

Response — ready: true with 200 once the world is loaded, has begun play, is not tearing down, and the game mode + session are up. Otherwise 503 with reasons[] naming what is missing. Distinct from /healthz, which only says the process is alive: use this one for orchestration and load-balancer membership, since it answers with the status code rather than in the body.

GET /permissions ​

readonly — List the API permission catalog

Response — permissions[] — the tokens you can assign to keys/roles: read, players, bans, whitelist, admins, chat, world, settings, config, maintenance, reports, rcon.

GET /capabilities ​

readonly — Feature tokens this server supports

Response — apiVersion + features[] — named tokens for optional behaviour, so a client can tell what this server supports instead of guessing from a version number. Purely additive: tokens are never renamed or removed, and an absent token means not supported. A server too old to have this endpoint returns 404, which clients should read as “baseline server”, not as an error.

Example response

json
{
  "success": true,
  "apiVersion": 1,
  "count": 15,
  "features": [
    "waters",
    "players.groupId",
    "backups.list",
    "list.pagination"
  ]
}

GET /commands ​

readonly — List of RCON/console commands (DumpCommands)

Response — commands[] — the console commands available via POST /rcon.

Server ​

GET /info ​

readonly — Server identity + population summary

Response — serverName, motd, discord, playersOnline, maxPlayers, mapName, gameVersion (e.g. 1337h1), buildRevision, engineVersion, uptimeSeconds.

Example response

json
{
  "success": true,
  "serverName": "My Server",
  "playersOnline": 12,
  "maxPlayers": 100,
  "mapName": "Panjura",
  "gameVersion": "1337h1",
  "uptimeSeconds": 84213
}

GET /metrics ​

readonly — Performance metrics

Response — fps, frameTimeMs, playersOnline, uptimeSeconds.

GET /log ​

readonly — Recent server log lines (tail)

Query parameters

NameDescription
countint, optional (default 200) — number of trailing lines

Response — lines[] (strings, oldest first).

POST /save ​

admin — Force a world/database save

Response — response string.

POST /restart ​

admin — Schedule a restart

Request body

NameDescription
secondsint, optional — delay before restart
messagestring, optional — broadcast shown to players

Example request body

json
{ "seconds": 300, "message": "Restarting for an update in 5 min" }

POST /cancelrestart ​

admin — Cancel a scheduled restart

GET /restart/schedule ​

readonly — Recurring auto-restart schedule

Response — bServerAutoRestart, restartLengthInSeconds, times[] etc.

PUT /restart/schedule ​

admin — Update the recurring auto-restart schedule

Request body

NameDescription
(schedule object)same shape returned by GET /restart/schedule

POST /rcon ​

admin — Run any RCON/console command

Note: Requires bAllowGenericCommand=true on the server.

Request body

NameDescription
commandstring, required — the console command line

Example request body

json
{ "command": "Announce Server maintenance in 10 minutes" }

Players ​

GET /players ​

readonly — Connected players

Response — players[] — each: name, alderonId, ping, role, roleHierarchy, platform, species, gender, growth, growthStage, marks, location{x,y,z}, spectator, characterSelect, inHomeCave, groupId, groupLeader, discordId. groupId/groupLeader appear only when the player is in a party, and discordId only when they have a Discord account linked.

Example response

json
{
  "success": true,
  "players": [
    {
      "name": "RexHunter",
      "alderonId": "525053709",
      "ping": 42,
      "species": "Tyrannosaurus",
      "growth": 1.0,
      "spectator": false,
      "characterSelect": false
    }
  ]
}

GET /players/ ​

readonly — A single connected player, or 404

Path parameters

NameDescription
agiddashed (525-053-709) or raw (525053709) id

Response — A single player object (as in /players).

DELETE /players/ ​

admin — Kick a player

Path parameters

NameDescription
agiddashed display id, e.g. 525-053-709

Query parameters

NameDescription
reasonstring, optional — shown to the kicked player

POST /players/{agid}/heal ​

admin — Heal a player

Path parameters

NameDescription
agiddashed display id

POST /players/{agid}/cleareffects ​

admin — Clear a player's buffs/debuffs (leaves state effects alone)

Path parameters

NameDescription
agiddashed display id

POST /players/{agid}/damage ​

admin — Deal damage to a player. No instigator is recorded, so a lethal hit is not credited to anyone as a kill

Path parameters

NameDescription
agiddashed display id

Request body

NameDescription
amountnumber — damage to apply, must be > 0

POST /players/{agid}/growth ​

admin — Reward growth to a player

Path parameters

NameDescription
agiddashed display id

Request body

NameDescription
amountnumber — growth to add (0..1 scale)

POST /players/{agid}/marks ​

admin — Add/remove a player's marks

Path parameters

NameDescription
agiddashed display id

Request body

NameDescription
deltaint — signed change to the player's marks

POST /players/{agid}/mute ​

admin — Server-mute/unmute a player

Path parameters

NameDescription
agiddashed display id

Request body

NameDescription
mutedbool — true to mute, false to unmute

POST /whisper ​

admin — Direct-message one player

Request body

NameDescription
alderonIddashed display id (alias accepted: agid)
messagestring

Moderation ​

GET /mutes ​

readonly — Persisted server mutes

Query parameters

NameDescription
offsetint, optional
limitint, optional

Response — mutes[] — each: alderonId, expiration (0 = permanent, else a unix timestamp), adminReason, userReason, expired. This is the PERSISTED store, not the connected players: a mute outlives the session that applied it, so offline players appear here too. expired is reported rather than left to the client, because an expired entry survives in the file until the next load prunes it.

GET /bans ​

readonly — List active bans

Query parameters

NameDescription
offsetint, optional — skip this many (default 0)
limitint, optional — max to return (default: all)

Response — total, count + bans[] — each: alderonId, ipAddress, expiration (0 = permanent), adminReason, userReason.

PUT /bans/ ​

admin — Ban a player

Path parameters

NameDescription
agiddashed display id

Request body

NameDescription
reasonstring, optional

DELETE /bans/ ​

admin — Lift a ban

Path parameters

NameDescription
agiddashed display id

GET /whitelist ​

readonly — List whitelisted players

Query parameters

NameDescription
offsetint, optional — skip this many (default 0)
limitint, optional — max to return (default: all)

Response — enforced (bool), total, count + whitelist[] — each: alderonId.

PUT /whitelist/ ​

admin — Whitelist a player

Path parameters

NameDescription
agiddashed display id

DELETE /whitelist/ ​

admin — Remove from whitelist

Path parameters

NameDescription
agiddashed display id

GET /admins ​

readonly — Players with an assigned role, including offline ones

Response — count + admins[] — each: alderonId, role, online plus name when the player is currently connected. Read from the persisted role assignments, so OFFLINE admins are included — unlike /players, which only shows who is on right now. A player promoted by name while offline is stored under that name, and is reported verbatim in alderonId.

PUT /admins/ ​

admin — Promote (assign an admin role)

Path parameters

NameDescription
agiddashed display id

Request body

NameDescription
rolestring — role name to assign

DELETE /admins/ ​

admin — Demote (remove admin roles)

Path parameters

NameDescription
agiddashed display id

GET /reports ​

readonly — In-game player reports queue

Query parameters

NameDescription
offsetint, optional — skip this many (default 0)
limitint, optional — max to return (default: all)

Response — total, count + reports[] — each: id, time, reporterName, reporterAlderonId, reportedName, reportedAlderonId, reason, category, resolved.

PATCH /reports/ ​

admin — Update a report. Every field is optional and only applied when present, so you can assign a ticket without clearing its reply. Sending a reply shows it to the reporter in game immediately if they are online, and on their next join if not

Path parameters

NameDescription
idreport id

Request body

NameDescription
statusstring, optional — open | investigating | resolved | rejected
assignedTostring, optional — moderator handling it
actionstring, optional — action taken
responsestring, optional — reply shown to the reporter in game
resolvedbool, optional — kept in step with status

Database editor ​

GET /database/characters/ ​

admin — Every stored character record for a player, including deleted ones (so a character removed by mistake can be recovered). Needs the 'database' permission, which is deliberately NOT part of an ordinary admin key — these are the raw save records

Path parameters

NameDescription
agiddashed display id

PUT /database/characters/{agid}/ ​

admin — Overwrite one character record. Takes a backup first. Rejected without confirm:true, because a malformed record costs the player their character and the only undo is that backup. The player must reconnect for the change to load

Path parameters

NameDescription
agiddashed display id
cidcharacter id

Request body

NameDescription
dataobject — the complete character record
confirmbool — must be true

Chat & Events ​

GET /chat ​

readonly — Recent player chat messages

Response — messages[].

POST /chat ​

admin — Post a message to global chat as the server

Request body

NameDescription
messagestring

POST /announce ​

admin — Broadcast a message (HUD announcement)

Request body

NameDescription
messagestring

QUERY /events ​

readonly — Filtered event search (structured body, GET semantics)

Request body

NameDescription
typesarray of strings, optional — only these event types
containsstring, optional — substring match on the event text
countint, optional — how many to return

Response — The same events[] shape as GET /events, filtered. Every field is optional, and an empty body is equivalent to the plain newest-N tail.

HTTP QUERY is a safe, idempotent read that carries a body (draft-ietf-httpbis-safe-method-w-body): GET semantics with POST transport, for filters too structured for a query string. It needs an engine that recognises the verb — older builds reject it before routing, so check the query.events capability first.

Example request body

json
{
  "types": ["PlayerKilled"],
  "contains": "Rex",
  "count": 50
}

GET /events ​

readonly — Recent server events (webhook feed)

Query parameters

NameDescription
countint, optional (default 200)

Response — events[] — the same events webhooks emit (joins, kills, admin actions...).

World ​

GET /world ​

readonly — Current weather + time of day

Response — weather, timeOfDay (+ related fields).

POST /world/weather ​

admin — Set the weather

Request body

NameDescription
typestring — weather type name

POST /world/time ​

admin — Set the time of day

Request body

NameDescription
timeOfDaystring/number — e.g. "day", "night", or 0..2400

GET /waters ​

readonly — Water bodies + current quality

Response — count + waters[] — each: identifier, quality (0..1).

POST /waters/refresh ​

admin — Refresh water quality to full

Query parameters

NameDescription
identifierstring, optional — one water body; omit for all

Response — refreshed — number of water bodies set back to full.

Settings & Config ​

GET /settings ​

readonly — Current mutable server settings

Response — Flat object of setting key -> current value.

GET /settings/all ​

readonly — All mutable settings with metadata + values

Response — settings[] — each: key, value, type, default, needsRestart, description.

PATCH /settings ​

admin — Update server settings

Request body

NameDescription
(key: value)object of setting keys to new values

Response — results — per-key outcome.

Example request body

json
{ "MaxPlayers": 100, "bServerPassword": false }

GET /config/ ​

admin — Read a raw config ini

Path parameters

NameDescription
whichgame | engine | curveoverrides | mods | webhooks

Response — content — the raw ini text — plus exists. For mods and webhooks, an absent dedicated file falls back to the legacy location and sets usingFallback (see the config.legacyFallback capability). A file that is simply not there (Mods.ini and Webhooks.ini are optional) answers 200 with exists: false and empty content, NOT a 500. Keep the two apart: for Mods.ini, absent means "fall back to GameUserSettings" while present-but-empty means "no mods", so collapsing them would turn a save into a silent mod wipe.

PUT /config/ ​

admin — Overwrite a raw config ini (needs restart)

Path parameters

NameDescription
whichgame | engine | curveoverrides | mods | webhooks

Request body

NameDescription
contentstring — full ini file text

Response — needsRestart + bytes. The previous contents are copied to &lt;name&gt;.ini.bak first, and the write is staged to a temp file and atomically renamed, so a failed write cannot truncate the live config. Creates the file if it did not exist.

POST /config/{which}/reload ​

admin — Re-read a config ini that was edited outside the API

Path parameters

NameDescription
whichgame | engine | curveoverrides | mods | webhooks

Response — Picks up a hand edit or a hosting-panel change without a restart. Branch-shape aware: game/engine rebuild the whole combined hierarchy (Default*.ini layers plus the generated file), standalone files re-read in place. Audited into the events feed like a write.

Player state ​

POST /players/{agid}/teleport ​

admin — Teleport a player to coordinates, a POI, or another player

Path parameters

NameDescription
agidplayer id, dashed or raw

Request body

NameDescription
destinationstring — a player name, a POI name, or Unreal coordinates (X=..,Y=..,Z=..)
x / y / znumbers — an alternative to destination for coordinates, which is what a JSON client naturally produces
safebool, optional (default true) — a safe teleport finds ground and avoids dropping the player inside geometry. Send false to place them exactly where asked.

Response — The command's response text. Forwards to the same Teleport RCON command an admin would type, so player resolution and permissions match chat.

Example request body

json
{
  "destination": "(X=45000,Y=-60000,Z=1500)"
}

GET /players/{agid}/attributes ​

readonly — Read a player's live gameplay attributes

Path parameters

NameDescription
agidplayer id, dashed or raw

Response — The GetAllAttr response text — health, stamina, growth and the rest of the attribute set. Returned as the command's own text rather than parsed: the set is large and game-specific, and parsing it in the plugin would put a second copy of that knowledge out of step with the game.

POST /players/{agid}/attributes ​

admin — Set one live gameplay attribute

Path parameters

NameDescription
agidplayer id, dashed or raw

Request body

NameDescription
namestring — the attribute, e.g. Health or Growth. Must be a plain identifier; the game resolves it and reports an unknown name as an error.
valuenumber — the new value

Response — The SetAttr response text. These exist so an integration does not need bAllowGenericCommand, a far broader grant than “may adjust a player’s health”.

Example request body

json
{
  "name": "Health",
  "value": 1450
}

MOTD & rules ​

GET /motd ​

readonly — Server MOTD, with its character limit

Response — The text under both motd and content, plus length and maxLength (16384) so you can check before sending rather than after a 400.

PUT /motd ​

admin — Replace the server MOTD

Request body

NameDescription
motdstring — the new MOTD
contentstring — accepted as an alias for the above

Response — Applies live; players see it immediately, so needsRestart is false. Over the limit is refused with a 400 naming the length and the limit — the setter would otherwise truncate silently. Newlines and the in-game rich-text tags both work. Needs the settings permission.

Example request body

json
{
  "motd": "Welcome!\nRaiding is allowed."
}

GET /rules ​

readonly — Server rules, with their character limit

Response — As GET /motd, under rules / content.

PUT /rules ​

admin — Replace the server rules

Request body

NameDescription
rulesstring — the new rules
contentstring — accepted as an alias for the above

Response — As PUT /motd. Both are also readable and writable through /settings; these exist because a single-value resource is the shape a bot actually wants. Stored as Saved/MOTD.txt and Rules.txt, not in an ini, which is why they do not appear in the config editor.

Webhooks ​

GET /webhooks ​

admin — Configured webhooks, section defaults, and every trigger this build can fire

Response — globals (the [ServerWebhooks] defaults actually in effect), webhooks[] (each: key, url, bAllowRetries, retryCount, timeoutSeconds, maxQueued, critical, perKeyOverrides) and availableKeys[] — every trigger name this build can fire, so a client can offer a picker instead of expecting the owner to know them. Per-key values are the EFFECTIVE ones: a key with no overrides reports the section defaults, and perKeyOverrides says which it is.

Needs the config permission, not read. A webhook URL is a bearer credential — whoever holds a Discord webhook URL can post to that channel as the server indefinitely — so listing them is exactly as privileged as reading Game.ini.

PUT /webhooks ​

admin — Replace the webhook set

Request body

NameDescription
webhooksarray — the FULL set to keep; an omitted entry is a deletion, and an entry with an empty url is removed rather than written blank
globalsobject, optional — the [ServerWebhooks] section defaults

Response — count written. Applies immediately (needsRestart: false): webhook config is re-read on every trigger. The section is rewritten wholesale, and a struct line is only emitted for a key that genuinely overrides a default, so a simple config stays simple. Keys are validated as plain identifiers before becoming ini key names.

Curves ​

GET /curves ​

readonly — Active curve/stat overrides

Response — The overrides set in the server ini alongside what actually resolved and applied, so a value that was accepted but never matched a real curve is visible rather than silently ignored.

PUT /curves ​

admin — Replace the server's curve overrides

Response — Applies live and persists to CurveOverrides.ini — no restart. Replaces the whole set, so send the full list, not a delta.

Roles ​

GET /roles ​

readonly — Configured player roles + permissions

Response — roles[] — each role with its permissions/flags (incl. spectatorAccess).

PUT /roles/ ​

admin — Create or edit a role definition (hot-reloaded)

Path parameters

NameDescription
namerole name

Request body

NameDescription
(role definition)permissions/flags object

DELETE /roles/ ​

admin — Delete a role definition

Path parameters

NameDescription
namerole name

Mods ​

GET /mods ​

readonly — Enabled + installed mods on this server

Response — enabledMods[] + installed[] — the installed list is the Mods folder itself (see mods.disk), each entry with hasFiles and detailsKnown.

GET /mods/available ​

readonly — Browse the Alderon mod catalog

Response — available[].

PUT /mods/ ​

admin — Enable a mod (needs restart)

Path parameters

NameDescription
skumod SKU, e.g. UGC_..._SK

Request body

NameDescription
buildSkustring, default "release"

DELETE /mods/ ​

admin — Disable a mod (needs restart)

Path parameters

NameDescription
skumod SKU

Backups ​

GET /backups ​

admin — List database backups

Response — count + backups[] — each: id, name (id is what /backups/{id}/restore takes).

POST /backups ​

admin — Create a database backup

POST /backups/{id}/restore ​

admin — Restore a database backup

Path parameters

NameDescription
idbackup id
Footer Image

1dc96e3