Documentación

tickets

Tickets y seguimiento

El servicio de tickets funciona sin agentes. Habilítalo en el contrato del cliente desde Central. En el panel puedes crear una solicitud, clasificarla, asignarla a un miembro del equipo, definir prioridad y vencimiento, responder, fusionar duplicados y cerrar el caso. Cada ticket tiene tipo (pregunta, incidente, problema o tarea), etiquetas, referencia externa, campos personalizados, correos en copia y calificación de satisfacción.

Los propietarios, administradores y agentes pueden atender tickets. Los observadores tienen acceso de lectura. Solo los propietarios y administradores pueden eliminarlos desde el panel. La API exige permisos tickets:read o tickets:write; las claves de sandbox no acceden a estos recursos.

Atención desde el panel

  1. Abre Tickets → Nuevo ticket y escribe el título y la descripción. El solicitante, responsable, vencimiento, etiquetas, referencia externa y correos en copia son opcionales.
  2. El vencimiento seleccionado en el calendario corresponde a las 23:59 en la hora de Colombia. Un ticket abierto o pendiente muestra la marca de vencido al superar esa fecha.
  3. Usa el icono Ver para abrir el seguimiento. Publicar respuesta agrega un mensaje visible al solicitante. Nota interna guarda información que solo ve el equipo. La primera respuesta pública del equipo fija la fecha de primera respuesta del ticket.
  4. Cambia el estado a pendiente, resuelto o cerrado. Un solicitante puede responder un caso resuelto y volverá a abierto. Un caso cerrado debe ser reabierto por el equipo para admitir nuevas respuestas públicas.
  5. La eliminación se realiza desde el listado, requiere confirmación y queda auditada. Se eliminan respuestas y enlaces privados; se conserva la conversación vinculada.
  6. El icono Configurar Tickets abre Configuración → Tickets: portal, prioridad y responsable predeterminados, plazos por prioridad, reapertura, calificación de satisfacción e integraciones.

Portal del solicitante

Un administrador activa el portal en Configuración → Tickets. El portal permanece desactivado inicialmente. La dirección tiene la forma /soporte/:empresa en el sitio público.

Un visitante puede crear una solicitud indicando nombre, correo, asunto y descripción. Recibe en pantalla un enlace privado que permite leer y responder únicamente ese ticket durante 30 días. Debe guardarlo; esta entrega no envía ese enlace automáticamente por correo. El correo indicado es un dato de contacto, no una identidad verificada.

El enlace contiene una credencial en el fragmento de la dirección, después de #. La aplicación la envía a la API mediante Authorization; no forma parte de la ruta ni de la consulta HTTP. La base de datos conserva únicamente su hash. No lo compartas fuera de las personas autorizadas para ese caso.

El equipo puede generar un nuevo enlace desde el detalle del ticket. Esto invalida el anterior. Revocar enlace cierra su acceso inmediatamente para las siguientes consultas. Desactivar el portal impide crear solicitudes y usar el seguimiento público. El contenido que alguien ya leyó no puede retirarse de su dispositivo.

Cuando el ticket queda resuelto o cerrado y la calificación está activa, el solicitante puede calificar la atención de 1 a 5 con un comentario opcional desde el mismo enlace. La calificación aparece en el detalle del ticket y en las estadísticas.

Las notas internas, identificadores del equipo y el correo del solicitante no aparecen en la API de seguimiento público. Este portal usa sus propios enlaces; no necesita una clave de API de la empresa en el navegador.

API para integraciones (v1)

Usa una clave de servidor de producción con tickets:read o tickets:write. Créala desde Configuración → Tickets → Integraciones y API, o desde Configuración → API keys. Cada acción hecha con una clave queda en auditoría con el identificador de la clave.

Método Ruta Permiso Función
GET /v1/tickets tickets:read Listado con filtros, orden y sincronización incremental
POST /v1/tickets tickets:write Crear; request_id opcional para reintentos seguros
GET /v1/tickets/stats tickets:read Conteos por estado y prioridad, vencidos, sin asignar, primera respuesta, resolución y satisfacción de los últimos 30 días
GET /v1/tickets/assignees tickets:read Miembros operativos asignables
PATCH /v1/tickets/bulk tickets:write Cambiar estado, prioridad, tipo, etiquetas, responsable o vencimiento de hasta 50 tickets
GET /v1/tickets/:id tickets:read Detalle; ?view=requester devuelve solo lo que ve el solicitante
PATCH /v1/tickets/:id tickets:write Modificar con revision
DELETE /v1/tickets/:id tickets:write Eliminar (auditado)
GET /v1/tickets/:id/entries tickets:read Historial; ?view=requester omite notas internas e identidades del equipo
POST /v1/tickets/:id/entries tickets:write Respuesta o nota, como equipo o en nombre del solicitante
POST /v1/tickets/:id/merge tickets:write Fusionar otros tickets en este
POST /v1/tickets/:id/satisfaction tickets:write Registrar la calificación del solicitante (1 a 5)
POST / DELETE /v1/tickets/:id/portal-link lectura y escritura Generar o revocar el enlace privado

Crear:

{
  "title": "No puedo facturar",
  "description": "La DIAN rechazó la factura F-1",
  "priority": "high",
  "type": "incident",
  "external_id": "CASE-100",
  "contact_id": "UUID de un contacto de la empresa",
  "tags": ["dian", "facturación"],
  "custom_fields": { "invoice_id": "F-1", "amount": 12.5 },
  "cc_emails": ["copia@empresa.com"],
  "requester_name": "Ana",
  "requester_email": "ana@empresa.com",
  "request_id": "UUID único del intento"
}

type admite question, incident, problem o task. external_id es único por empresa; repetirlo devuelve 409. tags admite hasta 10 etiquetas en minúsculas. custom_fields admite hasta 20 claves en minúsculas con valores de texto, número, booleano o nulo, con un máximo de 4 KB; se devuelve tal cual y no se interpreta. source lo fija el servidor: panel, portal, api o flow. Con request_id, repetir la misma petición devuelve el mismo ticket; la misma referencia con otro contenido devuelve 409.

Respuestas: POST /v1/tickets/:id/entries con { "content": "…", "request_id": "UUID", "is_internal": false, "author": { "kind": "requester", "name": "Ana" } }. Con kind: "requester" se aplican las reglas del solicitante: no puede crear notas internas, reabre un ticket resuelto si la configuración lo permite y no puede responder uno cerrado. author.name se muestra en el panel y, para el solicitante, en el seguimiento público. Reutiliza el mismo request_id y contenido si se pierde la respuesta HTTP.

Para modificar, envía la revision obtenida al consultar el ticket. Una revisión desactualizada devuelve 409. assigned_user_id debe pertenecer a un miembro operativo; conversation_id y contact_id, a la misma empresa. sla_due_at acepta una fecha ISO con zona horaria o null para retirar el vencimiento.

Listado: q, status, priority, type y source admiten varios valores separados por coma; tag, assigned_user_id (o none), requester_email (coincidencia exacta), external_id, contact_id, conversation_id, overdue, created_from, created_to, updated_since, sort (updated_at, created_at, sla_due_at, priority), order, page y pageSize (10, 20, 30 o 50). Para sincronizar cambios, guarda la fecha de la última consulta y pide updated_since con esa fecha.

Fusión: POST /v1/tickets/:id/merge con { "source_ids": ["…"] }. El historial de los tickets fusionados pasa al ticket destino, los fusionados quedan cerrados con merged_into_id y no aceptan más respuestas.

Calificación: POST /v1/tickets/:id/satisfaction con { "score": 4, "comment": "…", "request_id": "UUID" }, solo para tickets resueltos o cerrados y con la calificación activa en la configuración.

Generar un enlace privado mediante una clave requiere ambos permisos de lectura y escritura, porque concede acceso al contenido existente.

Límite de tasa: 120 solicitudes por minuto por clave. Las cabeceras X-RateLimit-Limit y X-RateLimit-Remaining informan el estado y 429 indica que debes esperar Retry-After segundos.

Webhooks

Suscribe un endpoint de producción a ticket.created, ticket.updated, ticket.status_changed, ticket.reply_added, ticket.note_added, ticket.merged, ticket.satisfaction_rated o ticket.deleted. Cada evento se confirma en la misma transacción que el cambio y llega con event_id estable, firma HMAC y reintentos. El cuerpo incluye data.ticket con los campos de equipo y, según el evento, data.entry, data.changes, data.from y data.to. Consulta webhooks.

API pública del portal

Método Ruta Credencial
GET / POST /public/ticket-portals/:empresa Sin credencial; portal activo
GET /public/ticket-followup Authorization: Bearer tkt_…
POST /public/ticket-followup/replies El mismo enlace privado
POST /public/ticket-followup/satisfaction El mismo enlace privado; { "score": 1-5, "comment": "…", "request_id": "UUID" }

La creación pública requiere title, description, requester_name, requester_email y un request_id UUID. Repetir el mismo formulario con la misma referencia recupera el mismo ticket y enlace mientras siga vigente. Una referencia reutilizada con otro contenido se rechaza. La respuesta pública exige content y request_id; no acepta notas internas.

Hay límites por IP de 5 creaciones, 30 respuestas y 120 lecturas por minuto. Las respuestas del portal usan Cache-Control: no-store. Los casos deshabilitados, revocados, vencidos o pertenecientes a una cuenta suspendida no permiten seguimiento.

Rutas anteriores

/tickets sigue disponible para el panel y para integraciones existentes con el mismo comportamiento. Las funciones nuevas (filtros múltiples, view=requester, fusión, estadísticas, calificación, respuestas en nombre del solicitante) solo existen en /v1/tickets.

Esta entrega no incluye adjuntos en tickets, formularios configurables, calendarios de horario laboral, correo entrante ni entorno de pruebas para tickets.