Perk fulfilment
You keep your store. Citadel does the granting.
Point whatever you already sell through — Tebex, PayNow, a bespoke checkout, a Discord command, a subscription expiry job — at one signed webhook. Citadel turns that into an in-game grant and keeps trying until it lands.
On this path Citadel takes no cut of your sales and never touches your money. It is $15 a month for the automation, and your checkout stays exactly as it is.
Would rather not run a checkout at all? Citadel can host the store for you — a themed storefront at its own link with Steam sign-in, purchase history and a live servers page, for $10 a month, with Citadel taking 5% of each sale into your own Stripe account. See Store & fulfilment. The delivery guarantees below are identical either way; only the checkout differs.
The request
POST https://ops.citadel-hub.com/api/v1/hooks/<your-webhook-id>
Sign the raw body with HMAC-SHA256 using your webhook secret, and send it as
x-citadel-signature: sha256=<hex>.
Sign the bytes you send, not a re-serialised object. Parsing to JSON and re-encoding changes key order and whitespace, and the signature then fails for reasons invisible in the payload.
A queue or whitelist grant
{
"commandType": "AddPriorityQueue",
"steam64": "76561198000000000",
"days": 30,
"comment": "VIP 30 days",
"dedupeKey": "your-order-id"
}
commandType is one of AddPriorityQueue, RemovePriorityQueue,
AddWhitelist, RemoveWhitelist. Omit days, or send -1, for permanent.
An LBmaster perk
{
"perk": "colored-tag-add",
"values": { "steamid": "76561198000000000", "remainingCount": -1 },
"dedupeKey": "your-order-id"
}
Send either commandType or perk, never both. A payload naming both is
refused rather than half-delivered — delivering one leg of a bundle and reporting
success is precisely the failure this is built to avoid.
Running more than one server? Add "serverId": "..." to target a specific one.
Omit it and the perk goes to the server the webhook belongs to.
dedupeKey is the important field
Send your order id. Every store retries, and without a stable key one purchase becomes two grants the first time a delivery times out after having succeeded.
A retry with a key we have already seen returns 200 and the original command,
not an error. A store told "conflict" retries harder; a store told "done" stops.
What happens next
The grant goes on a durable queue. If the server is down — and DayZ servers restart several times a day — it waits and delivers on the next poll. A restart is the normal case here, not an edge case.
Delivery is at-least-once with an explicit acknowledgement. Anything unacked comes back. Applying a grant twice is harmless; losing one somebody paid for is not.
Delivered is not applied
Worth understanding, because it is the failure that costs you money quietly.
LBmaster's mod answers 200 to a grant whose field names it did not recognise.
It drops what it does not know, defaults it, stores the rest, and reports
success. Every signal says the perk worked. The player has nothing.
That is not hypothetical: an allowance field was once named count instead of
remainingCount, and every grant registered the player with zero uses while
reporting fine.
So the console has a Send and verify action. It writes the perk, reads it
back from the mod's list route, and compares what was stored against what was
sent. Run it once per perk per server before you sell that perk. A 200 alone
proves nothing.
Seeing what happened
The LB Core screen in the console shows every command, its status, and what the mod actually replied — code and message, not just that it answered. That is the screen that settles "the customer says they did not get it".
Errors worth handling
| Response | Meaning |
| --- | --- |
| 401 | Signature missing or wrong |
| 404 | Unknown or revoked webhook |
| 400 unknown_perk | The perk name is not one we know |
| 400 missing_steamid | Every LB perk needs a steamid in values |
| 409 no_lb_connection | That server has no LB Core connection yet |
| 200 duplicate | Already queued under that dedupeKey — stop retrying |