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
- Handshake on startup to declare which commands you implement.
- Get-all-commands once to resync anything queued while you were offline.
- Ping in a loop (long-poll) to receive new commands.
- 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.