Plugin API: connect your game server
Connect your game server (Minecraft, Rust, ARK…) to your campaign: progress shows up in-game and rewards are granted automatically.
1. Authentication
Generate a key
In your dashboard: Campaign → Edit tab → “In-game plugin” → Generate a key. The full key (ka_live_…) is shown only once: copy it and paste it into your plugin config.
- A key is scoped to a single campaign / a single server.
- Only the SHA-256 hash is stored: nobody can read your key back. Lost it? Generate a new one.
- You can revoke a key at any time; it stops working immediately.
Use the key
Send the key in the Authorization header of every request:
Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxSecurity: the key is a server secret. Never put it in a game client, a public repo, or anything players can access.
2. Basics
| Base URL | https://keepalive.gg · local dev http://localhost:3100 |
|---|---|
| Format | JSON for requests and responses. |
| Rate limit | ~120 requests / minute per key. Beyond that → 429. |
| Polling | An interval of 30 to 60 s is plenty. |
Errors follow a standard envelope: { "error": { "code", "message" } }
401Missing, invalid or revoked key.404The campaign no longer exists.429Too many requests, try again shortly.
/api/plugin/campaignReturns the funding progress of the campaign tied to the key; call it periodically to refresh the in-game display.
curl https://keepalive.gg/api/plugin/campaign \
-H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxx"{
"campaign": {
"slug": "skycraft-survie",
"title": "SkyCraft Survie",
"game": "minecraft",
"status": "published",
"goalKind": "monthly",
"goalCents": 2000,
"currency": "EUR",
"raisedCents": 1450,
"pct": 73,
"supporters": 12,
"rewards": [
{ "minCents": 500, "title": "Role", "description": "…" }
]
}
}goalCents / raisedCents are in cents · pct already clamped to 0 to 100 · goalKind is monthly or oneshot.
/api/plugin/donationsLists captured donations, oldest first, to grant rewards. The cursor avoids re-fetching old donations.
| Param | Default | Description |
|---|---|---|
after | none | Opaque cursor: the nextCursor from the previous page. Omit it on the first call. |
limit | 50 | Max number of donations (capped at 50). |
curl "https://keepalive.gg/api/plugin/donations?after=CURSOR" \
-H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxx"{
"donations": [
{
"id": "don_9f2c…",
"donorName": "Nova",
"amountCents": 1000,
"currency": "EUR",
"message": "gg",
"recurring": false,
"rewardTitle": "Kit VIP",
"createdAt": "2026-07-21T18:04:11.000Z"
}
],
"nextCursor": "2026-07-21T18:04:11.000Z|don_9f2c…"
}Exposed fields (public only):
| Field | Description |
|---|---|
id | Unique donation id (used to de-duplicate). |
donorName | Public name entered by the donor (null if anonymous). |
amountCents | Donation amount, in cents. |
message | Public message from the donor (null if none). |
recurring | true if it’s a monthly donation. |
rewardTitle | Unlocked tier to grant in-game (null if none). |
createdAt | ISO 8601 date. |
Never an email, a Stripe id or the net amount: only what’s already public on the campaign page.
Recommended polling loop
cursor = load_cursor() # empty on first run
handled_ids = load_ids() # anti-duplicate
every 30 to 60 s:
page = GET /api/plugin/donations?after=cursor
for each donation in page.donations:
if donation.id already handled: continue
if donation.rewardTitle and donation.donorName:
player = find_player(donation.donorName)
if player: grant_reward(player, donation.rewardTitle)
mark donation.id handled
if page.nextCursor:
cursor = page.nextCursor ; save(cursor)Always de-duplicate on id: never grant the same reward twice, even at the cursor boundary.
3. Grant the reward to the right player
KeepAlive doesn’t know the donor’s in-game account, only the public name they entered (donorName). The recommended convention:
Ask your players to donate using their in-game name as the public name.
Your plugin then matches donorName to the player (case-insensitive). If nobody matches at donation time, keep the reward pending and replay it when they reconnect.
Planned: a “claim code” flow (/claim <code> in-game) will make attribution 100% reliable, regardless of the name.
Ready to connect your server?
Generate an API key from your campaign dashboard and follow the examples above.
Open my dashboard →