Skip to content

Tickets

Tickets is ProxPanel’s lightweight built-in help-desk. A subscriber opens a ticket from the Customer Portal, an admin or reseller answers, the thread accumulates replies until the issue is resolved. Categories, priorities, and assignment let you triage at scale; internal notes let your team coordinate without leaking context to the customer.

For ISPs that already use Zendesk or Freshdesk, Tickets is an alternative — not a competitor. For ISPs that have only the panel, it’s enough to run support without paying a second SaaS bill.

  • SidebarTickets (envelope icon).
  • Direct URL: /tickets.
  • From a subscriber’s detail page → Tickets tab.

Visible to admins and to resellers with tickets.view. The tickets.view_all permission elevates a user from “see only my own subscribers’ tickets” to “see all tickets in the system” — useful for a centralized support team that handles tickets from every reseller’s customers.

ColumnNotes
#Ticket number — autoincrement, prefixed with a configurable string (e.g., TKT-).
SubjectOne-line summary. Click to open the full thread.
SubscriberName + username; reseller shown for admins.
Categorybilling, connectivity, wifi, complaint, request, other (configurable).
Prioritylow, normal, high, urgent.
Statusopen, pending, resolved, closed.
Assigned toThe admin/reseller currently owning it, or unassigned.
UpdatedTime of the latest reply.

Top toolbar: filter by status, priority, category, assignee, and date. Default sort puts unresolved high/urgent tickets first.

Three ways:

  1. Customer Portal — subscriber clicks “Need help?” and submits subject + body + category. The handler (Create) attaches the subscriber ID server-side from the auth token so customers can’t open tickets on someone else’s account.
  2. Admin/reseller — open a subscriber’s detail page → Tickets tab → + New Ticket. Useful for documenting calls and walk-ins.
  3. APIPOST /api/tickets with subscriber_id, subject, body, category, priority. Permitted endpoints depend on tickets.create permission.

On creation the ticket gets status = open, priority = normal unless specified, and an audit log entry. If Communication Rules include a ticket_created event, the customer also receives an acknowledgment via their preferred channel.

AddReply (POST /api/tickets/:id/replies) appends a ticket_replies row. Each reply is tagged with the author’s user_type so the thread can render customer messages on one side and staff messages on the other. Markdown is permitted in reply bodies; the renderer is server-side and sanitised — no raw HTML.

When an admin or reseller replies:

  1. Ticket status flips to pending (waiting on customer) unless they explicitly chose resolved.
  2. If Communication Rules include ticket_reply, the customer is notified via their preferred channel with the reply text.
  3. updated_at is bumped — the ticket re-sorts to the top of the open queue.

When a customer replies:

  1. Status flips back to open (we’re waiting on staff again).
  2. If the ticket is assigned, the assignee is notified (via the same Communication channels, scoped to operator notifications).

Categories are configurable in Settings → General. Defaults:

  • billing — invoice questions, refund requests.
  • connectivity — line down, slow speed, packet loss.
  • wifi — router questions, SSID changes, password changes.
  • complaint — formal complaint, escalations.
  • request — plan changes, equipment, special handling.
  • other.

Categories drive reporting (Reports → Tickets shows resolution time by category) and routing rules (auto-assign all billing tickets to the billing team).

PriorityTypical SLA
urgentWithin 1 hour. Service-down for the customer.
highWithin 4 hours. Major impact but workable.
normalWithin 1 business day. The default.
lowWithin 3 business days. Cosmetic or non-time-sensitive.

Priority is set by the customer in the portal and can be re-prioritised by staff. The list view sorts urgent + high to the top regardless of recency, so they don’t get buried.

Update (PATCH /api/tickets/:id) lets you set assigned_to_user_id. Once assigned:

  • The assignee sees the ticket in My Tickets (a filter on their own dashboard).
  • Notifications about new replies go to the assignee primarily.
  • Reassignment is logged in the audit trail with old/new assignee names.

Round-robin auto-assignment is not built in — assignment is manual or via category-based routing rules.

A reply can be marked internal note. Internal notes:

  • Are visible only to admins and resellers — the customer never sees them in their portal.
  • Are excluded from ticket_reply notifications to the customer.
  • Are rendered with a distinct background in the thread view so staff don’t accidentally treat them as a public reply.

Use them for coordination (“Asked field tech to swing by Tuesday”), context (“Customer has been late on payments — escalate carefully”), and post-mortems.

By default, a reseller sees only tickets opened by their subscribers. With tickets.view_all granted, they see every open ticket in the system. This is the model used by:

  • Centralised support teams (one reseller’s staff answers tickets across all resellers).
  • Quality control (a senior reseller reviews how juniors are handling threads).
  • Bilingual fallback (a support agent fluent in a second language picks up tickets in that language regardless of reseller).

The same permission gates the Stats call (GetStats) — without it, ticket metrics are scoped to your own subscribers.

GetStats returns counters and averages for the current scope:

  • Open / pending / resolved / closed counts.
  • Average first-response time (creation → first staff reply).
  • Average resolution time (creation → status = resolved).
  • Backlog by category and priority.

The numbers appear at the top of the Tickets page and drive the Tickets widget on the Reports page.

  1. Open Tickets, default sort puts urgent and high at the top.
  2. Assign each unassigned urgent ticket to a staff member by clicking the Assignee column dropdown.
  3. For tickets that have been pending more than 24 hours, click in and either bump priority or push the customer for a reply.
  1. Pull up the subscriber → Tickets+ New Ticket.
  2. Subject = a summary of what they called about. Body = the exact words used.
  3. Mark category and priority. Set status to resolved if you fixed it on the call, or pending if you promised a follow-up.
  4. Add an internal note describing what you did so the next agent who looks doesn’t have to re-derive context.
  1. Last action of the shift: open the ticket, change assignee to the incoming agent.
  2. Drop an internal note with: current state, what’s been tried, what to do next.
  3. The audit log records the reassignment with timestamp, IP, and both names so there’s no ambiguity if a customer asks why their ticket bounced.
PermissionWhat it gates
tickets.viewOpen Tickets page. Scope = own subscribers.
tickets.view_allElevates scope to the whole system.
tickets.createOpen a ticket on behalf of a subscriber.
tickets.editChange category, priority, status, assignment.
tickets.replyPost replies (public or internal).
tickets.deleteSoft-delete a ticket — rare; almost always you want to close it instead.