Skip to main content

Documentation Index

Fetch the complete documentation index at: https://teambattles.gg/docs/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Webhooks allow your application to receive real-time HTTP POST notifications when events occur on TeamBattles. Instead of polling the API, you register an endpoint URL and select which events to receive.

Setup

Register an Endpoint

Go to Settings > Developer and click “Add Endpoint” in the Webhooks section, or use the API:
POST /api/user/webhooks
Body:
{
	"url": "https://your-server.com/webhooks/teambattles",
	"events": ["match.started", "match.completed", "score.submitted"],
	"label": "Production Server"
}

Webhook Secret

When you create an endpoint, a signing secret is generated. This secret is used to verify that webhook deliveries are from TeamBattles.
The webhook secret is shown only once when the endpoint is created. Store it securely.

Events

Match Events

EventDescription
match.createdA new match was created
match.publishedMatch was published and visible to opponents
match.acceptedAn opponent accepted the match
match.readyMatch is ready to begin (all check-ins complete)
match.startedMatch began
match.completedMatch finished with a result
match.cancelledMatch was cancelled
match.forfeitedA team forfeited the match

Score Events

EventDescription
score.submittedA score was submitted
score.confirmedA score was confirmed by the opponent
score.disputedA submitted score was disputed

Team & Player Events

EventDescription
roster.updatedMatch roster was changed
player.checked_inA player checked in for the match
team.joinedA team joined the match
team.leftA team left the match

Payload Format

All webhook deliveries use the following format:
{
	"id": "evt_abc123",
	"event": "match.completed",
	"timestamp": "2026-02-23T15:30:00Z",
	"data": {
		"matchId": "match_123",
		"gameId": "call_of_duty_black_ops_7",
		"winner": "team_abc",
		"scores": {
			"team_abc": 250,
			"team_def": 180
		}
	}
}

Signature Verification

Every webhook delivery includes an X-TeamBattles-Signature header containing an HMAC-SHA256 signature of the request body. The header value is prefixed with sha256= followed by the hex digest (for example, sha256=abc123...). Strip the prefix before comparing against your computed digest.

Verifying in Node.js

import crypto from "crypto";

function verifyWebhookSignature(body, signatureHeader, secret) {
	// Header is "sha256=<hex>"; strip the scheme prefix before comparing.
	const signature = signatureHeader.startsWith("sha256=")
		? signatureHeader.slice("sha256=".length)
		: signatureHeader;
	const expected = crypto.createHmac("sha256", secret).update(body, "utf8").digest("hex");
	return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

// In your webhook handler
app.post("/webhooks/teambattles", (req, res) => {
	const signature = req.headers["x-teambattles-signature"];
	const isValid = verifyWebhookSignature(req.rawBody, signature, process.env.WEBHOOK_SECRET);

	if (!isValid) {
		return res.status(401).send("Invalid signature");
	}

	const event = req.body;
	console.log(`Received ${event.event}:`, event.data);
	res.status(200).send("OK");
});

Verifying in Python

import hmac
import hashlib

def verify_signature(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        body,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

Delivery

Each event is delivered exactly once. Requests use a 10-second timeout and do not follow redirects - a 3xx response is treated as a failure. There are no automatic retries: if your endpoint times out or returns a non-2xx response, the delivery is recorded as failed.
  • Webhooks are delivered within seconds of the event
  • Your endpoint must respond with a 2xx status within 10 seconds
  • Requests are sent with redirect: 'manual'; any 3xx response counts as a failed delivery
  • After 50 consecutive failed deliveries, the endpoint is automatically disabled and you will receive an in-app notification
Successful deliveries reset the consecutive-failure counter. Re-enable a disabled endpoint from Settings > Developer once your server is healthy again.

Testing

Use the “Test” button next to any webhook endpoint in the dashboard to send a test event. This sends a test.ping event to verify your endpoint is working.