Helpdesk API
The Helpdesk module manages customer support tickets from creation through resolution. It supports SLA policies, team assignment, priority routing, and a customer-facing portal for self-service ticket tracking.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/helpdesk/tickets | List tickets (paginated) |
POST | /api/helpdesk/tickets | Create a ticket |
GET | /api/helpdesk/tickets/:id | Get a ticket |
PATCH | /api/helpdesk/tickets/:id | Update a ticket |
POST | /api/helpdesk/tickets/:id/assign | Assign to a team member |
POST | /api/helpdesk/tickets/:id/reply | Add a reply / internal note |
POST | /api/helpdesk/tickets/:id/close | Close a ticket |
POST | /api/helpdesk/tickets/:id/reopen | Reopen a closed ticket |
GET | /api/helpdesk/teams | List helpdesk teams |
GET | /api/helpdesk/sla | List SLA policies |
GET | /api/helpdesk/stats | Support statistics |
Ticket Status Workflow
new → in_progress → pending_customer → resolved → closed
↑ ↓
└──────────── reopen ───────────┘
| Status | Description |
|---|---|
new | Ticket received, unassigned |
in_progress | Agent working on it |
pending_customer | Waiting for customer reply |
resolved | Solution provided |
closed | Ticket closed (after resolution) |
List Tickets
GET /api/helpdesk/tickets?status=new&priority=high&teamId=018e...&page=1&limit=20
Query Parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by ticket status |
priority | low | medium | high | urgent | Filter by priority |
teamId | string | Filter by helpdesk team |
assigneeId | string | Filter by assigned agent |
contactId | string | Filter by customer contact |
overdueSla | boolean | Only tickets that have breached SLA |
from | ISO 8601 | Created from date |
Response
{
"data": [
{
"id": "018e3333-abcd-7000-8000-000000000001",
"ticketNumber": "HD-2026-0142",
"subject": "License activation failing on Odoo 19",
"status": "in_progress",
"priority": "high",
"contact": { "id": "...", "name": "Acme Corp", "email": "[email protected]" },
"assignee": { "id": "...", "name": "Sarah Agent" },
"team": { "id": "...", "name": "Technical Support" },
"sla": {
"policyName": "Enterprise SLA",
"firstResponseDeadline": "2026-03-20T14:00:00Z",
"firstResponseMet": true,
"resolutionDeadline": "2026-03-22T14:00:00Z",
"resolutionBreached": false
},
"createdAt": "2026-03-20T09:00:00Z",
"updatedAt": "2026-03-20T10:30:00Z"
}
],
"meta": { "total": 56, "page": 1, "limit": 20, "totalPages": 3 }
}
Create a Ticket
POST /api/helpdesk/tickets
Content-Type: application/json
{
"subject": "Cannot download purchased module",
"description": "After purchase the download link returns a 403 error.",
"contactId": "018e1234-abcd-7000-8000-000000000001",
"priority": "medium",
"teamId": "018e3333-dddd-7000-8000-000000000001",
"tags": ["download", "license"]
}
Required fields: subject, contactId
Response: 201 Created with the ticket in new status.
Assign a Ticket
POST /api/helpdesk/tickets/018e3333-abcd-7000-8000-000000000001/assign
Content-Type: application/json
{
"assigneeId": "018ecccc-abcd-7000-8000-000000000001",
"teamId": "018e3333-dddd-7000-8000-000000000001"
}
Add a Reply
POST /api/helpdesk/tickets/018e3333-abcd-7000-8000-000000000001/reply
Content-Type: application/json
{
"body": "We've identified the issue. Please clear your browser cache and try again.",
"internal": false,
"attachments": []
}
Set "internal": true to add an internal note visible only to agents (not the customer).
Close a Ticket
POST /api/helpdesk/tickets/018e3333-abcd-7000-8000-000000000001/close
Content-Type: application/json
{
"resolution": "Customer confirmed issue resolved after clearing cache."
}
Support Statistics
GET /api/helpdesk/stats?from=2026-03-01&to=2026-03-31&teamId=018e...
Response
{
"period": { "from": "2026-03-01", "to": "2026-03-31" },
"ticketsCreated": 142,
"ticketsClosed": 128,
"avgFirstResponseMinutes": 34,
"avgResolutionHours": 6.2,
"slaBreachRate": 0.04,
"csat": 4.7,
"byPriority": {
"low": 45, "medium": 62, "high": 28, "urgent": 7
}
}
SLA Policies
GET /api/helpdesk/sla
[
{
"id": "018e3333-aaaa-7000-8000-000000000001",
"name": "Enterprise SLA",
"firstResponseHours": 4,
"resolutionHours": 48,
"applies": ["high", "urgent"]
},
{
"id": "018e3333-bbbb-7000-8000-000000000001",
"name": "Standard SLA",
"firstResponseHours": 24,
"resolutionHours": 120,
"applies": ["low", "medium"]
}
]
Status Codes
| Code | Scenario |
|---|---|
200 | Get, list, or action succeeded |
201 | Ticket or reply created |
400 | Attempt to close an already-closed ticket |
403 | Non-agent attempting to access agent-only routes |
404 | Ticket not found |
422 | Missing required field |