Endpoints de Tickets
El módulo de ticketing expone una API REST bajo /tickets/api/ para gestión
completa de soporte técnico, incluyendo tickets, departamentos, mensajes,
notas internas, asignación de agentes y acciones de flujo de trabajo.
Tickets — /tickets/api/tickets/
Gestión principal de tickets de soporte. Los clientes solo ven sus propios tickets; los agentes (staff/superuser) ven todos.
Método |
Endpoint |
Descripción |
|---|---|---|
|
|
Listar tickets (con filtros) |
|
|
Crear nuevo ticket |
|
|
Detalle de ticket con mensajes |
|
|
Actualizar ticket |
|
|
Eliminar ticket |
Acciones de Ticket
Método |
Endpoint |
Descripción |
|---|---|---|
|
|
Añadir respuesta al ticket |
|
|
Añadir nota interna (solo agentes) |
|
|
Asignar ticket a un agente |
|
|
Marcar como resuelto |
|
|
Cerrar ticket |
|
|
Reabrir ticket cerrado/resuelto |
Filtros disponibles
?status=open— Filtrar por estado (new, open, pending, on_hold, resolved, closed)?priority=high— Filtrar por prioridad (low, medium, high, urgent, critical)?department=soporte— Filtrar por slug de departamento?assigned_to=me— Tickets asignados al usuario actual?assigned_to=unassigned— Tickets sin asignar
Ejemplo — Crear ticket:
curl -X POST https://panel.example.com/tickets/api/tickets/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"subject": "No puedo acceder a mi sitio web",
"priority": "high",
"department": 1
}'
Respuesta (201 Created):
{
"id": "e5f6a7b8-c9d0-1234-5678-9abcdef01234",
"number": "TK-000042",
"subject": "No puedo acceder a mi sitio web",
"tenant": 1,
"requester": 5,
"requester_email": "cliente@example.com",
"requester_name": "Juan Perez",
"assigned_to": null,
"department": 1,
"status": "new",
"priority": "high",
"source": "api",
"tags": [],
"sla_policy": null,
"sla_first_response_due": null,
"sla_resolution_due": null,
"first_responded_at": null,
"resolved_at": null,
"closed_at": null,
"messages": [],
"created_at": "2026-02-08T10:00:00Z",
"updated_at": "2026-02-08T10:00:00Z"
}
Ejemplo — Listar tickets abiertos:
curl -X GET "https://panel.example.com/tickets/api/tickets/?status=open" \
-H "Authorization: Bearer $TOKEN"
Ejemplo — Responder a un ticket:
curl -X POST https://panel.example.com/tickets/api/tickets/e5f6a7b8-c9d0-1234-5678-9abcdef01234/reply/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"body": "Hemos revisado el servidor y el problema era un error de DNS. Ya está corregido. Por favor, verifica si puedes acceder ahora."
}'
Respuesta (201):
{
"id": 15,
"ticket": "e5f6a7b8-c9d0-1234-5678-9abcdef01234",
"author": 1,
"author_email": "agente@noxpanel.com",
"author_name": "Admin NoxPanel",
"message_type": "reply",
"body": "Hemos revisado el servidor y el problema era un error de DNS. Ya está corregido. Por favor, verifica si puedes acceder ahora.",
"body_html": "",
"is_from_agent": true,
"created_at": "2026-02-08T10:15:00Z"
}
Ejemplo — Añadir nota interna:
curl -X POST https://panel.example.com/tickets/api/tickets/e5f6a7b8-c9d0-1234-5678-9abcdef01234/note/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"body": "El DNS apuntaba a la IP antigua. Actualizado registro A a 203.0.113.10."
}'
Ejemplo — Asignar ticket:
# Asignar a uno mismo
curl -X POST https://panel.example.com/tickets/api/tickets/{id}/assign/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json"
# Asignar a otro agente
curl -X POST https://panel.example.com/tickets/api/tickets/{id}/assign/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"agent_id": 3}'
Ejemplo — Resolver y cerrar:
# Resolver
curl -X POST https://panel.example.com/tickets/api/tickets/{id}/resolve/ \
-H "Authorization: Bearer $TOKEN"
# Cerrar
curl -X POST https://panel.example.com/tickets/api/tickets/{id}/close/ \
-H "Authorization: Bearer $TOKEN"
Departamentos — /tickets/api/departments/
Gestión de departamentos de soporte. Lectura para todos los autenticados, escritura solo para agentes (staff/superuser).
Método |
Endpoint |
Descripción |
|---|---|---|
|
|
Listar departamentos |
|
|
Crear departamento (agente) |
|
|
Detalle por slug |
|
|
Actualizar departamento |
|
|
Eliminar departamento |
Respuesta:
{
"id": 1,
"name": "Soporte Técnico",
"slug": "soporte-tecnico",
"description": "Problemas técnicos con hosting, DNS, email y servidores",
"email": "soporte@noxpanel.com",
"manager": 1,
"is_active": true
}
Estados de Ticket
Un ticket pasa por los siguientes estados durante su ciclo de vida:
Estado |
Descripción |
|---|---|
|
Recién creado, sin primera respuesta |
|
Abierto y en proceso de atención |
|
Pendiente de respuesta del cliente |
|
En espera (dependencia externa) |
|
Resuelto, pendiente de confirmación |
|
Cerrado definitivamente |
Prioridades
Prioridad |
Valor |
Uso recomendado |
|---|---|---|
|
Baja |
Consultas generales, mejoras |
|
Media |
Problemas que no afectan producción |
|
Alta |
Problemas que afectan a la operativa |
|
Urgente |
Servicio degradado en producción |
|
Crítica |
Servicio caído, pérdida de datos |
Orígenes del Ticket
Los tickets pueden crearse desde diferentes fuentes:
web— Panel web de NoxPanelemail— Email recibido (IMAP/OAuth2) procesado automáticamenteapi— Creado vía API RESTphone— Registrado manualmente desde llamada telefónica
SLA (Service Level Agreement)
El sistema de SLA permite definir tiempos máximos de respuesta y resolución según la prioridad. Las políticas SLA se asignan automáticamente al ticket según su prioridad.
Las tareas de Celery verifican periódicamente si hay incumplimientos de SLA:
check-sla-breaches: Cada 15 minutosauto-close-resolved-tickets: Diariamente (cierra tickets resueltos tras X días)