Skip to content

Events & Payloads

Every webhook delivery sends a JSON payload with three fields:

FieldTypeDescription
eventstringThe event identifier
dataobjectEvent-specific payload
timestampstringISO 8601 timestamp of when the event occurred

Fired when points are awarded to a user via POST /v1/points/award.

{
"event": "points.awarded",
"data": {
"ledgerId": "f1e2d3c4-b5a6-7890-1234-567890abcdef",
"userId": "user_12345",
"eventType": "signup",
"pointsAwarded": 500,
"userBalance": 5500,
"reference": "ref_signup_user12345",
"createdAt": "2025-07-15T10:00:00Z"
},
"timestamp": "2025-07-15T10:00:00Z"
}
FieldTypeDescription
ledgerIduuidUnique ledger entry ID
userIdstringThe user who received points
eventTypestringThe event type that triggered the award
pointsAwardedintegerPoints awarded
userBalanceintegerUser’s balance after the award
referencestringIdempotency reference (if provided)
createdAtdatetimeWhen the award was created

Fired when a user plays a game via POST /v1/games/play.

{
"event": "game.played",
"data": {
"playId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"gameType": "NEON_WHEEL",
"userId": "user_12345",
"pointsSpent": 100,
"userBalance": 4900,
"outcome": {
"winningSegment": 3,
"spinAngle": 247.5
},
"reward": {
"tier": "rare",
"type": "cashback",
"value": 50,
"label": "$0.50 cashback"
},
"environment": "LIVE",
"playedAt": "2025-07-15T10:30:00Z"
},
"timestamp": "2025-07-15T10:30:00Z"
}
FieldTypeDescription
playIduuidUnique play record ID
gameTypestringNEON_WHEEL, COSMIC_SLOTS, or ENIGMA_BOXES
userIdstringThe user who played
pointsSpentintegerPoints deducted
userBalanceintegerBalance after deduction
outcomeobjectGame-specific outcome data
reward.tierstringepic, rare, or common
reward.typestringcashback, xp, points, item, or special
reward.valueintegerNumeric reward value
reward.labelstringHuman-readable reward label
environmentstringLIVE or TEST
playedAtdatetimeWhen the game was played

import express from 'express';
import crypto from 'crypto';
const app = express();
app.use(express.json());
const WEBHOOK_SECRET = 'whsec_your_secret_here';
app.post('/webhooks/gamifyhost', (req, res) => {
// 1. Verify signature
const signature = req.headers['x-webhook-signature'];
const expected = 'sha256=' + crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(JSON.stringify(req.body))
.digest('hex');
if (signature !== expected) {
return res.status(401).send('Invalid signature');
}
// 2. Handle event
const { event, data } = req.body;
switch (event) {
case 'points.awarded':
console.log(`${data.userId} earned ${data.pointsAwarded} pts`);
break;
case 'game.played':
console.log(`${data.userId} won ${data.reward.label}`);
break;
}
res.status(200).send('OK');
});