
DayZ in the Customer API and the Discord Bot
The DayZ routes in the Customer API and the Discord bot's /dayz command: what each returns, which ones need the GameGrid DayZ server mod, which read the platform's own record and so answer while the server is stopped, how paging, the leaderboard, player profiles and broadcasts work, and what the error answers mean.
What Each Route Needs
The Customer API and the GameGrid Discord bot have DayZ routes and a /dayz command. Each one reads from one of two places, and knowing which saves a lot of debugging.
| Feature | Comes from | What to expect |
|---|---|---|
| Player list, kill feed, player map positions | The GameGrid DayZ server mod | Available while the server is running and the mod has reported. Each answers about players who are in game, so an empty server returns an empty list rather than an error |
| On-screen broadcast | The GameGrid DayZ server mod | Available. The answer says what the platform did, including how many players it reached |
| Connects, disconnects and in-game chat | BattlEye RCon | Available while the BattlEye connection is open. A line appears when a player joins, leaves or types one, so a quiet server returns nothing new |
| Kill leaderboard, player profiles, the recorded kill feed | GameGrid's own record of what the server mod reported | Available even while the server is stopped, and it covers a longer stretch than one boot. It holds nothing from before GameGrid started watching that server |
| Items players sold back to your shop | GameGrid's own record of every sale it handled | Available even while the server is stopped. It is empty until a player sells something |
query_port on GET /servers/{id} | The server's ports | Available |
| The Battle Royale ring map link | The round this server is holding, and the share link that round was given | Available while a round is running. A server holding no round answers that it has none, which is an ordinary answer rather than an error |
The GameGrid DayZ server mod runs on the server side only, and GameGrid loads it for you: your players install nothing for the player list, the map, the kill feed or a broadcast.
For the general picture of the API and the bot, see Customer API Overview and Discord Bot Setup Guide.
Customer API Endpoints
All paths are under /api/public/v1. A server that is not DayZ answers 501 capability_unsupported. "Needs the server mod" means the route reads the GameGrid DayZ server mod, so it answers while the server is running and the mod has reported. "Reads GameGrid's record" means the route reads what the platform has stored from that mod, so it also answers while the server is stopped.
| Method and path | Scope | What it returns |
|---|---|---|
GET /servers/{id}/dayz/players | ingame:read | Online players: name, name_known, dayz_id, steam_id, alive, unconscious, in a vehicle, health and blood, plus player_count and age_ms. Needs the server mod |
GET /servers/{id}/dayz/killfeed | ingame:read | Deaths: time, victim, killer (player kills only), cause, weapon and distance in metres. Needs the server mod, unless you ask for source=recorded, which reads GameGrid's record |
GET /servers/{id}/dayz/leaderboard | ingame:read | The kill leaderboard for a window: rank, the player's key and name, kills, deaths, kd, longest kill and playtime, with watching_since and gap_seen. Reads GameGrid's record |
GET /servers/{id}/dayz/players/{playerKey} | ingame:read | One player's profile: combat counters, sessions and playtime, their last known state, and their recent kills and deaths. Reads GameGrid's record |
GET /servers/{id}/dayz/events | ingame:read | Players connecting and disconnecting, from BattlEye RCon |
GET /servers/{id}/dayz/chat | ingame:read | In-game chat lines, with the channel, from BattlEye RCon |
GET /servers/{id}/dayz/presets | settings:read | The ready-made configurations for areas, loot, crates, infected pressure, announcements, settings windows and Battle Royale rounds, each with an honest verdict about whether it works yet. Needs nothing running |
POST /servers/{id}/dayz/broadcast | ingame:message | Shows a message to every player. The on-screen notification comes from the server mod; without it the message goes out as a BattlEye chat line |
GET /servers/{id}/dayz/sales | economy:read | Items players sold back to your shop with !sell: what was offered, what it was priced at, what the server says it actually removed, and why a sale did not go through. Reads GameGrid's record |
GET /servers/{id}/map/players | map:read | Online players with their map positions. Needs the server mod |
GET /servers/{id}/battle-royale/ring-map | map:read | The public ring map link the Battle Royale round running now was given: round, and ring_map with its share token, what the link shows, and when it stops working. Needs nothing running |
GET /servers/{id} | servers:read | Includes query_port, the Steam query port (your game port plus 4 on DayZ), for server browsers and status sites |
GET /dayz/players is the only route that carries an identifier, and only for somebody who is online: dayz_id is the 44-character DayZ player id that ban.txt and whitelist.txt take, and steam_id is the 17-digit SteamID64 that priority.txt takes. Either can be null when the mod has no identity for that player yet, and name_known is false when name is the id's short form rather than a name the player chose. The leaderboard and the player profile carry the per-server key and the display name instead. No response carries a BattlEye GUID or an IP address, and player positions are only on the map route, behind its own scope.
GET /dayz/presets is the odd one out and it is worth knowing why: it reads nothing on your machine at all — no server, no mod, no stored record — so it answers while your server is stopped, which is when you are most likely to be setting one up. It takes settings:read rather than ingame:read because it is a catalogue of ways to CONFIGURE a server and not a report of what is happening inside one. Every preset comes back with status (today, next_restart or blocked), applies, caveat, still_needed and, when it is blocked, blocked_by naming the one thing that is missing. If you list these for other people, carry the verdict with them: a preset that needs a restart, or that is blocked, says so, and a list without that is advertising something we cannot deliver.
GET /dayz/sales needs saying plainly, because the setting that feeds it can be switched on today and what it answers depends on one thing outside the API. A player holds an item, types !sell, is quoted a price and accepts it; only then is the item removed and their wallet credited. That chain is joined end to end in the platform, and the order it runs in is the part worth knowing: the item is removed on your own server first, and the server re-checks that it is still the same item before destroying it, so a player who moved, dropped or swapped it is not charged for something else. Payment follows what the server says it actually destroyed rather than what was quoted, and a removal the server cannot confirm stops the sale for a person rather than guessing: it is neither paid nor cancelled until somebody looks at it. A sale pays into the wallet behind a player's linked account, so a !sell from a player who has not linked one ends the same way every time: a row with refusal_reason no_linked_wallet, a chat line telling the player to run /link, and nothing of theirs removed. Linking takes a minute and there are three ways to do it: the player runs /link in your Discord and types !link CODE in game, or you mint the code yourself with POST /servers/{id}/economy/link/initiate and confirm it with link/verify, or you link the account by hand from the server's Economy page. Once a link exists the wallet is there and the next !sell settles against it. A sell box is the other half of the same chain and it works the same way. Switch it on, and a player types !sellbox in game to place a container; anything they put in it is bought, priced from the same sell list, with the same removal-then-payment order and the same stop-for-a-person on a removal the server cannot confirm. There is no second confirmation — the box IS the consent — and the contents are dropped on the ground rather than destroyed if it expires or is removed. The command ships in the GameGrid server mod from build 1.3.2, and the platform asks your server which build it is running rather than assuming: a server on an older build is named on its own Economy page and told to restart, because two servers on one host can be running different builds. Selling from the hands with !sell is unaffected either way. Read Earning and Spending on DayZ before you price a sell list.
Two fields on this route are the ones to build anything against. needs_a_person, and the envelope's uncertain_count, mark a sale where the server took the removal and could not say whether it happened: the item may be gone, so it is never paid and never cancelled by anything automatic, and only a person decides. removed_item and removed_quantity are what the SERVER says it destroyed, which is what a settled sale is paid against - not what was quoted, because the two can differ. readiness reports the chain link by link with a state of working, not_built or off; show it rather than hide it, for the same reason the presets carry their verdicts. working is a link that is built and in service, not_built is one with no implementation at all, and off is one you have switched off yourself.
GET /servers/{id}/battle-royale/ring-map answers { round, ring_map } in snake_case with no envelope, and a server that is holding no round answers { "round": null, "ring_map": null } with a 200 - a server without a round is an ordinary state, not a failure, so do not treat it as an outage. It never makes a link. A round is given its ring map at the moment the round is requested, so polling this route cannot use up the live share links your server is allowed; there is no write counterpart and no scope grants one, because issuing and revoking a share link stay yours to do in the control panel. ring_map.token is the share token - build /map/share/<token> on your own origin - and it is null once the link has been revoked or has expired, with ring_map.reason carrying the sentence that says which. ring_map.shows is the list of feeds the link really exposes and ring_map.exposes is a sentence for each, in the same order, so a tool about to post the URL somewhere public can check rather than trust. A ring map link cannot carry player positions. The ring feed and the players feed cannot be carried by the same link, so shows never contains players and the players feed answers 404 on a ring link: whoever you hand it to sees the circles, the clock and how many players are left, and nothing about where anybody is standing.
The broadcast is rate limited like a start or restart.
Kill Feed, Connects and Chat: How Paging Works
Kill feed (needs the server mod). GET /servers/{id}/dayz/killfeed?limit=20 without a cursor returns the latest deaths, oldest first, and a next_cursor. Pass that back as ?cursor= to get only the deaths since. limit is 1 to 100. cause is one of pvp, infected, animal, vehicle, explosion, suicide, environment or unknown, and killer is set only for pvp.
{
"kills": [
{ "at": "2026-09-17T12:03:20.000Z", "victim": { "name": "Vex" }, "killer": { "name": "Rook" },
"cause": "pvp", "weapon": "M4A1", "distance_metres": 186.2 }
],
"next_cursor": "1789000000-004211.42",
"has_more": false,
"gap": false,
"complete": true
}gap: true means some deaths between your cursor and this page are no longer stored.
The recorded kill feed. ?source=recorded answers from GameGrid's own record instead of the running server. It keeps every death since we started watching, so it answers while the server is stopped and it does not begin again each time the server comes back up. It returns the latest limit deaths and is not paged: next_cursor is null and cursor is ignored, so use source=live (the default) when you want to page. gap is true when deaths were reported lost before we could record them.
Connects and chat. GET /servers/{id}/dayz/events and GET /servers/{id}/dayz/chat take ?since= and return a cursor to pass next time; start with 0. If cursor_reset is true, the numbering started again (the connection to the server was restarted), so start from 0. Poll every few seconds rather than continuously.
The Leaderboard and Player Profiles
The kill feed above pages the running server, so its numbering begins again every time the server comes back up. The leaderboard and the player profile read GameGrid's own record of what the server mod reported, so they cover a longer stretch than one boot and they answer while the server is stopped.
Leaderboard. GET /servers/{id}/dayz/leaderboard?window=7d&limit=25 returns rows ranked by kills, then by fewest deaths. window is session (since this server last started), 7d, 30d or all; all is the default, a value we do not recognise is answered as all rather than refused, and the response repeats the window it used. limit is 1 to 100, default 25.
{
"window": "7d",
"rows": [
{ "rank": 1, "key": "p-4c1d9f02ab7e5630", "name": "Rook", "name_known": true,
"kills": 14, "deaths": 3, "kd": 4.67, "longest_kill_metres": 312.5,
"playtime_seconds": 20460 }
],
"watching_since": "2026-09-14T08:11:00.000Z",
"gap_seen": false
}Only a player killing another player scores a kill — the infected, animals, falls and suicides count as deaths only. kd is null until a player has at least 10 kills, because one lucky kill says nothing. watching_since is the oldest death on record, and there is no history from before GameGrid started watching this server, so a new server's board starts at zero. gap_seen is true when events were reported lost, which means the board is incomplete. The session window is empty until the server has been read at least once.
Player profile. GET /servers/{id}/dayz/players/{playerKey} takes a key from the leaderboard. That key is a stable handle for one player on one server: it is not a Steam or DayZ id and it links to nothing, and a key from another server will not resolve here.
The answer carries combat (kills, deaths, and the split into pvp_deaths, pve_deaths, suicides and other_deaths, plus kd, the longest kill and the last kill and death times), presence (sessions and playtime_seconds, with the last connect and disconnect), last_known_state (health, blood, alive, unconscious, in a vehicle) and the player's recent_kills and recent_deaths. Every one of those sections names its own source: mod_events for anything counted from events as they happened, mod_snapshot for the last state we were shown.
other_deaths is every death that was not PvP, PvE or a suicide: falls, drowning, cold, bleeding out. Playtime is measured from connects and disconnects, so a crash, which sends no disconnect, shortens that session. Nothing in a profile predates GameGrid watching this server, and no offline character file is read — the game owns that file, and a wipe deletes it. There are no coordinates here either; positions are on GET /servers/{id}/map/players, behind map:read.
Broadcasting a Message
Send POST /servers/{id}/dayz/broadcast with a JSON body:
{ "message": "Server restart in 5 minutes", "title": "Admin", "seconds": 10 }message is one line of up to 256 bytes, title is optional and up to 64 bytes, and seconds (1 to 30, default 8) is how long the on-screen notification stays.
The answer tells you what the platform did:
status | Meaning |
|---|---|
delivered | via: "mod" means an on-screen notification (with recipients); via: "rcon" means BattlEye accepted it as a chat line |
uncertain | The server took the message but did not confirm it. It is not sent again, so it never appears twice |
failed | Not sent. reason says why, for example not_running |
recipients is how many players were in game when the mod showed the message, so a broadcast to an empty server is delivered with recipients: 0. If the server mod is not reporting, the message goes out as a BattlEye chat line instead (via: "rcon"). BattlEye messages are plain ASCII: accented letters and emoji are replaced with ?.
Send an Idempotency-Key header with a UUID, and retrying the same request returns the first answer instead of sending the message again. Every broadcast is recorded in your account's audit trail.
The /dayz Discord Command
On a Discord server linked to your GameGrid account, /dayz works on DayZ servers only, and reads the same data as the API routes above:
| Command | Does | Bot ability | API scope |
|---|---|---|---|
/dayz players | Who is online. Needs the server mod | ingame.read | ingame:read |
/dayz killfeed | The latest deaths. count is 1 to 20; visibility posts it in the channel. Needs the server mod | ingame.read | ingame:read |
/dayz broadcast | Sends your message (and optional title) to every player in game | ingame.message | ingame:message |
/dayz map | A link to the live map page for the server. Needs the server mod | map.read | map:read |
/dayz ring-map | The Battle Royale ring map link for the round running now. visibility posts it in this channel (the default) or shows it only to you. The link never carries player positions | ingame.message and map.read | map:read |
Every command takes the usual optional server-id; leave it blank to use the channel's or the Discord server's default.
Two things must both allow it. The Discord role needs the ability (grant it with /permissions), and the API key you linked with /setup needs the scope. ingame.read and map.read are in the member preset and ingame.message in the operator preset. The key is checked first and for everybody, including the Discord server owner, so /dayz map needs a key carrying map:read even though it only prints a link. The "Discord Bot" preset in the key screen includes ingame:read and ingame:message but not map:read, so tick map:read yourself when you create the key, and create a new key and run /setup again if the bot says the key is the problem.
/dayz ring-map is the one subcommand that asks for two abilities at once, and it is worth knowing why before you grant it. map.read is the ability behind the scope the read itself needs. ingame.message is the bot's existing permission to put something in front of everybody - the one /dayz broadcast already asks for - and it is required here because what this hands out is a working link that anybody holding it can open, with no GameGrid account and no sign-in. It sits in the operator preset, and the bot refuses to give anything above member to @everyone, so a public invite is not a way into it. Both are required for Only me as well: a private reply is a quieter way to receive the same link, not a smaller one. It posts into the channel you typed it in and nowhere else, and if the link it is handed turns out to show player positions it posts nothing and says so instead.
See Discord Bot Permissions & Security for how abilities and scopes combine.
Error Answers
| You see | Why | What to do |
|---|---|---|
501 capability_unsupported / "not a DayZ server" | The server id is for another game | Pick the DayZ server |
502 upstream_unavailable with reason: no_snapshot | The GameGrid DayZ server mod has not reported yet. It writes its first snapshot a short while after the server comes up | Wait until the server is online, then try again |
502 with reason: snapshot_stale or not_running | The server is stopped, starting or restarting | Try again once it is online |
502 with reason: rcon_not_connected | The BattlEye connection is still being opened | Try again in a moment |
404 from /dayz/players/{playerKey} | GameGrid has no record of that player on this server | Take a key from GET /servers/{id}/dayz/leaderboard; a key belongs to one server, and a player GameGrid never watched has none |
403 | The key lacks ingame:read, ingame:message or map:read | Create a key with the scope; keys cannot be widened |
/dayz ring-map says there is no round | This server is not holding a Battle Royale round, so there is no ring map to share | Request a round on the server's Battle Royale page, then run it again |
/dayz ring-map says the round has no map link | A round is given its ring map when it is requested, and it was made without one if the server was already holding its maximum number of live share links, or the link has since been revoked or expired | Revoke a share link you no longer need, and the next round is given a map |
Questions about the console itself are covered in DayZ BattlEye RCon and the Console Tab.
