Documentation
Everything you need to get a server running, plus the reference for templates and permissions.
Getting started
1. Sign in with Discord
HC Tickets reads your Discord guild list and shows the servers where you have Manage Server or Administrator. Nothing else is visible to you, and the check is repeated on every request rather than trusted from the browser.
2. Invite the bot
From the server picker, choose a server the bot has not joined and use Invite. The bot needs Manage Channels, Manage Roles, View Channel, Send Messages, Manage Messages, Embed Links, Attach Files and Read Message History.
3. Configure the basics
Under Configuration → General, pick the category new tickets are created in and set your ticket naming template. Under Permissions, choose which roles count as support staff.
4. Build and deploy a panel
Panels → New panel. Design the embed, add at least one button, choose the channel, then Save and Deploy. The preview shows exactly what Discord will render.
Variables
Usable in welcome messages, panel embeds, ticket naming templates and custom command responses. An unknown variable is left in place rather than blanked, so a typo is visible instead of silent.
| Variable | Description |
|---|---|
| {user.id} | Discord ID of the acting user |
| {user.name} | Display name, falling back to username |
| {user.username} | Raw Discord username |
| {user.mention} | Clickable @mention |
| {user.avatar} | Avatar image URL |
| {server.id} | Discord server ID |
| {server.name} | Server name |
| {server.icon} | Server icon URL |
| {server.member_count} | Total members |
| {ticket.id} | Internal ticket UUID |
| {ticket.number} | Per-server ticket number |
| {ticket.name} | Ticket channel name |
| {ticket.owner} | Mention of the ticket opener |
| {ticket.owner_id} | Discord ID of the opener |
| {ticket.owner_name} | Username of the opener |
| {ticket.channel} | Clickable channel link |
| {ticket.panel} | Name of the panel used |
| {ticket.created_at} | Creation time, localized |
| {ticket.created_relative} | Creation time, relative |
| {claim.user} | Mention of the claiming staff member |
| {claim.user_id} | Discord ID of the claimer |
| {claim.user_name} | Username of the claimer |
| {form.<field>} | Answer to a form field, by its variable name |
Reference
Ticket naming
The naming template runs through the variable engine and is then sanitised for Discord: lowercased, accents reduced to ASCII, illegal characters replaced with hyphens, and truncated to 100 characters. ticket-{ticket.number} produces ticket-42; {user.name}-support produces ada-support.
Panel inheritance
Each button can override the server defaults for category, naming, per-user limit, support roles, claiming, transcripts and the welcome message. Leaving a field unset inherits the server value. Setting it to an empty list is a real override meaning 'nobody', not 'inherit'.
Limits
Per-user and server-wide ticket limits both treat 0 as unlimited. Open, claimed and reopened tickets count against a limit; closed and deleted ones do not.
Transcripts
On close, the bot collects the full channel history and writes a canonical JSON document to private storage, then renders HTML from it. Both are reachable only through short-lived signed URLs issued after an authorization check. Because the JSON is the source, the HTML can be regenerated at any time.
Permissions model
Support roles can view, claim, close, reopen, rename and manage members on tickets. The ticket owner can view, close, add users and request a transcript. Admin roles can do everything, including taking over another staff member's claim. Blacklisted roles cannot open tickets at all, and that check runs before every other rule.
Ready to configure a server? Open the dashboard.