Skip to main content

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-TB-Signature header containing an HMAC-SHA256 signature of the request body.

Verifying in Node.js

import crypto from "crypto";

function verifyWebhookSignature(body, signature, secret) {
  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-tb-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 & Retries

  • Webhooks are delivered within seconds of the event
  • Your endpoint must respond with a 2xx status within 10 seconds
  • Failed deliveries are retried up to 3 times with exponential backoff
  • After 3 consecutive failures, the endpoint is marked as “failing”
  • After 10 consecutive failures, the endpoint is automatically disabled

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.