A customer opens a ticket through a Discord panel. Depending on the panel mode, TicketNova creates a private Discord channel or a portal-only ticket. The customer can then follow the same case in the Customer Portal.
What TicketNova is
TicketNova is a public, hosted Discord support platform. Members start support from a Ticket Panel in Discord. Staff manage cases from the web dashboard and, when configured, customers can continue the conversation in the Customer Portal. The bot, website, Discord integration and database work together as one system.
Every Discord server has its own workspace with support queues, panels, permissions, work hours, automation, integrations and audit history. Data is always scoped to the selected Discord server.
Most administration is performed in the website. Discord commands exist for several staff actions, but normal configuration does not depend on commands.
TicketNova platform administrators can manage connected servers, limits, custom-domain approvals, notifications, incidents, migrations, sessions and platform reliability from the Admin Center.
Normal Discord server owners do not need Node.js, MySQL, a VPS, Discord OAuth credentials or a bot token. Those technical deployment settings are only relevant to the operator of the TicketNova platform.
Getting started
The normal setup flow is designed to move from Discord authorization to a usable support desk without requiring technical knowledge.
Use the TicketNova login button. Discord identifies your account and the servers you can manage.
Choose the server where TicketNova should be installed or managed. Only servers for which your Discord permissions allow management are offered.
If the bot is not in the server yet, complete Discord's authorization screen. TicketNova then detects the new guild and prepares its server-specific settings.
Choose your support role, ticket category, logging channels, review channel, timezone and basic ticket behaviour. Optional steps can be skipped.
Build at least one panel and publish it in a Discord channel. This is the normal customer entry point for creating tickets.
Open a test ticket, reply from the dashboard, close it as staff, check the transcript and verify the Customer Portal/custom-domain flow before announcing the system to members.
Setup Wizard
The Setup Wizard is a guided first configuration. Skipping a step is safe: all settings remain available later from the normal sidebar pages.
Set the Discord role that represents support staff and the category in which Discord-channel tickets should be created.
Configure the channels used for ticket events, transcript notices and review publishing. TicketNova requires permission to view and send messages in those channels.
Choose whether dashboard replies use the TicketNova bot identity or a staff webhook identity and configure the maximum number of open tickets per customer.
Select the server timezone and the opening-hours/SLA foundation used by panels and response-time calculations.
Configure a Support Role, ticket category and Ticket Log channel first. After that, create a test panel and verify permissions before configuring advanced automation.
Dashboard overview
The Overview page summarizes the current Discord server. TicketNova does not use a global mixed ticket list inside a guild dashboard: server-specific routes and queries always carry the selected guild ID.
See active workload, open/closed counts, priority work and current support activity without storing a separate analytics-history system.
Ticket lists and conversations use live updates so staff do not have to continuously refresh pages while working.
Switching servers changes the complete workspace context. Permissions, panels, tags, tickets, reviews and settings from another guild are not reused.
Only pages allowed by the user's TicketNova dashboard permissions are shown. Platform administrators additionally receive an Admin Center link.
Ticket Panels
Ticket Panels are Discord messages with configurable buttons. Each button can represent a different support reason and can ask its own questions before the ticket is created.
Set the panel title, body text, thumbnail and large image so the message matches the server's support branding.
Create buttons for General Support, Reports, Billing, Applications, Appeals or any custom use case. Button labels and behaviour are configured per panel.
Attach questions to a panel button so customers provide the required context before TicketNova creates the case.
A button can create a private Discord ticket channel, or create the ticket without a Discord channel and continue it through the Customer Portal.
Publish the configured panel to the Discord channel where members should request support. Existing published panels can be updated.
Panel content can reflect opening hours, maintenance and service availability. Invalid or unavailable actions can be disabled automatically.
How tickets move through TicketNova
A ticket record remains the central source of truth even when its Discord channel is removed. Closing a ticket removes the Discord channel when applicable, but keeps the case, messages and transcript available for staff and the portal.
TicketNova stores the customer, ticket type, answers, priority, panel source and optional Discord channel ID.
Departments, tags, custom status, priority, SLA and automation can be applied. Auto-assignment can select a staff member when configured.
Staff reply, claim/assign, add internal notes, watch the ticket, request approvals, schedule callbacks, link tickets and update workflow state.
Closing is a staff action. Customers in the Customer Portal cannot close or reopen a ticket. For Discord tickets, the channel is removed while the stored case remains available.
The retained conversation can be viewed as a web transcript. If reviews are configured, the customer can submit feedback after the support interaction.
TicketNova intentionally retains closed ticket records. Permanent cleanup is handled through authorized data-retention/cleanup tools, not by giving customers a delete button.
Working inside a ticket
The ticket detail page combines the customer conversation with support-only controls. Sections are collapsible so the conversation stays usable even when a ticket has a lot of metadata.
Staff can reply from the dashboard. Depending on the ticket mode, messages are delivered to Discord and/or the Customer Portal while staying in the ticket history.
Claim a ticket for yourself or assign it to an eligible support member. TicketNova checks support access before allowing assignment.
Authorized staff can select Discord members and update ticket participation. Channel permissions are updated for Discord-channel tickets.
Use priority and organization fields to make queues meaningful. Departments can also affect SLA rules and automatic assignment.
Internal notes are for the support team and are not customer replies. Customer history and answers can be reviewed without leaving the case.
Operations tools can escalate a case, merge related tickets, link cases, add reminders or snooze work until a later time.
Ticket Questions, quick replies & answers
TicketNova separates customer intake questions from staff response helpers. This lets you standardize both the information customers provide and the answers staff send.
Create saved server-level questions and reuse them when staff need to collect structured information from a customer.
Panel button questions are asked before the ticket is created, so the first staff view already contains the customer's answers.
Save frequently used support responses so staff can insert consistent text instead of rewriting the same answer.
The Support Suite provides response snippets and ticket templates for more structured workflows and case updates.
Operations Center
The Operations Center is for day-to-day queue control. It focuses on tickets that need attention rather than on configuration.
Surfaces urgent/high-priority tickets so important requests are less likely to be buried.
Shows tickets with no owner and tickets approaching or exceeding their deadlines.
Provides a focused list of cases that were escalated for senior attention.
Staff can follow specific open cases and return to them from a dedicated list.
Create reusable server-specific labels for filtering, routing and human triage.
Advanced service-desk features
The Support Suite groups the larger operational modules that turn a basic ticket system into a service desk. Access is controlled by dashboard capabilities.
Control whether support is available and coordinate maintenance/availability behaviour with panels and workflow automation.
Review service performance based on ticket data without a separate long-term analytics-history subsystem.
Create scheduled summaries that are delivered to configured Discord channels.
Publish incidents and help articles, and process customer privacy requests created through portal tools.
Create outbound webhooks and server-specific REST API keys for external systems.
Export operational data, save configuration backups and run configuration diagnostics.
Departments, staff availability, shifts & leave
Departments organize support by team or subject. They can be matched to ticket types, Discord roles/categories and automatic assignment rules.
A department can have a name, description, color, Discord role/category relationship and optional ticket-type match.
Round Robin rotates staff based on previous assignment. Least Open prefers eligible members with fewer current open tickets.
Staff availability preferences affect assignment and operational visibility.
Define recurring staff availability and temporary time off so the support desk has more accurate staffing context.
Work Hours, response time & SLA policies
Work Hours define when the support desk is considered open. SLA policies add first-response and resolution targets and can be matched by department, ticket type or priority.
Opening hours and exceptions must be interpreted in the server's configured timezone.
Set the normal open/closed schedule for each weekday.
Use exceptions for holidays, special closures or temporary opening times without changing the recurring schedule.
Set first-response, resolution and warning thresholds. Ticket snapshots keep the applicable targets attached to the case.
Opening-hours and maintenance information can be reflected in Discord panels so members see whether support is currently available before opening a request.
Notification Center
Staff notifications are stored per guild and per user. The dashboard can show assignment, reminder, escalation, mention, SLA and review-related notifications according to personal preferences.
New items appear in the dashboard notification surface and can be marked as read.
Each staff member can enable or disable supported notification categories for their own account.
When enabled and permitted by the browser, TicketNova can surface supported events beyond the visible page.
Platform administrators have their own notification page for events such as new custom-domain requests. Those notifications can be deleted individually or in bulk.
Incidents and Knowledge Base
TicketNova can publish service information alongside support tickets so customers can find answers or understand a known incident before asking staff for an update.
Create incidents with service status and updates. Incidents can be linked to affected tickets and surfaced in the Customer Portal.
Create server-specific help content. Published articles are available to customers in the portal, while drafts remain for staff.
Server announcements can be shown through the portal and related surfaces to communicate current information.
When a known issue or help article already answers the question, staff can direct customers to the existing content instead of repeating the same explanation.
Snippets, templates, statuses, automation & approvals
These tools help teams handle recurring situations consistently while keeping human control over important support decisions.
Store common answers by category and insert them when replying.
Apply predefined ticket properties/content so recurring workflows start in a consistent state.
Create extra status labels and positions to describe the support process in language that matches the community.
Automation can run supported actions when matching ticket events occur, reducing repetitive manual work.
Use ticket approvals when an action requires explicit review from another staff member.
Save ticket views for personal or shared use so staff can return to the same queue definition quickly.
Reviews & review moderation
Reviews are tied to real TicketNova tickets. Server owners can configure the review channel and additional review questions, while authorized staff can moderate feedback in the Support Suite.
Choose where review messages should be published. If no review channel is configured, publishing features that depend on it are unavailable.
Add additional review questions to collect more useful information than a single score/comment.
Authorized staff can review submitted feedback and manage how it is used by the server.
TicketNova can use approved ticket reviews on public surfaces while keeping the source tied to the originating guild.
Customer Portal
The Customer Portal is for customers who already opened a TicketNova ticket from Discord. It is not a public website ticket form: new tickets still begin from a Discord Ticket Panel.
The signed-in Discord account is used to load tickets that belong to that customer and the correct guild. Filters do not fall back to tickets from another server.
Customers can read staff replies and answer from the portal. Supported files remain associated with the ticket conversation.
Customers cannot close, reopen or permanently delete their tickets. Those status changes are intentionally controlled by authorized support staff.
Where enabled, a ticket owner can create a limited participant invitation. The invited person must authenticate and meet the guild membership checks.
Customers can use server-specific help content and current service information from the same portal.
The portal can expose personal data export/request tools. Staff processes those requests from the Support Suite Privacy Center.
When a customer or staff member signs out on the unified custom domain, TicketNova returns to the root Landing Page on that same hostname. If no approved custom domain exists, it safely falls back to the main TicketNova site.
Staff Portal and personal workspace
The unified custom domain also provides the staff entrance. Authorized dashboard users can use the same hostname as customers, while the personal Workspace still aggregates work relevant to the signed-in staff member across accessible TicketNova servers.
The approved unified hostname exposes /staff as the staff entry point and routes authorized members into that server's dashboard while Discord OAuth continues through the central TicketNova callback.
The personal workspace can combine assignments, callbacks, reminders/tasks, handovers, notifications, shifts, favorites and recently used servers.
Using the Staff Portal route on the unified custom domain does not bypass access checks. The user must still be authorized for the relevant Discord server and dashboard capabilities.
Signing out from either the Customer or Staff area returns to the Landing Page at the root of the same unified custom hostname.
One custom domain for every portal surface
From v5.6.0 each Discord server has one unified custom hostname. The same approved domain serves the public Landing Page, Customer Portal and Staff Portal using fixed routes. The old short-path concept such as /voorbeeld remains removed.
| Type | Purpose | Example |
|---|---|---|
| Landing | Public branded support landing page. | support.example.nl/ |
| Customer | Complete Customer Portal for authenticated ticket owners. | support.example.nl/portal |
| Staff | Authorized staff dashboard entrance for that Discord server. | support.example.nl/staff |
Approval states
A new or changed hostname is disabled until a TicketNova platform administrator approves it.
The hostname is allowed to serve all three surfaces: Landing, Customer Portal and Staff Portal.
Routing is disabled immediately. A suspension reason can be stored. Only the Admin Center can restore approval.
Routing remains disabled. If the server owner submits the hostname again, the request returns to Pending for a new review.
When a new custom domain is submitted, TicketNova creates a platform-admin notification. Platform administrators can review the request from the Admin Center, then Approve, return to Pending, Suspend, Reject or Delete the domain.
From v5.5.4 a permanent Delete removes the managed nginx hostname route and the exact Let's Encrypt certificate/renewal lineage through the Automatic Domain Gateway. Cleanup is stored in a retry queue and is skipped safely if the hostname is added again before cleanup runs. Suspend deliberately keeps SSL so the domain can be restored quickly; Reject removes the managed route but keeps the certificate.
DNS, SSL and VPS routing verification
TicketNova checks more than DNS. From v5.4.8 the Admin Center verifies whether the request actually reaches TicketNova on the shared VPS. This catches the common case where DNS is correct but nginx/Caddy/another hosting virtual host sends the custom hostname to a completely different website.
TicketNova compares the resolved IPv4/IPv6 address with the Public Target configured by the platform administrator.
If the hostname is a CNAME, TicketNova shows the alias and still follows resolution to verify whether it ends at the Public Target.
After DNS is correct, TicketNova connects to the Public Target on port 443 with the requested hostname as SNI and records whether the certificate is valid.
TicketNova requests /.well-known/ticketnova-domain-check on the custom hostname. If AMP Pulse, a default nginx site or another application answers, the card reports ROUTE Mismatch.
Verify & approve performs a fresh check and stays disabled until the hostname resolves correctly, HTTPS is valid when required and the Host header reaches TicketNova.
Custom Page Builder
The Custom Domains page contains a separate Custom Page tab. Changes made there control the real Landing Page rendered on the approved unified custom hostname, not a disconnected mock page.
Choose the main page composition and comfortable/compact density.
Configure accent, background, surface, text and muted colors plus logo, background-image and hero-image URLs.
Customize browser title, server label, hero title/highlight, introduction and primary/secondary button labels.
Edit proof items, six feature cards and three How It Works steps, including their icons, labels, titles and text.
Navigation, system status, member count, portal preview, trust row, proof, features, How It Works, final CTA and footer can be shown or hidden.
Use the live preview to check the page before visitors see the updated design.
CUSTOMER CARE · POWERED BY TICKETNOVA cannot be changed through the editor, old stored configuration or a forged request. The application normalizes it server-side to the fixed TicketNova value.
Direct hosting, custom-domain gateway and Discord OAuth
Cloudflare is not required. Normal A/AAAA records can point every customer hostname to the same Public Target. Remember that DNS only selects the VPS IP; the VPS frontend still decides which application receives that hostname.
If a custom hostname opens AMP Pulse or another site on the same VPS, TicketNova never received the request. Configure the frontend webserver so unmatched customer hostnames go to TicketNova while normal sites keep explicit hostnames.
Recommended automatic setup
Create an A record (IPv4) or AAAA record (IPv6) and point it to the Public Target shown by TicketNova.
Run sudo bash deploy/install-auto-domain-gateway.sh on the VPS. It installs the TicketNova gateway agent that can create nginx vhosts and Let's Encrypt certificates automatically.
TicketNova polls Pending/Approved domains. As soon as A/AAAA resolves to Public Target, the agent creates an explicit nginx server_name, ACME route and trusted certificate, then reloads nginx only after nginx -t succeeds.
The gateway must forward the original Host, X-Forwarded-For and X-Forwarded-Proto to the TicketNova Node.js service.
Run Check DNS + SSL + Routing. Approval is allowed only when the Admin card reports DNS Ready, SSL Ready (HTTPS) and ROUTE Ready.
Update BASE_URL and the three Discord callback URLs to the new main TicketNova hostname, then add those exact callback URLs in the Discord Developer Portal. The unified custom domain itself does not need separate Discord callback URLs.
OAuth flow
Discord OAuth continues through the main TicketNova BASE_URL. Custom domains do not need their own Discord redirect URI. TicketNova remembers the approved destination, completes the central Discord login and uses a short-lived, single-use login bridge to return the user to the correct Customer or Staff route on that same hostname.
Dashboard Permissions, audit and security
TicketNova uses Discord identity plus server-specific dashboard capabilities. Server owners can decide which Discord roles may see or manage individual parts of the dashboard.
Capabilities control areas such as Overview, Support, Panels, Operations, Support Suite, Work Hours, Verification, Custom Domains, Settings, Audit and Data Cleanup.
Separate capabilities can control replying, claiming, assigning, participant management, integrations and destructive/administrative actions.
Important management and ticket actions are written to guild audit history with actor, action, target and supporting details.
The Support Suite includes a security overview for abuse controls, integration access and related protections.
Configured TicketNova platform administrators can open every connected server workspace for platform support/administration. This is separate from normal guild-role permissions.
Verification Center
The Verification Center is server-specific and provides configuration, a publishable Discord verification panel and verification history.
Define the server's verification behaviour and the Discord role/result that follows successful verification.
Use supported account-age or verification checks to reduce obvious abuse where appropriate.
Configure panel text and member-facing messages before publishing the verification panel.
Authorized staff can review the server's verification records and related activity.
Data Cleanup
Data Cleanup manages server-specific retention and destructive maintenance. Use it carefully because several actions permanently remove data.
Configure supported retention periods. A disabled/zero retention setting leaves that category outside automatic cleanup.
Remove matching old data immediately rather than waiting for scheduled retention.
A combined cleanup can remove stored support history, including ticket records, web transcripts, message/answer data and audit logs.
Separate cleanup controls exist for supported verification history, revoked verification, reviews and expired form/session records.
The full reset is intended for deliberate server-level data removal and should only be used with a verified backup/decision.
TicketNova includes guild-data cleanup behaviour for servers the bot leaves, preventing abandoned server data from remaining indefinitely.
These actions are intentionally more powerful than closing a ticket. Back up important configuration/data before destructive maintenance.
Exports, configuration backup and diagnostics
The Support Suite includes tools for moving configuration, exporting operational records and checking whether the Discord/server configuration is healthy.
Authorized users can export supported datasets as CSV for external review or reporting.
Backups contain server configuration such as departments, panels, questions, hours, verification, integrations and related settings.
Restoring a backup never silently re-approves a custom hostname. Restored domains return to the platform approval process.
Diagnostics check the bot connection and important Discord capabilities/references so missing channels, roles or permissions can be fixed before they break support.
Outgoing webhooks
Webhooks let TicketNova push ticket events to your own public HTTPS/HTTP endpoint. They are useful when an external CRM, status system, automation platform or internal service needs to react immediately instead of polling the REST API.
Creating a webhook
You need the integrations_manage capability.
Private/local destinations such as localhost, private RFC1918 addresses and local-only hostnames are rejected to reduce SSRF risk.
Use * for all events or select supported event filters such as ticket.opened, ticket.closed and ticket.merged.
If a secret is configured, normal live webhook deliveries include X-TicketNova-Signature, an HMAC-SHA256 hex digest calculated over the exact raw JSON body.
Payload format
{
"event": "ticket.opened",
"guild_id": "111111111111111111",
"created_at": "2026-09-05T08:30:00.000Z",
"data": {
"ticket_id": 1842,
"ticket_number": 422,
"type": "General Support",
"priority": "Normal",
"department": "Support",
"assigned_to": "222222222222222222"
}
}TicketNova currently emits live events including ticket.opened, ticket.closed, ticket.merged, ticket.transferred, ticket.escalated and ticket.sla_warning. A webhook configured for * receives supported event types that match the server.
Verifying the signature in Node.js
const crypto = require('crypto');
function isValidTicketNovaSignature(rawBody, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
if (!signature || signature.length !== expected.length) return false;
return crypto.timingSafeEqual(
Buffer.from(signature, 'utf8'),
Buffer.from(expected, 'utf8')
);
}Live deliveries use a 7-second timeout and redirects are not followed. Delivery status and duration are stored in the webhook delivery history. Failed deliveries can be retried from the Support Suite. The current manual test/retry helper is intended for reachability checks; signature validation should be tested against a normal signed live event when a secret is used.
How the TicketNova API system works
The TicketNova REST API is a server-to-server, read-only API. An API key belongs to exactly one Discord server. Every successful request is automatically scoped to that key's guild, which means an integration does not send a guild ID to choose another server.
For the hosted TicketNova service, requests use https://ticketnova.app/api/v1. If the platform is deployed on another main hostname, use that deployment's main BASE_URL with /api/v1.
Create an API key
Go to that server's dashboard and open Support Suite → Integrations.
Enter a descriptive name such as Website integration and choose Generate API key.
The raw key starts with tn_ and is shown once. TicketNova stores a SHA-256 hash plus a short prefix, not the original secret.
Put the key in an environment variable or secrets manager. Never put it in public JavaScript, GitHub, HTML or a mobile app bundle.
Revocation is immediate. A revoked key receives 401 on future requests. Create a replacement key before rotating a production integration.
Authentication
Use one of these two headers. The Bearer header is recommended because it follows the common HTTP authentication pattern.
curl "https://ticketnova.app/api/v1/guild" \
-H "Authorization: Bearer tn_YOUR_API_KEY"curl "https://ticketnova.app/api/v1/guild" \
-H "X-API-Key: tn_YOUR_API_KEY"Security and isolation
The key record contains its Discord guild ID. Ticket and statistics queries always use that guild ID on the server side.
The current v1 API can read guild information, tickets and ticket statistics. It does not create, reply to, close, reopen, assign or delete tickets.
TicketNova compares a SHA-256 hash of the incoming key with the stored key hash. The raw key cannot be shown again after creation.
If the guild is suspended by a platform administrator, API requests return 503 until the workspace is restored.
The Admin Center can set an API-per-hour limit for a guild. Once the key exceeds that limit in the current hour, TicketNova returns 429.
Successful key validation updates the key's last-used timestamp so server managers can identify active and unused integrations.
A browser bundle exposes the key to every visitor and cross-origin browser rules may block the request anyway. Call TicketNova from your own backend and send only the safe data your frontend needs.
REST API v1 endpoints
| Method | Endpoint | What it returns |
|---|---|---|
| GET | /api/v1/guild | Basic information/settings for the API key's Discord server. |
| GET | /api/v1/tickets | Up to the 250 newest tickets in the guild. Optional status filter. |
| GET | /api/v1/tickets/:id | One ticket plus its stored messages and tags. |
| GET | /api/v1/stats | Current ticket totals: total, open, closed, deleted and urgent-open. |
GET /api/v1/guild
Returns the guild attached to the API key. This is useful for confirming that a configured key belongs to the expected Discord server.
{
"guild": {
"id": "111111111111111111",
"name": "TicketNova Support",
"maintenance_mode": 0,
"announcement_enabled": 1,
"announcement_text": "Support is available today."
}
}GET /api/v1/tickets
Returns tickets newest first, with a hard limit of 250 rows. The optional status query parameter supports exactly Open, Closed or Deleted. If a different value is supplied, TicketNova does not apply a status filter.
curl "https://ticketnova.app/api/v1/tickets?status=Open" \
-H "Authorization: Bearer tn_YOUR_API_KEY"{
"items": [
{
"id": 1842,
"ticket_number": 422,
"subject": "Cannot connect",
"type": "General Support",
"status": "Open",
"priority": "High",
"workflow_state": "WaitingStaff",
"custom_status": null,
"user_id": "333333333333333333",
"user_name": "ExampleUser",
"claimed_by": "222222222222222222",
"claimed_by_name": "Support Agent",
"department_id": 2,
"created_at": "2026-09-05T06:30:00.000Z",
"closed_at": null,
"last_activity_at": "2026-09-05T07:10:00.000Z"
}
]
}GET /api/v1/tickets/:id
Returns the full ticket database record for that guild, together with message history and tags. If the ID does not exist in the API key's guild, the API returns 404; a ticket from another guild is therefore not exposed.
curl "https://ticketnova.app/api/v1/tickets/1842" \
-H "Authorization: Bearer tn_YOUR_API_KEY"{
"ticket": { "id": 1842, "ticket_number": 422, "status": "Open", "...": "other stored ticket fields" },
"messages": [
{
"author_name": "ExampleUser",
"is_staff": 0,
"content": "I cannot connect to the server.",
"attachments_json": [],
"created_at": "2026-09-05T06:30:10.000Z",
"edited_at": null,
"deleted_at": null
}
],
"tags": [
{ "name": "connection", "color": "#4f8cff" }
]
}GET /api/v1/stats
Returns current counts calculated directly from tickets for the API key's server.
{
"stats": {
"total": 422,
"open": 8,
"closed": 410,
"deleted": 4,
"urgent": 1
}
}HTTP error responses
| Status | Meaning | Typical response |
|---|---|---|
401 | Missing, invalid or revoked API key. | {"error":"Invalid or revoked TicketNova API key."} |
404 | Requested ticket does not exist in this guild. | {"error":"Ticket not found."} |
429 | Configured hourly API limit exceeded. | {"error":"Hourly TicketNova API limit reached."} |
503 | The guild/workspace is suspended by the platform. | {"error":"This TicketNova workspace is temporarily suspended."} |
API examples in cURL, Node.js, Python and PHP
These examples use environment variables so the secret does not need to be hardcoded. Replace the base URL only when your TicketNova deployment uses another main hostname.
cURL: show open tickets
export TICKETNOVA_API_KEY="tn_YOUR_API_KEY"
curl -s "https://ticketnova.app/api/v1/tickets?status=Open" \
-H "Authorization: Bearer $TICKETNOVA_API_KEY"Node.js 20+: fetch current stats
const apiKey = process.env.TICKETNOVA_API_KEY;
async function getTicketNovaStats() {
const response = await fetch('https://ticketnova.app/api/v1/stats', {
headers: {
Authorization: `Bearer ${apiKey}`
}
});
const body = await response.json();
if (!response.ok) {
throw new Error(body.error || `TicketNova returned HTTP ${response.status}`);
}
return body.stats;
}
getTicketNovaStats()
.then(stats => console.log('Open tickets:', stats.open))
.catch(console.error);Node.js: use the ticket list in your own backend route
app.get('/internal/support-summary', async (req, res) => {
const response = await fetch(
'https://ticketnova.app/api/v1/tickets?status=Open',
{ headers: { 'X-API-Key': process.env.TICKETNOVA_API_KEY } }
);
const body = await response.json();
if (!response.ok) {
return res.status(502).json({ error: body.error || 'TicketNova API failed' });
}
// Return only the fields your frontend actually needs.
res.json(body.items.map(ticket => ({
number: ticket.ticket_number,
subject: ticket.subject,
priority: ticket.priority,
status: ticket.status
})));
});Python: retrieve one ticket
import os
import requests
api_key = os.environ["TICKETNOVA_API_KEY"]
ticket_id = 1842
response = requests.get(
f"https://ticketnova.app/api/v1/tickets/{ticket_id}",
headers={"Authorization": f"Bearer {api_key}"},
timeout=15,
)
if response.status_code == 404:
print("Ticket not found in this TicketNova server")
else:
response.raise_for_status()
data = response.json()
print(data["ticket"]["status"])
print("Messages:", len(data["messages"]))PHP: read guild information
<?php
$apiKey = getenv('TICKETNOVA_API_KEY');
$ch = curl_init('https://ticketnova.app/api/v1/guild');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Accept: application/json'
],
CURLOPT_TIMEOUT => 15
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($body, true);
if ($status !== 200) {
throw new RuntimeException($data['error'] ?? 'TicketNova API error');
}
echo $data['guild']['name'];Recommended production pattern
Your frontend should call your own backend. Your backend stores the TicketNova API key privately, requests only the data needed, optionally caches it for a short period and sends a limited response to the browser. This avoids leaking the API key and gives you control over your own authorization rules.
Admin Center
The Admin Center is only for configured TicketNova platform administrators. It provides cross-server platform control that normal guild administrators do not receive.
Review connected guilds, current ticket activity and per-server platform settings.
Set server-level guardrails. Blank/zero-style unlimited values leave the relevant limit unrestricted according to the control.
Review domain requests as responsive cards, see the detected A/AAAA/CNAME record, DNS propagation status, TLS certificate state and last verification time, then Verify & approve, Pending, Suspend, Reject or Delete.
Custom-domain requests and supported platform events appear on a separate Notifications page. Items can be removed individually or all at once.
Review authenticated sessions, background jobs/failures and automatic SQL migration history.
Manage platform-administrator controls and review platform audit/security information.
Admin Center lists use numbered pagination in groups of five. Long result sets show controls such as 1 2 3 4 5 … with previous/next navigation, and search works together with the paging.
Application updates and automatic SQL migrations
This section is for the operator who hosts TicketNova. Existing installations should keep their database; application updates are designed to apply not-yet-run SQL automatically during startup.
Keep a restorable copy before replacing an application release.
Keep your real .env, upload/storage folders and any deployment-specific persistent data.
Run npm install using Node.js 20+.
For PM2, use a restart with updated environment variables when required.
Files in database/auto-updates/ run once in filename order. Applied/failed status is recorded in platform_migration_history.
Check /healthz, /readyz, the Admin Center migration history, a normal dashboard, Customer Portal and approved custom domains.
This hosting/proxy compatibility release does not require a schema change. Its automatic SQL file records v5.4.4 in migration history; the functional changes are in Express proxy handling, sessions/custom-domain host detection and deployment guidance.
Troubleshooting
A custom domain shows AMP Pulse or another wrong website.
The A/AAAA record can be completely correct while the VPS virtual-host routing is wrong. The frontend webserver is sending the hostname to another application before TicketNova sees it. Run Check DNS + SSL + Routing: the card will show ROUTE Mismatch. In v5.5.0 the automatic gateway agent fixes this after DNS propagation by creating the hostname-specific nginx route and SSL certificate itself. After the one-time gateway-agent installation, do not add domains manually in nginx.
The DNS record is correct but TicketNova still says Pending.
DNS and TicketNova approval are separate. A TicketNova platform administrator must Approve the domain in the Admin Center before the hostname is allowed to route.
I see ERR_ERL_UNEXPECTED_X_FORWARDED_FOR and login does not stay logged in.
Your host is using a reverse proxy and Express must trust that local/private proxy. v5.4.4 defaults to TRUST_PROXY=auto. Remove an old invalid proxy setting or set TRUST_PROXY=auto, restart TicketNova, and ensure the proxy sends X-Forwarded-Proto: https. This is also required for secure session cookies behind HTTPS termination.
Discord login returns to the wrong hostname.
Keep Discord OAuth redirect URLs on the main TicketNova BASE_URL. Custom domains use TicketNova's signed return state and one-time bridge; they should not be registered as separate Discord OAuth callback URLs.
I cannot see a sidebar page.
Check Dashboard Permissions for your Discord role. TicketNova intentionally hides pages and actions for which your server-specific role lacks the required capability.
A customer cannot close or reopen a ticket.
That is intentional. In the current Customer Portal, close and reopen controls are staff-only. The customer can continue the conversation while the ticket is open but cannot change that status themselves.
An API request returns 401.
The API key is missing, invalid or revoked. Use Authorization: Bearer tn_... or X-API-Key: tn_.... If the original raw key was lost, create a new key; TicketNova cannot recover it from the stored hash.
An API request returns 429.
The key exceeded the server's configured API-per-hour limit. Wait for the next hourly window or ask a platform administrator to adjust the guild's API limit if the integration legitimately needs more requests.
An API request returns 503.
The Discord server's TicketNova workspace is suspended at platform level. A platform administrator must restore it before API access resumes.
The API only returns 250 tickets.
The current GET /api/v1/tickets endpoint intentionally returns at most the 250 newest tickets and does not yet expose pagination. Use the status filter to reduce the result set when possible.
Webhook delivery fails immediately.
Confirm the destination is a public HTTP/HTTPS URL that resolves to a public IP. Private/local addresses are blocked. Make sure the endpoint responds within 7 seconds and does not require TicketNova to follow a redirect.
My webhook signature does not match.
Calculate HMAC-SHA256 over the exact raw request body using the configured secret and compare the hexadecimal digest with X-TicketNova-Signature. Do not parse and re-stringify JSON before calculating the signature because whitespace/order changes can alter the digest.
Automatic SQL did not apply.
Open Admin Center migration history and check whether the update is Applied or Failed. A failed automatic SQL file stops startup progression so the underlying MySQL error can be fixed instead of leaving a partly upgraded database.
A Discord ticket channel disappeared after closing.
That is normal. Closing removes the Discord channel but keeps the TicketNova ticket record, messages and transcript. Staff and customers continue to see the retained case where their permissions allow it.
Ask the TicketNova support team.
Include the Discord server name, the page/feature involved, the exact error message, and a screenshot or API/webhook response when possible.
