Ticket System
A full support platform inside Discord — departments, conditional forms, SLA timers, staff routing, automation, satisfaction ratings and searchable transcripts.
Four ideas. Everything else on this page is a setting on one of them.
Departments
A support team — Billing, Appeals, Bug Reports. Each owns its own staff, response targets, form, channel category and access rules. This is what replaced flat “categories”.
Forms
The questions asked before a ticket opens. Questions can branch on earlier answers, so a member only ever sees what applies to them.
Panels
The message members click. Buttons, a dropdown, or both — posted to any channel, and editable in place without losing its position.
Staff
People, not just roles. Each has availability, a ticket cap, the departments they cover, and a performance record. Roles still control who can see a ticket.
What a member actually experiences
Steps that are not configured are skipped silently. With no departments, no form and no knowledge base, clicking the panel opens a channel immediately — the simple setup still works.
Everything lives on Dashboard → Tickets, which is split into nine tabs.
-
1Create a department
Departments → + New department. At minimum give it a name and a support role — the role decides who can see tickets opened under it. Pick a Discord category to hold the channels.
One department is enough to start. Members never see a pointless one-option dropdown — with a single department, the panel button opens it directly.
-
2Add staff
Staff → + Add staff. Pick a member or a whole role — the same picker the Permissions page uses, because it writes the same thing. Add a role and everyone in it works tickets, including people who join it later.
This is the Ticket System permission: grant it here or in the Permission Manager, and both pages show it. People are also added automatically the first time they claim or reply to a ticket.
-
3Build a panel and deploy it
Panels → + New panel, then Deploy and choose a channel. Leave the department list empty to show every visible department automatically, so a department added later appears without touching the panel.
-
4Optional: a form, an SLA, some automation
Add these once tickets are flowing and you can see what is actually slow or repetitive. None of them are required.
A ticket is always in exactly one of these. They exist so “open” tickets can be told apart from tickets that are actually waiting on you.
| State | Meaning | Response timer |
|---|---|---|
| 🟢 Open | Just opened, nobody has replied yet. | Running |
| 🟡 Waiting for Staff | The member replied — it is your turn. | Running |
| 🔵 Waiting for User | Staff replied — waiting on the member. | Paused |
| ⏸️ On Hold | Deliberately parked; blocked on something outside the conversation. | Paused |
| ⚪ Closed | Finished. The transcript is kept. | Stopped |
The waiting states move on their own. When a staff member replies, the ticket becomes Waiting for User; when the member replies, it goes back to Waiting for Staff. Nobody has to remember to set it.
Priority
Four levels, and they do more than colour a row: each one scales your response targets automatically. You configure one set of numbers per department and every priority derives from it.
| Priority | Target multiplier | With a 60-minute first-response target |
|---|---|---|
| 🔥 Urgent | ×0.25 | 15 minutes |
| ⬆️ High | ×0.5 | 30 minutes |
| ➖ Normal | ×1 | 60 minutes |
| ⬇️ Low | ×2 | 2 hours |
Closing
Staff pick a reason when they close; members just confirm. The reason is not decoration — it decides whether the member is asked to rate their experience, and it feeds your resolution rate.
| Reason | Counts as resolved | Asks for a rating |
|---|---|---|
| ✅ Resolved | Yes | Yes |
| 💬 Question Answered | Yes | Yes |
| 👤 Closed by User | Yes | Yes |
| 🔁 Duplicate | No | No |
| 🕓 No Response | No | No |
| 🚫 Invalid / Not an Issue | No | No |
| 🗑️ Spam | No | No |
| 🤖 Auto-Closed (Inactive) | No | No |
Nobody is asked to rate the support they received on a spam ticket they did not open — that is why the middle column and the right one differ.
Reopening
A closed ticket can be reopened within a window you set (48 hours by default; set it to 0 to disable). Reopening restores the member's ability to write and restarts the response timer. Past the window, they open a new ticket instead.
Everything a support team needs to work differently from the others.
| Setting | What it does |
|---|---|
| Support roles | Who can see and answer these tickets. Members of these roles get access to every channel opened here. |
| Ticket category | Where this department's ticket channels are created. Leave it blank and the department uses the Default ticket category from Settings. |
| Archive category | Where this department's channels are moved read-only when a ticket is archived. Leave it blank to use the server default. Whether a closed ticket is archived is the close action. |
| Transcript channel | Where this department's transcripts are posted. Leave it blank to use the Default transcript channel from Settings. |
| Form | The questions asked before the channel opens. Optional. |
| Assignment | Manual, round robin, least busy, or random. See routing. |
| Default priority | What new tickets start at. |
| Welcome message | Posted at the top of every ticket here. Supports {user} and {number}. |
| Channel naming | A pattern like billing-{number}. Tokens: {number} {username} {department} {priority}. |
| Required roles | A member must hold at least one to open here. Departments they cannot use are hidden from them rather than failing on click. |
| Blocked roles | Holding any of these refuses the ticket. |
| Max open per member | A per-department cap, on top of the server-wide one. |
| Log channel override | Send this department's close logs somewhere specific. Leave empty to use the Logging page. |
| SLA & escalation | Response targets and who to page when they slip. See SLA. |
The questions a department asks before it opens a ticket.
Forms are their own module now — they used to be a tab of this page, which meant the only thing a set of questions could do was open a support ticket. A department still asks one: pick it under Departments → Form, and the member answers it before their channel is created, exactly as before.
Read the Forms documentation → — the 15 field types, conditional questions, how a form splits into steps, panels, submission limits and the review queue.
Off by default. Turn it on per department when you want to know — and be told — that something is slipping.
| Target | Measures | Default |
|---|---|---|
| First response | Ticket opened → first staff message | 60 minutes |
| Next response | Member replies → next staff message | 2 hours |
| Resolution | Ticket opened → closed | 24 hours |
What happens as a target approaches
At-risk and breach alerts are posted in the ticket and ping the assignee — not the whole support role, because an alert that pings everyone every time is an alert people turn off. Both also fire automation triggers, so you can decide what else should happen.
Escalation chain
Up to five rungs per department, each firing once, in time order, while a first response is still outstanding. A rung can notify a role or a person, raise the priority, or both.
Business hours
Set a working week and a timezone per department. Daylight saving is handled properly — targets do not silently shift by an hour twice a year.
Who picks up a ticket, and how many they hold at once.
| Strategy | Behaviour |
|---|---|
| Manual | Nobody is assigned; staff claim from the queue. The classic behaviour, and the default. |
| Round robin | Handed out in turn to whoever is available and under their cap. |
| Least busy | Goes to whoever holds the fewest open tickets. Ties break on who was assigned longest ago. |
| Random | Picked uniformly among available, under-cap staff. |
Automatic assignment only ever picks someone who can actually take it — marked available, in that department, under their cap, still holding a support role, and still holding the Ticket System permission. A staff record outlives both the role that granted access and the permission behind it, so those last two checks run against the live server and the live permissions, never the stored record. If nobody qualifies, the ticket simply waits in the queue for someone to claim. That is a normal outcome, not a failure.
Staff and permissions are one list
The Staff tab and the Permission Manager's Ticket System module are the same setting seen from two pages. The Staff tab holds both subjects in one section — Roles and Members, added from the one Add staff button — and either writes that same grant. Grant it in either place and the other updates: add a role on the Staff tab and its members appear on the rota; grant the module in the Permission Manager and they appear there too. Take it away and they stop being assigned tickets immediately.
Availability
Staff set their own with /ticket staff, or you set it on the dashboard.
| Status | Gets new tickets |
|---|---|
| 🟢 Available | Yes |
| 🟠 Busy | No — keeps their current tickets |
| 🟡 Away | No |
| ⚫ Offline | No |
Ticket caps
Give someone a maximum and they stop receiving new tickets at it — and the Claim button refuses too. A cap that routing honours but the button ignores is not a cap.
Performance
Tickets handled and closed, average first response, average resolution, and average satisfaction — per person, with a 7-day, 30-day and lifetime leaderboard. These are the numbers a lead manages against, shown side by side rather than folded into one score nobody can audit.
When something happens → check some conditions → do things. The same shape as Discord's own AutoMod.
Triggers
| Group | Triggers |
|---|---|
| Lifecycle | Ticket opened · closed · reopened · claimed · unclaimed · transferred |
| Messages | User replied · Staff replied · First staff response |
| Form | Form submitted |
| Changes | Tag added · Status changed · Priority changed · Internal note added · Member added |
| Timing | SLA nearly breached · SLA breached · No activity for… |
| Feedback | Rating submitted |
Conditions
Department · priority · status · tag · any form answer · opener has role · available staff count · open ticket count · ticket age · message count · within business hours · opener's first ticket · opener's lifetime tickets · rating given · is assigned.
Match all of them or any of them. Priority comparisons use severity order, so “priority is at least High” correctly includes Urgent.
Actions
| Group | Actions |
|---|---|
| Communicate | Send message · Send embed · DM a user · Notify staff · Add internal note |
| The ticket | Set status · Set priority · Add tag · Remove tag · Assign staff · Move department · Escalate · Close |
| The member | Add role · Remove role |
| The channel | Rename · Move category · Lock · Create staff thread |
| Timing | Pause SLA · Resume SLA · Wait (minutes to a week) |
| Integration | Call a webhook |
| AI | Summarize · Auto-categorize · Suggest a reply |
Test it before you trust it
| Mode | What runs |
|---|---|
| Enforce | Everything, for real. |
| Test | Everything except destructive actions (closing, roles, locking). Logs what it would have done. |
| Simulate | Evaluates and logs only. Nothing happens. |
| Disabled | Not evaluated at all. |
Test and Simulate run the same code path as Enforce, which is what makes the preview trustworthy. Each workflow also shows how many times it has run and how often it matched.
Worth knowing
- A Wait survives a restart. “Remind after 24 hours, then close after 48” genuinely works — the pending half is stored, not held in memory.
- One failing action does not stop the rest. A workflow that could not add a role still sends its message.
- A cooldown stops a chatty trigger like User replied re-running on every message.
- Message text supports placeholders —
{user}{staff}{ticket}{department}{priority}{status}{topic}{server}, and{form.your_question}for any answer. - Pings are scoped. Typing
@everyoneinto a workflow message does not ping everyone — a message only mentions who the action was told to.
With no workflows yet, the page offers four ready-made starters — greet new tickets, nudge-then-close on silence, page a manager on a breach, and thank a five-star rating. They are ordinary workflows you can edit or delete.
The cheapest ticket is the one nobody had to open.
Write short articles answering the questions your staff repeat most. When a member picks a department, Azra offers the relevant ones before any form. They read one and either say it solved their problem — no ticket is created — or continue to open one.
| Field | Notes |
|---|---|
| Title | What the member sees in the list. Phrase it as the answer, not the topic. |
| Summary | One line, shown under the title. |
| Article | The full answer. Discord formatting works. |
| Keywords | The phrases members use, not the ones you do. These carry the most weight in matching. |
| Department | Limit an article to one team, or leave it available to all. |
Turn it on with Settings → Suggest knowledge-base articles. If nothing matches what the member needs, they are shown nothing rather than an unrelated article — a bad suggestion reads as the bot not having understood them.
Every action is available in three places: buttons in the channel, the /ticket command, and the dashboard.
Buttons in the channel
Every ticket opens with a control panel: Close · Claim/Unclaim · Status · Priority · Add · Remove · Note · Transfer. It updates itself as the ticket changes.
Commands
Every option is autocompleted — start typing and Azra offers the valid values, so there is nothing to memorise. Members do not need these commands: everything available to them is a button in their own ticket.
Internal notes
Staff-only, invisible to the member, kept with the ticket forever and included in its history. Use them for “refund issued, waiting on finance” — the context the next person needs.
Saved replies
Reusable answers with a shortcut. /ticket reply refund-policy sends it with {user}, {ticket} and the rest filled in. You can restrict one to a single department.
Tags
Label tickets for filtering, reporting and automation conditions. Tags appear in the queue, in analytics, and can be added automatically by a workflow.
Nine tabs at Dashboard → Tickets.
| Tab | What it is for |
|---|---|
| Dashboard | Open tickets, what is waiting on whom, closed today, SLA at-risk and breached, staff availability, average response and resolution, satisfaction, peak hours, and a live activity feed. |
| Tickets | The queue. Filter by status, priority, department, tag, assignee, SLA breach or text; sort by urgency, age or staleness. Click any row for the full ticket. |
| Departments | Create and configure teams, including their SLA and escalation chain. |
| Forms | The form designer, with a live view of the steps a member will walk through. |
| Automation | Build workflows; see how often each has run and matched. |
| Panels | Build and deploy the messages members click. |
| Knowledge | Write help articles and see how many tickets each has deflected. |
| Staff | Availability, caps, departments and the performance leaderboard. |
| Analytics | Volume, response times, satisfaction trend, by department, by priority, how tickets ended, a day-by-hour heatmap, workload, and the transcript centre. |
| Settings | Naming, limits, cooldowns, ratings, auto-close, archiving, tags, saved replies, webhooks and the blacklist. |
Opening a ticket from the dashboard
Clicking a ticket shows everything about it — form answers, response timers, internal notes, full history, the rating — and lets you close, claim, assign, transfer, retag, or change status and priority without opening Discord.
Search
The search box at the top of the page looks inside tickets, form answers, internal notes and transcript text at once. Finding “that ticket about the failed invoice from March” is a search, not an archaeology expedition.
Saved automatically when a ticket closes.
The member gets a private link by DM. Staff can browse every transcript in the Analytics tab, search inside them, and export in four formats:
| Format | Good for |
|---|---|
| HTML | Reading. Discord-styled, with images inline and names resolved. |
| Plain text | Attaching to an email or a case file. |
| Markdown | Pasting into a wiki or an issue tracker. |
| JSON | Feeding another system. |
Transcripts record who said what and when, edits, attachments, embeds and stickers, and resolve mentions to names — so an archive read months later still makes sense after the people involved have left.
Closing records the outcome. What happens to the channel is a second, separate decision.
When a staff member closes a ticket, Azra asks what should happen to the channel — right there in the channel, so any staff member can answer and the choice survives a restart:
| Choice | What happens |
|---|---|
| 📦 Archive | The channel is moved to the archive category, renamed closed-0001 and made read-only for the member. It is then deleted automatically after 24 hours — change that to any number of hours in Settings, or set it to 0 to keep archives forever. |
| 📄 Transcript & delete | The transcript is posted to the transcript channel, then the ticket channel is deleted. |
Settings → When a ticket is closed chooses the default: Always archive, Always create a transcript and delete, or Ask staff every time (the default).
Both the archive category and the transcript channel are set in Settings and can be overridden per department — so Billing transcripts can land in one channel and Appeals transcripts in another, while everything else follows the default. The prompt in the channel always names the resolved destination, so what the buttons say is what actually happens.
Ask the member how it went, and know which of your team people are happiest with.
When a ticket is closed for a reason that warrants it, the member's closing DM carries star buttons. One rating per ticket, credited to whoever handled it. Ratings appear on the dashboard overall, per staff member, per department, and as a trend over time.
Turn it off entirely in Settings, or change the scale. Spam, duplicate and invalid closures never ask — asking would only poison the average.
| Control | What it does |
|---|---|
| Open tickets per type | How many of one department a member may have open at once — 1 by default, so somebody can hold one Bug Report and one Suggestion, but never two Bug Reports. A department can set its own cap. |
| Open tickets in total | How many they may have across every department combined — 3 by default. Both limits apply, so a member with three open tickets waits for one to close even if the fourth would be a fresh type. |
| Cooldown | A wait between one ticket and the next. |
| Blacklist | Bar a member from opening tickets, permanently or until a date. They are told why. |
| Required / blocked roles | Per department — who may open one at all. |
| Auto-close on inactivity | Close tickets nobody has touched for N hours. |
| Inactivity reminder | Nudge first, at a separate threshold. Fires an automation trigger, so you decide what the nudge says and does. |
Send ticket events to anything that accepts an HTTPS request.
Subscribe an endpoint in Settings → Outbound webhooks and pick the events you want. Azra POSTs signed JSON when they happen — enough to drive Zapier, Make, n8n, a Slack relay or your own service without a vendor-specific connector.
| Events |
|---|
| Ticket opened · closed · reopened · claimed · assigned · transferred · status changed · priority changed · tagged · note added · SLA at risk · SLA breached · rating submitted · form submitted |
Every delivery carries X-Azra-Signature, an HMAC-SHA256 over the timestamp and body using a secret shown to you once at creation. Verify it and you know the request genuinely came from Azra and has not been replayed. Endpoints that keep failing are disabled automatically, with the last error shown on the dashboard.
These are for external systems. For Discord logging, use the Logging page instead.
When enabled, AI can summarize a long ticket for a handover, suggest a category and priority for a new one, draft a reply, detect the language, and flag spam or abuse.
A suggested reply is always posted for staff to read and send themselves — it is never sent to the member as though it were an answer. That is deliberate and is not a setting.
Ticket capabilities are granted through the Permission Manager, separately from each other.
| Capability | Covers |
|---|---|
| Claim Ticket | Claim, unclaim, assign, close, send saved replies, set your own availability |
| Change Status / Priority | Move a ticket through the lifecycle and change its urgency |
| Transfer Between Departments | Reroute a ticket to another team |
| Add Internal Note | Write staff-only notes |
| Add / Remove Members | Bring people into a ticket, and rename it |
They are separate because they are different levels of trust — “may answer tickets” and “may reroute the queue” are routinely given to different people. Granting one never grants another, and it works the same whether the person uses a button, a command or the dashboard.
Do I have to use departments, forms and SLAs?
No. One department with a support role is a complete, working ticket system. Everything else is opt-in.
What happens to my existing tickets and categories?
Categories become departments automatically, numbering continues unbroken, closed tickets keep their transcripts, and panels already posted in your server keep working.
Will a ticket be deleted when it closes?
Only if you choose it. By default staff are asked — archive the channel, or save the transcript and delete it. The transcript is saved either way.
How long are archived tickets kept?
24 hours by default, then the channel is deleted automatically. Change it to any number of hours in Settings → Delete archived tickets after, or set 0 to keep them forever. Tickets archived before this setting existed are never deleted by it.
Can a member reopen a ticket?
Within the window you set — 48 hours by default, and it can be switched off.
Why is my automation not firing?
Check its mode is Enforce (Test skips destructive actions, Simulate does nothing), that its conditions actually match, and that a cooldown is not suppressing it. Every workflow shows its run and match counts, which usually answers this in one glance.
Why did nobody get assigned automatically?
The department's assignment is probably Manual, which is the default. Otherwise nobody was eligible — available, in that department, under their cap, and still holding a support role.
Why can I not delete this department?
It still has open tickets. Close or transfer them first.
Where do ticket logs go?
To your central Logging destination, branded like every other Azra log. A department can override this with its own channel.