Skip to content

Tickets ​

O ticket é o recurso central do Helpdesk. Ele guarda o estado atual do atendimento — solicitante, agente responsável, status, prioridade, categoria — e concentra as métricas de tempo, os alvos de SLA, os marcadores de leitura e o lock_version de controle de concorrência. A conversa em si fica nas threads.

O mesmo recurso aparece nos dois domínios, com visões diferentes: o staff opera o board completo (/v1/helpdesk/agent/tickets) e o cliente acompanha apenas os próprios chamados (/v1/helpdesk/customer/tickets).

Headers obrigatórios

Todas as requisições devem incluir o header X-Helpdesk-Id (UUID) e Authorization: Bearer {token} — token do agente na área de staff, token do cliente no portal.


Estrutura de Dados Principal ​

CampoTipoDescrição
idNumberIdentificador do ticket.
numberNumberNúmero sequencial por instância — exibido com o prefixo da instância (TCK-1, TCK-2...).
subjectStringAssunto do chamado (máx. 250 caracteres).
statusStringopen, pending, solved ou closed.
priorityStringlow, normal, high ou urgent (padrão: normal).
channelStringCanal de origem: portal, email, api, chat ou phone.
helpdeskUserIdNumberCliente solicitante.
helpdeskAgentIdNumberAgente responsável (null = na fila, não atribuído).
helpdeskCategoryIdNumberCategoria (fila) do ticket.
parentIdNumberTicket pai, para chamados vinculados (opcional).
assignedAtStringQuando o ticket foi atribuído pela primeira vez.
firstResponseDueAtStringAlvo de SLA para a primeira resposta.
resolutionDueAtStringAlvo de SLA para a resolução.
helpdeskSlaPolicyIdNumberPolítica de SLA aplicada (conforme a prioridade).
firstReplyAtStringQuando o agente respondeu pela primeira vez.
lastCustomerReplyAtStringÚltima mensagem do cliente.
lastAgentReplyAtStringÚltima resposta pública do agente.
solvedAtStringQuando o ticket foi resolvido.
closedAtStringQuando o ticket foi fechado.
reopenedCountNumberQuantas vezes o ticket foi reaberto.
threadsCountNumberTotal de itens na timeline (mensagens + eventos).
customerLastReadAt / agentLastReadAtStringMarcadores de leitura para o contador de não lidos.
lockVersionNumberVersão do registro, incrementada nas operações de atribuição (concorrência otimista).

Ciclo de Status ​

StatusSignificado
openAguardando ação do atendimento.
pendingAguardando retorno do cliente.
solvedResolvido — pode reabrir com resposta do cliente ou fechar automaticamente.
closedEncerrado definitivamente — não aceita novas mensagens do cliente.

Regras Automáticas ​

A instância aplica gatilhos nativos sobre os tickets, todos configuráveis na gestão da instância:

  • Auto-reopen (isAutoReopenSolved): quando o cliente responde um ticket solved, o status volta para open, solvedAt é zerado e reopenedCount incrementa. A mudança gera um evento status_changed na timeline.
  • Auto-pending (isAutoPendingOnAgentReply): quando o agente envia uma resposta pública em um ticket open, o status muda para pending. Notas internas não disparam o gatilho.
  • Auto-assign (settings.autoAssign === true): na criação de um ticket sem agente, a instância distribui automaticamente em round-robin — escolhe o agente ativo e disponível (isAvailable) que atende a categoria do ticket, sem estourar maxOpenTickets, com a menor contagem de tickets abertos (desempate: quem respondeu por último há mais tempo). A atribuição automática gera um evento assigned na timeline com automatic: true.
  • Auto-close (autoCloseAfterDays): o comando node ace helpdesk:auto-close fecha tickets solved há mais dias que o configurado, registrando um evento status_changed na timeline.

SLA ​

Os alvos de SLA são calculados em dois momentos, a partir da política ativa da prioridade vigente (veja Políticas de SLA):

  1. Na criação do ticket — conforme a prioridade inicial (padrão normal).
  2. Na mudança de prioridade — via update ou troca explícita, os alvos são recalculados a partir do momento da mudança.

Se a política tiver isBusinessHoursOnly: true e a instância tiver settings.businessHours válido, os minutos contam apenas dentro da janela comercial (no timezone da instância); caso contrário, o cálculo é em tempo corrido. Sem política ativa para a prioridade, os campos firstResponseDueAt/resolutionDueAt ficam null.


Endpoints do Staff ​

Board de Tickets ​

Lista os tickets da instância com paginação e filtros combináveis — a base do board do atendente.

http
GET /v1/helpdesk/agent/tickets

Parâmetros de Query ​

NomeTipoObrigatórioDescrição
pagenumberNãoO número da página (mínimo: 1).
perPagenumberNãoItens por página (entre 1 e 100, padrão: 25).
statusstringNãoopen, pending, solved ou closed.
prioritystringNãolow, normal, high ou urgent.
channelstringNãoportal, email, api, chat ou phone.
helpdeskUserIdnumberNãoFiltra por cliente solicitante.
helpdeskAgentIdnumberNãoFiltra por agente responsável.
helpdeskCategoryIdnumberNãoFiltra por categoria (fila).
tagIdsnumber[]NãoFiltra por tags vinculadas.
unassignedbooleanNãoSomente tickets sem agente atribuído.
searchstringNãoBusca por termo no assunto (máx. 250 caracteres).
orderBystringNãoid, number, createdAt, updatedAt, firstResponseDueAt ou resolutionDueAt — útil para ordenar por SLA mais próximo de estourar.
orderDirectionstringNãoDireção: asc ou desc.

Exemplo de Requisição ​

bash
curl -X GET "https://api.us.basis.tavares.in/v1/helpdesk/agent/tickets?status=open&unassigned=true&orderBy=firstResponseDueAt&orderDirection=asc" \
  -H "X-Helpdesk-Id: 3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

Respostas ​

200 OK

Retorna um objeto de paginação contendo a lista de tickets.

json
{
  "meta": {
    "currentPage": 1,
    "perPage": 25
  },
  "data": [
    {
      "id": 1,
      "number": 1,
      "subject": "Não consigo acessar o painel",
      "status": "open",
      "priority": "normal",
      "channel": "portal",
      "helpdeskUserId": 1,
      "helpdeskAgentId": null,
      "helpdeskCategoryId": 1,
      "firstResponseDueAt": "2026-09-01T18:05:33.000+00:00",
      "resolutionDueAt": "2026-09-02T10:05:33.000+00:00",
      "threadsCount": 1,
      "createdAt": "2026-09-01T10:05:33.000+00:00",
      "updatedAt": "2026-09-01T10:05:33.000+00:00"
    }
  ]
}

Criar Ticket ​

Cria um ticket em nome de um cliente, já com a primeira mensagem na timeline. Os alvos de SLA são calculados neste momento e, se settings.autoAssign estiver ativo, o ticket pode nascer atribuído.

http
POST /v1/helpdesk/agent/tickets

Payload (Body) ​

AtributoTipoObrigatórioDescrição
helpdeskUserIdnumberSimID do cliente solicitante.
subjectstringSimAssunto do chamado (máx. 250 caracteres).
bodystringNãoPrimeira mensagem — registrada na timeline como senderType: customer.
isHtmlbooleanNãoIndica que o body é HTML (padrão: false).
fileIdsnumber[]NãoIDs de arquivos já enviados, anexados à primeira mensagem.
parentIdnumberNãoID de um ticket pai (vínculo entre chamados).
helpdeskCategoryIdnumberNãoCategoria (fila) do ticket.
prioritystringNãolow, normal, high ou urgent (padrão: normal).
channelstringNãoCanal de origem: portal, email, api, chat ou phone.
tagIdsnumber[]NãoTags vinculadas já na criação.

Exemplo de Requisição ​

bash
curl -X POST "https://api.us.basis.tavares.in/v1/helpdesk/agent/tickets" \
  -H "X-Helpdesk-Id: 3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "helpdeskUserId": 1,
    "subject": "Erro ao emitir nota fiscal",
    "body": "Cliente relatou erro 500 ao emitir NF-e pelo painel.",
    "helpdeskCategoryId": 2,
    "priority": "high",
    "channel": "phone",
    "tagIds": [1]
  }'

Respostas ​

201 Created

Retorna o ID do ticket criado.

json
{
  "id": 1
}

Obter Ticket por ID ​

Recupera os detalhes de um ticket, incluindo vínculos (cliente, agente, categoria, tags, pai).

http
GET /v1/helpdesk/agent/tickets/:id

Respostas ​

200 OK

Retorna os dados do ticket.

404 Not Found

Ocorre quando o ticket não existe na instância.

Atualizar Ticket ​

Atualiza assunto, prioridade, categoria e tags. Mudanças de prioridade recalculam o SLA; mudanças de prioridade e categoria geram eventos de sistema (priority_changed / category_changed) na timeline.

http
PUT /v1/helpdesk/agent/tickets/:id

Payload (Body) ​

AtributoTipoObrigatórioDescrição
subjectstringNãoNovo assunto (máx. 250 caracteres).
prioritystringNãoNova prioridade — recalcula os alvos de SLA.
helpdeskCategoryIdnumberNãoNova categoria; envie null para remover.
tagIdsnumber[]NãoSubstitui os vínculos de tags.

Respostas ​

204 No Content

Atualização concluída com sucesso.

Atribuir Ticket ​

Atribui um ticket não atribuído a um agente. Sem helpdeskAgentId no corpo, o ticket é atribuído ao próprio agente autenticado (ação "assumir").

http
POST /v1/helpdesk/agent/tickets/:id/assign

Payload (Body) ​

AtributoTipoObrigatórioDescrição
helpdeskAgentIdnumberNãoID do agente; omitido, assume o agente autenticado.

Respostas ​

204 No Content

Atribuição concluída — gera um evento assigned na timeline e incrementa o lockVersion.

409 Conflict — Trava de concorrência

A atribuição usa update condicional (helpdesk_agent_id IS NULL): se dois agentes tentarem assumir o mesmo ticket ao mesmo tempo, apenas o primeiro vence. O segundo recebe 409 TICKET_ALREADY_ASSIGNED.

json
{
  "message": "Ticket já foi atribuído a outro agente",
  "code": "TICKET_ALREADY_ASSIGNED"
}

404 Not Found

Agente informado não existe na instância (AGENT_NOT_FOUND).

Transferir Ticket ​

Transfere um ticket para outro agente, independentemente de já estar atribuído — ao contrário do assign, não há trava de concorrência. Gera um evento assigned na timeline com os IDs de origem e destino.

http
POST /v1/helpdesk/agent/tickets/:id/transfer

Payload (Body) ​

AtributoTipoObrigatórioDescrição
helpdeskAgentIdnumberSimID do agente de destino.

Respostas ​

204 No Content

Transferência concluída.

Devolver para a Fila ​

Remove a atribuição do ticket (helpdeskAgentId e assignedAt voltam a null). Gera um evento assigned na timeline ("Ticket devolvido para a fila").

http
POST /v1/helpdesk/agent/tickets/:id/unassign

Respostas ​

204 No Content

Ticket devolvido para a fila.

Alterar Status ​

Muda o status do ticket. Ao resolver (solved), grava solvedAt; ao fechar (closed), grava closedAt; ao reabrir, os marcadores são zerados. Toda mudança efetiva gera um evento status_changed na timeline.

http
PATCH /v1/helpdesk/agent/tickets/:id/status

Payload (Body) ​

AtributoTipoObrigatórioDescrição
statusstringSimopen, pending, solved ou closed.

Respostas ​

204 No Content

Status alterado com sucesso.

Sincronizar Tags ​

Substitui os vínculos de tags do ticket pela lista enviada (envie [] para remover todas).

http
POST /v1/helpdesk/agent/tickets/:id/tags

Payload (Body) ​

AtributoTipoObrigatórioDescrição
tagIdsnumber[]SimIDs das tags da instância.

Respostas ​

204 No Content

Tags sincronizadas com sucesso.

Marcar como Lido ​

Atualiza o marcador de leitura do agente (agentLastReadAt), zerando o contador de não lidos do ticket para o staff.

http
POST /v1/helpdesk/agent/tickets/:id/read

Respostas ​

204 No Content

Marcador de leitura atualizado.


Endpoints do Cliente ​

O cliente só enxerga e opera os próprios tickets — qualquer ticket de outro cliente retorna 404 Not Found.

Meus Tickets ​

Lista os tickets do cliente autenticado.

http
GET /v1/helpdesk/customer/tickets

Parâmetros de Query ​

NomeTipoObrigatórioDescrição
pagenumberNãoO número da página (mínimo: 1).
perPagenumberNãoItens por página (entre 1 e 100, padrão: 25).
statusstringNãoopen, pending, solved ou closed.

Respostas ​

200 OK

Retorna um objeto de paginação contendo os tickets do cliente.

Abrir Ticket ​

Cria um ticket em nome do cliente autenticado, já com a primeira mensagem na timeline.

http
POST /v1/helpdesk/customer/tickets

Payload (Body) ​

AtributoTipoObrigatórioDescrição
subjectstringSimAssunto do chamado (máx. 250 caracteres).
bodystringSimPrimeira mensagem do ticket.
isHtmlbooleanNãoIndica que o body é HTML (padrão: false).
fileIdsnumber[]NãoIDs de arquivos já enviados pelo cliente.
channelstringNãoCanal de origem (padrão do ticket: portal via API pública).

Exemplo de Requisição ​

bash
curl -X POST "https://api.us.basis.tavares.in/v1/helpdesk/customer/tickets" \
  -H "X-Helpdesk-Id: 3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Não consigo acessar o painel",
    "body": "Desde ontem o login retorna erro 500.",
    "fileIds": [3]
  }'

Respostas ​

201 Created

Retorna o ID do ticket criado.

json
{
  "id": 2
}

Obter Ticket por ID ​

http
GET /v1/helpdesk/customer/tickets/:id

Respostas ​

200 OK

Retorna os dados do ticket do cliente.

404 Not Found

Ocorre quando o ticket não existe ou pertence a outro cliente.

Responder Ticket ​

Adiciona uma mensagem do cliente à timeline. Se a instância tiver isAutoReopenSolved ativo e o ticket estiver solved, ele reabre automaticamente.

http
POST /v1/helpdesk/customer/tickets/:id/reply

Payload (Body) ​

AtributoTipoObrigatórioDescrição
bodystringSimConteúdo da mensagem.
isHtmlbooleanNãoIndica que o body é HTML (padrão: false).
fileIdsnumber[]NãoIDs de arquivos anexados à mensagem.

Respostas ​

201 Created

Retorna o ID da thread criada.

json
{
  "id": 5
}

422 Unprocessable Entity

Tickets closed não aceitam novas mensagens do cliente.

json
{
  "message": "Ticket fechado não aceita novas mensagens do cliente",
  "code": "TICKET_CLOSED"
}

Marcar como Lido ​

Atualiza o marcador de leitura do cliente (customerLastReadAt), zerando o contador de não lidos no portal.

http
POST /v1/helpdesk/customer/tickets/:id/read

Respostas ​

204 No Content

Marcador de leitura atualizado.


Próximos Passos ​