Relay API reference

The Command Relay is how Citadel delivers commands (perk grants/revokes) to your game server or worker. Any client can implement it: handshake, poll, apply, ack.

Base URL: https://api.citadel-hub.com/api/v1/command-relay/{serviceId}

Authentication

Every request is authenticated with the relay key (csk_…) issued when you create the connection, as a Bearer token. The {serviceId} in the path must match the key.

Authorization: Bearer csk_xxxxxxxxxxxx
Content-Type: application/json

Lifecycle

  1. Handshake on startup to declare which commands you implement.
  2. Get-all-commands once to resync anything queued while you were offline.
  3. Ping in a loop (long-poll) to receive new commands.
  4. Ack the commands you successfully applied.

POST /{serviceId}/handshake

// request
{ "Commands": ["AddPriorityQueue", "RemovePriorityQueue"] }
// response
{ "Success": true, "Message": "ok", "InitCommands": [] }

POST /{serviceId}/ping

Long-poll. Returns immediately if commands are queued; otherwise waits up to WaitTimeMs (0–120000, default 30000) and returns whatever appeared.

// request
{ "WaitTimeMs": 25000 }
// response
{
  "Success": true,
  "Commands": [
    {
      "Id": "cmd_abc",
      "CommandType": "AddPriorityQueue",
      "Payload": { "steam64": "7656119...", "days": 30 },
      "ServiceId": null,
      "CreatedAt": "2026-06-02T00:00:00.000Z"
    }
  ]
}

Send the next ping immediately after processing a response.

POST /{serviceId}/get-all-commands

Resync — re-leases every command not yet acked, so a reconnecting client sees all outstanding work. Same response shape as ping.

POST /{serviceId}/ack

Confirm the commands you applied. Only acked commands are considered done.

// request
{ "Ids": ["cmd_abc"] }
// response
{ "Success": true, "Acked": 1 }

Delivery guarantees

Delivery is at-least-once with ack:

  • A polled command is leased, not consumed. It is "done" only when you ack it.
  • Anything you don't ack (a crash mid-batch, a failed apply) is redelivered after the lease (≈60s) — so a paid grant is never silently dropped.
  • Because of redelivery, apply commands idempotently.
  • A command that can't be applied after ~25 redeliveries is dead-lettered and surfaced in your audit log.

Errors

The relay returns HTTP 200 on success. A non-200 or timeout means "treat the API as down" — back off and re-handshake before resuming.