Responde no chamado
POST /portal/support/tickets/{id}/messages
Escopo do token: support:write. Recurso: Chamados.
O chamado volta a esperar a equipe; o resolvido reabre. Num chamado fechado (resolvido há mais dias que close_days) a mensagem abre um chamado novo de continuação, que é o devolvido (outro id, com follow_up_of). Chamado juntado a outro: 409 support.ticket_merged. internal e macro_id só valem para a equipe (400). attachment_ids: anexos enviados antes por /portal/support/attachments. Conversa apagada pelo prazo de guarda ou com 200 mensagens: 409. Rate limit por conta: 60 por hora (burst 20).
Exemplo de requisição
Seção intitulada “Exemplo de requisição”Os exemplos leem o token da variável de ambiente HALVER_API_TOKEN (um token sc_live_… criado em Desenvolvedores › Tokens de API). Nunca escreva o token no código.
curl -X POST "https://dash.halver.com.br/api/v1/portal/support/tickets/f638f2ab-a5a5-45f6-886a-51b17661e088/messages" \ -H "Authorization: Bearer $HALVER_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "body": "Obrigado, voltou a responder."}'package main
import ( "fmt" "io" "net/http" "os" "strings" "time")
func main() { body := strings.NewReader(`{ "body": "Obrigado, voltou a responder."}`) req, err := http.NewRequest(http.MethodPost, "https://dash.halver.com.br/api/v1/portal/support/tickets/f638f2ab-a5a5-45f6-886a-51b17661e088/messages", body) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer "+os.Getenv("HALVER_API_TOKEN")) req.Header.Set("Content-Type", "application/json") client := &http.Client{Timeout: 30 * time.Second} resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() out, err := io.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Println(resp.Status) fmt.Println(string(out))}import os
import requests
resp = requests.post( "https://dash.halver.com.br/api/v1/portal/support/tickets/f638f2ab-a5a5-45f6-886a-51b17661e088/messages", headers={ "Authorization": f"Bearer {os.environ['HALVER_API_TOKEN']}", }, json={ "body": "Obrigado, voltou a responder.", }, timeout=30,)resp.raise_for_status()print(resp.json())Parâmetros
Seção intitulada “Parâmetros”Parâmetros do caminho
Seção intitulada “Parâmetros do caminho”-
idstring (uuid) obrigatórioExemplo:
f638f2ab-a5a5-45f6-886a-51b17661e088.
Corpo da requisição
Seção intitulada “Corpo da requisição”application/json, obrigatório.
-
attachment_idsarray de string (uuid)Até 5 itens.
-
bodystring obrigatórioAté 5000 caracteres.
{ "body": "Obrigado, voltou a responder."}Respostas
Seção intitulada “Respostas”Mensagem gravada; o chamado com a conversa.
Campos da resposta
-
can_rateboolean obrigatórioResolvido por alguém há até 28 dias; pode ser avaliado.
-
categorystring obrigatórioDo que se trata: vendas, suporte técnico, financeiro, bare metal ou privacidade (pedidos do titular, LGPD art. 18). Um de:
sales,technical,billing,bare_metal,privacy. -
closedboolean obrigatórioResolvido há mais dias que
close_days; uma mensagem nova abre um chamado de continuação. -
created_atstring (date-time) obrigatório -
expectedqualquer obrigatório pode ser nuloQuando a equipe deve responder (só enquanto espera a equipe).
-
due_atstring (date-time) obrigatório -
targetstring obrigatório
-
-
follow_up_ofqualquer obrigatório pode ser nulo-
idstring (uuid) obrigatório -
numberstring obrigatório
-
-
idstring (uuid) obrigatório -
last_fromstring obrigatórioUm de:
customer,staff,""(vazio). -
last_message_atstring (date-time) obrigatório -
merged_intoqualquer obrigatório pode ser nulo-
idstring (uuid) obrigatório -
numberstring obrigatório
-
-
messagesarray de objectA conversa (só no detalhe).
-
attachmentsarray de object obrigatório-
content_typestring obrigatórioUm de:
image/png,image/jpeg,image/gif,image/webp,application/pdf,text/plain. -
created_atstring (date-time) obrigatório -
file_namestring obrigatório -
idstring (uuid) obrigatório -
size_bytesinteger obrigatório
-
-
authorstring obrigatórioUm de:
customer,staff,system. -
author_namestring obrigatórioQuem escreveu; toda mensagem da equipe aparece como “Equipe Halver” e as do sistema como “Halver”.
-
bodystring obrigatório -
created_atstring (date-time) obrigatório -
idstring (uuid) obrigatório
-
-
numberstring obrigatório -
prioritystring obrigatórioPrioridade: baixa, normal, alta ou urgente (define o SLA). Um de:
low,normal,high,urgent. -
purgedboolean obrigatórioA conversa foi apagada pelo prazo de guarda (1 ano após a resolução).
-
ratingqualquer obrigatório pode ser nulo-
commentstring obrigatório -
rated_atstring (date-time) obrigatório -
ratingstring obrigatórioUm de:
good,bad.
-
-
resolved_atstring (date-time) obrigatório pode ser nulo -
serverqualquer obrigatório pode ser nulo-
hostnamestring obrigatório -
idstring (uuid) obrigatório
-
-
statusstring obrigatórioopen: espera a equipe;answered: espera o cliente;resolved: resolvido. Um de:open,answered,resolved. -
subjectstring obrigatório -
unreadboolean obrigatórioHá resposta da equipe que a conta ainda não leu.
{ "can_rate": false, "category": "sales", "closed": false, "created_at": "2026-10-20T18:00:00Z", "expected": { "due_at": "2026-10-20T18:00:00Z", "target": "até 4 horas úteis" }, "follow_up_of": { "id": "0e37dfb9-2f9b-4ac0-a557-346d5265ae2f", "number": "FAT-0000123" }, "id": "f638f2ab-a5a5-45f6-886a-51b17661e088", "last_from": "customer", "last_message_at": "2026-10-20T18:00:00Z", "merged_into": { "id": "0e37dfb9-2f9b-4ac0-a557-346d5265ae2f", "number": "FAT-0000123" }, "messages": [ { "attachments": [ { "content_type": "image/png", "created_at": "2026-10-20T18:00:00Z", "file_name": "", "id": "bab8d9c9-1562-4059-820d-444a4445a168", "size_bytes": 0 } ], "author": "customer", "author_name": "Ana Souza", "body": "Obrigado, voltou a responder.", "created_at": "2026-10-20T18:00:00Z", "id": "90bd97e4-e575-44de-9d55-2b401363292c" } ], "number": "SUP-000123", "priority": "low", "purged": false, "rating": { "comment": "", "rated_at": "2026-10-20T18:00:00Z", "rating": "good" }, "resolved_at": null, "server": { "hostname": "web-01", "id": "b71b4464-1ef5-411f-a6f2-c5450d0a7616" }, "status": "open", "subject": "Servidor sem rede depois da reinstalação", "unread": false}Todo erro vem como application/problem+json (RFC 9457), com um code estável, a mensagem em português em detail, o motivo de cada campo em errors (nos erros de validação) e o request_id, que você informa ao suporte. Veja a lista completa de códigos.
| Status | Quando | Códigos |
|---|---|---|
| 400 | Requisição inválida (JSON malformado, campo desconhecido, parâmetro inválido ou falha de validação). | validation_failed, request.invalid_json |
| 401 | Não autenticado (token ausente, inválido ou expirado; credenciais inválidas). | auth.unauthorized |
| 403 | Autenticado, mas sem permissão para a área ou a operação. | api_token.insufficient_scope |
| 404 | Recurso não encontrado (ou fora do escopo do usuário). | ticket.not_found |
| 409 | Conflito (unicidade ou operação concorrente em andamento). | support.ticket_merged |
| 429 | Limite de requisições excedido. Retry-After diz em quantos segundos cabe a próxima requisição; os limites de taxa também mandam RateLimit-Policy e RateLimit (draft-ietf-httpapi-ratelimit-headers). |
rate_limited |
{ "type": "about:blank", "title": "Forbidden", "status": 403, "detail": "o token não tem o escopo support:write; crie um token com esse escopo em Desenvolvedores › Tokens de API", "code": "api_token.insufficient_scope", "request_id": "6f1c0b2a9e4d7c3b5a8f0e1d"}