Documentation / Guides

Webhooks

We call your address the moment a match starts, a result is official or a new event is on the calendar.

Instead of asking the API every few minutes, add an address on your dashboard's Webhooks tab and we send you a POST when something happens. Webhooks are on the Live and Complete plans, up to 10 addresses an account.

Events

EventWhen it is sentdata holds
match.finishedA match has its official resultThe match, as GET /v1/matches/{id}
match.liveA match startsThe match, as GET /v1/matches/{id}
event.addedA new event is on the calendarThe event, as GET /v1/events/{id}

Choose the events each address gets. Only matches played in the last three days are sent, so nothing old ever arrives.

What a delivery looks like

JSON
{
  "id": "evt_6extq8sj",
  "type": "match.finished",
  "created_at": "2026-10-01T21:38:02Z",
  "data": { "id": "mt_qrvrky4e", "status": "finished", "score": { "a": 3, "b": 1 }, ... }
}

The headers say what it is: X-TTA-Event is the event type, X-TTA-Delivery a number for this delivery, and X-TTA-Signature proves it came from us.

Checking the signature

Every address has its own signing secret, shown on the dashboard. The signature header is t=<unix time>,v1=<hash>, where the hash is HMAC-SHA256 of the time, a full stop and the raw body. Recompute it and compare, and refuse anything older than five minutes:

PHP
$body = file_get_contents('php://input');
[$t, $v1] = sscanf($_SERVER['HTTP_X_TTA_SIGNATURE'], 't=%d,v1=%s');
$ok = hash_equals(hash_hmac('sha256', "$t.$body", getenv('TT_WEBHOOK_SECRET')), $v1)
      && abs(time() - $t) < 300;
Python
import hmac, hashlib, time
t, v1 = (p.split("=", 1)[1] for p in request.headers["X-TTA-Signature"].split(","))
mac = hmac.new(SECRET.encode(), f"{t}.".encode() + request.get_data(), hashlib.sha256).hexdigest()
ok = hmac.compare_digest(mac, v1) and abs(time.time() - int(t)) < 300

Answering, and retries

  • Answer with any 2xx within 10 seconds. Do the slow work afterwards.
  • Anything else, or no answer, and we send it again: 8 tries over about 3 days (after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, 1 day and 2 days).
  • A 4xx (other than 408, 409, 425 or 429) means "do not send this again", and we stop for that delivery.
  • After 20 failures in a row we turn the address off and email you. Turn it back on from the dashboard once it answers again.
  • The same event can arrive more than once. Use its id to skip ones you have already handled.

Trying it

Press Send a test next to an address: we send a real match.finished for the most recent result straight away, and the dashboard shows what your address answered. Addresses must be https on the standard port, and never a private or local network.