Developer documentation

Cinder API

Import original staff cases and export accepted bans from your own tools.

Base path
/api/cinder
Authentication
Authorization: Bearer wg_cinder_…
Format
JSON requests and responses
Cost
Free with an approved Cinder account
OpenAPI 3.1
/api/openapi.json

Authentication

Create a key in Cinder under API keys.

Send it as a bearer token in the Authorization header.

Authorization: Bearer wg_cinder_…
  • Keys reach only your own Cinder account.
  • Read views need the bans.read scope.
  • Import, publish, save and withdraw need the bans.write scope.
  • Keys can be revoked at any time in the dashboard.

Export

GET /api/cinder?view=export&page=0

Returns accepted cases from followed public and private lists with evidence and your saved decisions.

  • Use source=own to export your own cases.
  • Pages hold up to 25 cases, continue until page + 1 === pages.
  • Withdrawn and expired public cases are excluded.

Public queue

GET /api/cinder?view=queue&status=pending&page=0

Read unreviewed public cases without subscribing or changing a game-server ban list.

Import

Import original staff cases as drafts, then publish them from the API or the dashboard.

FieldRequiredFormat
externalIdYesStable unique ID from your system, 1 to 120 characters. The same ID returns the existing case
steamIdYes17-digit Steam ID as a string
originYes"staff" for original manual bans only
reasonYesShort ban reason, 1 to 200 characters
issuedAtYesUnix milliseconds, not in the future
expiresAtNoUnix milliseconds after issuedAt, or null for permanent
context.notesFor the official public listStaff explanation, up to 10,000 characters, with more than the category word
context.linksFor the official list without an uploadArray of {url, kind}, up to 2,000 characters per URL. kind is video, image or supporting, and only video and image count as evidence
context.tagsNoUp to 5 of Cheating, Griefing, Toxicity, Racism, Other
context.transcriptNoText, up to 30,000 characters
context.ticketNoArray of up to 100 {author, role, time, text} messages per case
context.appealNo{community, method, message, url} where method is community or arbitration
evidenceIdsNoUp to 10 upload IDs. Empty on import, attach uploads in the dashboard
POST /api/cinder
Content-Type: application/json

{
  "action": "import",
  "cases": [{
    "externalId": "my-system-ban-123",
    "steamId": "76561198000000001",
    "origin": "staff",
    "reason": "Cheating",
    "issuedAt": 1792530000000,
    "expiresAt": null,
    "context": {
      "notes": "Staff reviewed the recording and documented the incident.",
      "tags": ["Cheating"],
      "links": [{"kind": "video", "url": "https://example.com/clip"}]
    }
  }]
}
  • Requires the bans.write scope.
  • Import up to 100 cases per request and send another request for more.
  • Unknown fields are rejected with 400, so send only the fields in the table.
  • Imports stay private drafts under your account until you publish them.
  • Imports return their ids in request order.
  • Retrying an identical external ID returns its existing case, and different content returns 409.
  • Automatic and received bans cannot be imported as original staff cases.

Publish

POST /api/cinder
{"action":"publish","id":"CASE_UUID","version":1}
  • Publish sends one draft to the official public WarGuardian ban list.
  • Drafts, private lists and your own exports need no evidence.
  • The official list needs notes that say more than the ban category.
  • It also needs one uploaded video or image, or one link with kind video or image.
  • Supporting links alone do not count as evidence.
  • Tickets and transcripts are optional, and valid submissions publish at once.

Accepted-ban export fields

GET /api/cinder?view=export&page=0&listId=LIST_UUID
  • Exports accepted bans only.
  • Omit listId for all followed lists.
  • Your submissions remain separate under source=own.
FieldValue
entriesAccepted, active, accessible cases only
entries[].id / listId / listNameCase ID and source ban list
entries[].steamId / nameStable Steam ID and available Steam username
entries[].reason / actorNameOriginal ban reason and issuing staff name
entries[].issuedAt / expiresAtUnix milliseconds, a null expiry means permanent
entries[].publishedAt / sourceCommunityIdPublication time and issuing community ID
entries[].reviewYour status, version and decision time
entries[].contextShared notes, tags, links, transcript, ticket and appeal details
entries[].evidenceShared file metadata: id, name, type and size
entries[].canEvidenceWhether evidence is accessible for this list
page / pages / totalZero-based page, page count and total accepted cases
exportRevisionStays the same across a complete export, retry the export if it changes

Evidence files

GET /api/cinder?view=list-evidence&listId=LIST_UUID&entryId=CASE_UUID&fileId=FILE_UUID

Returns a short-lived file URL that expires after 60 seconds.

  • Hidden evidence is omitted.
  • Private lists require a valid sharing-code grant.
  • Revoked, withdrawn, expired and inaccessible cases are excluded.

Update and withdraw

GET /api/cinder?view=case&id=CASE_UUID
POST /api/cinder {"action":"save","id":"CASE_UUID","version":1,"input":{...}}
POST /api/cinder {"action":"withdraw","id":"CASE_UUID","version":2}
  • Use the latest case version.
  • Published case facts cannot be edited.
  • Withdrawing removes the case from public exports.

Responses

StatusMeaning
200The request succeeded and the body holds the view or result.
400A field failed validation, an unknown field was sent, or the publication lacks notes or evidence.
401The key is missing, invalid or revoked.
403The key lacks the required scope or the account is not approved.
409The case changed, needs attention, or an external ID was retried with different content.