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
| Event | When it is sent | data holds |
|---|---|---|
match.finished | A match has its official result | The match, as GET /v1/matches/{id} |
match.live | A match starts | The match, as GET /v1/matches/{id} |
event.added | A new event is on the calendar | The 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
{
"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:
$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;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)) < 300Answering, 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
idto 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.