Back to SDK Docs
Webhooks
Real-time event notifications for your backend
HTTPS OnlyHMAC-SHA256 SignaturesAutomatic Retries
Overview
Webhooks allow your server to receive real-time notifications when events occur in Funstack. Configure webhook endpoints in your Creator Dashboard to start receiving events.
Available Events
Subscribe to specific events or use * to receive all events.
player.created New player registeredplayer.login Player logged inxp.earned Player earned XPxp.spent Player spent XPachievement.unlocked Achievement unlockeditem.purchased Item purchased from storeitem.transferred Item transferred between playersad.completed Rewarded ad completedad.failed Rewarded ad failedwallet.connected Wallet connected to accountlevel.up Player leveled upPayload Format
All webhook payloads follow a consistent JSON structure with event type, timestamp, data, and signature.
Example Payload (xp.earned)
{
"id": "evt_1234567890",
"type": "xp.earned",
"created": 1704672000,
"data": {
"playerId": "player_abc123",
"amount": 100,
"source": "ad_reward",
"newBalance": 1500,
"metadata": {
"adPlacement": "level_complete",
"gameSession": "session_xyz"
}
},
"signature": "sha256=abc123..."
}Verifying Signatures
Always verify webhook signatures to ensure requests are from Funstack. The signature is included in the X-XP-Signature header.
Signature Verification (Node.js)
import crypto from 'crypto';
function verifyWebhook(payload: string, signature: string, secret: string): boolean {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(`sha256=${expectedSignature}`)
);
}
// Express.js example
app.post('/webhooks/xp-platform', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-xp-signature'] as string;
const payload = req.body.toString();
if (!verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET!)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const event = JSON.parse(payload);
switch (event.type) {
case 'xp.earned':
handleXPEarned(event.data);
break;
case 'achievement.unlocked':
handleAchievement(event.data);
break;
// ... handle other events
}
res.status(200).json({ received: true });
});Security Best Practices
- • Always verify signatures before processing events
- • Use HTTPS endpoints only
- • Respond quickly (within 5 seconds) to avoid timeouts
- • Process events asynchronously if they require heavy computation
Retry Policy
Failed webhook deliveries are automatically retried with exponential backoff.
Retry Schedule
// Webhook retry schedule:
// - Attempt 1: Immediate
// - Attempt 2: 5 minutes
// - Attempt 3: 30 minutes
// - Attempt 4: 2 hours
// - Attempt 5: 24 hours
// Response codes:
// - 2xx: Success, no retry
// - 4xx: Client error, no retry (except 429)
// - 429: Rate limited, retry with backoff
// - 5xx: Server error, retry