Skip to content

Webhooks ​

Ticketeer can send HTTP POST requests to your server when ticket events occur. This allows you to build integrations that react to ticket activity in real time.

Webhooks are a premium feature.

Setup ​

  1. Navigate to Server Settings > Webhooks
  2. Click Create Webhook
  3. Enter a name, HTTPS URL, and select the events you want to receive
  4. Save — copy the secret shown (it won't be displayed again)

Authentication ​

Every webhook request includes an HMAC-SHA256 signature in the X-Ticketeer-Signature header:

X-Ticketeer-Signature: <hex_digest>

To verify a request, compute the HMAC-SHA256 of the raw request body using your webhook secret and compare it to the signature value.

Verification examples ​

Node.js

js
const crypto = require('crypto')

function verify(body, secret, signature) {
  const expected = crypto.createHmac('sha256', secret).update(body).digest('hex')
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))
}

Python

python
import hmac, hashlib

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

PHP

php
function verify(string $body, string $secret, string $signature): bool {
  $expected = hash_hmac('sha256', $body, $secret);
  return hash_equals($expected, $signature);
}

Request format ​

All webhook deliveries are HTTP POST requests with the following headers:

HeaderDescription
Content-Typeapplication/json
X-Ticketeer-SignatureHMAC-SHA256 signature
X-Ticketeer-EventEvent name (e.g. close, create)
User-AgentTicketeer-Webhook/1.0

Payload structure ​

json
{
  "event": "close",
  "guild_id": "123456789012345678",
  "ticket": {
    "id": "987654321098765432",
    "channel_id": "111222333444555666",
    "owner_id": "444555666777888999",
    "group_id": "555666777888999000",
    "status": "closed",
    "priority": 2,
    "name": "Support Request"
  },
  "user": {
    "id": "444555666777888999",
    "username": "example_user"
  },
  "timestamp": "2026-03-03T12:34:56+00:00"
}

The user field contains the user who triggered the event, or null for system-initiated events (e.g. expiry).

Events ​

EventDescription
createTicket created
openTicket reopened
closeTicket closed
deleteTicket deleted
lockTicket locked
unlockTicket unlocked
expiredTicket expired automatically
expireExpiry date set on ticket
eternalTicket marked as eternal (no expiry)
user_addedUser added to ticket
user_removedUser removed from ticket
assignTicket assigned to staff
unassignTicket unassigned from staff
priority_changedTicket priority changed
owner_changedTicket owner changed
name_setTicket name set
name_clearTicket name cleared
moveTicket moved to another group
rateTicket rated by user
feedbackFeedback submitted on ticket
transcript_createTranscript generated
private_thread_createPrivate notes thread created
private_thread_user_addUser added to private thread
private_thread_user_removeUser removed from private thread

Delivery behavior ​

  • Requests time out after 30 seconds
  • Failed deliveries are retried up to 3 times
  • After 10 consecutive failures, the webhook is automatically disabled
  • All delivery attempts are logged and viewable in the webhook's Logs page

Managing webhooks ​

From the webhooks page you can:

  • Edit — update name, URL, or subscribed events
  • Toggle — enable or disable a webhook without deleting it
  • Regenerate secret — generate a new signing secret (invalidates the old one)
  • Test — send a ping event to verify your endpoint is reachable
  • Delete — permanently remove the webhook and its logs

Responding to webhooks ​

Your endpoint should return a 2xx status code to indicate successful receipt. The response body is logged but not processed.

If your endpoint is slow or does heavy processing, return 200 immediately and handle the event asynchronously.