Webhooks
Subscribe to real-time events instead of polling. Get instant notifications when matches start, end, or when specific events occur.
Instant Updates
Get notified within milliseconds of events occurring
Reduce API Calls
No more polling - save your rate limit for other requests
Secure
HMAC signatures verify webhook authenticity
Registering a Webhook
Register a webhook endpoint to receive events:
curl -X POST "https://api.citoapi.com/v1/webhooks" \
-H "Authorization: Bearer sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhook",
"events": ["match.started", "match.ended", "player.elimination"],
"description": "Match notifications for Discord bot"
}'{
"id": "wh_abc123",
"url": "https://yourapp.com/webhook",
"events": ["match.started", "match.ended", "player.elimination"],
"secret": "whsec_xyz789...",
"status": "active",
"created_at": "2026-01-15T10:00:00Z"
}Important: Save the secret value. You'll need it to verify webhook signatures.
Available Events
| Event | Description |
|---|---|
match.started | Fired when a competitive match begins |
match.ended | Fired when a match concludes with final scores |
match.updated | Fired on significant score changes during live matches |
player.elimination | Fired when a player is eliminated (Fortnite) |
player.kill | Fired on player kills with attacker/victim info |
tournament.started | Fired when a tournament begins |
tournament.ended | Fired when a tournament concludes |
round.ended | Fired at the end of each round (Valorant, CS) |
Handling Webhooks
Create an endpoint to receive webhook events:
// Express.js example
const crypto = require('crypto');
app.post('/webhook', (req, res) => {
// Verify signature
const signature = req.headers['x-cito-signature'];
const expectedSig = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(JSON.stringify(req.body))
.digest('hex');
if (signature !== expectedSig) {
return res.status(401).send('Invalid signature');
}
// Handle the event
const { event, data } = req.body;
switch (event) {
case 'match.started':
console.log(`Match started: ${data.tournament}`);
// Notify Discord, update database, etc.
break;
case 'match.ended':
console.log(`Match ended. Winner: ${data.winner}`);
break;
case 'player.elimination':
console.log(`${data.eliminator} eliminated ${data.eliminated}`);
break;
}
res.sendStatus(200);
});Webhook Payload
All webhooks follow the same structure:
{
"id": "evt_123abc",
"event": "match.started",
"created_at": "2026-01-15T18:00:00Z",
"data": {
"match_id": "match_12345",
"game": "fortnite",
"tournament": "FNCS Grand Finals",
"region": "NA-EAST",
"players_count": 100
}
}Retry Policy
If your endpoint returns a non-2xx status code, we'll retry with exponential backoff:
- 1st retry: 1 minute
- 2nd retry: 5 minutes
- 3rd retry: 30 minutes
- 4th retry: 2 hours
- 5th retry: 24 hours (final attempt)
After 5 failed attempts, the webhook will be disabled. You can re-enable it from the dashboard.