API pública
O helpdesk expõe uma única API pública: um endpoint GraphQL. Todas as operações do schema são alcançáveis fora do browser com um token de acesso pessoal (Personal Access Token, PAT).
Esta página é o contrato — o que é estável, como autenticar-se, o que os âmbitos concedem e qual a forma dos erros. A CLI hdmx é construída sobre ela, e o versionamento da API descreve como esta superfície evolui.
O endpoint
POST https://<your-host>/backend/<subdomain>/api/<version>/graphql
<subdomain>identifica a sua conta (o mesmo identificador com que inicia sessão).<version>é uma versão datada da API, como2026-07— veja versionamento da API. Também pode omitir o segmento da versão e invocar…/backend/<subdomain>/graphql; o pedido é então servido pela versão mais antiga suportada, e cada resposta indica-lhe que versão respondeu.
Autenticação
Envie um token de acesso pessoal como credencial Bearer:
Authorization: Bearer hdmx_<random>
Um PAT é de longa duração (com validade obrigatória), tem âmbitos, é restringido por IP e revogável. Está ligado a uma única conta: apresentar um token ao subdomínio de outra conta é rejeitado com HTTP 401.
Criar um token
Crie e faça a gestão dos tokens você mesmo na aplicação de agente, em Settings → API tokens:
- Clique em New token.
- Dê-lhe um nome que reconheça mais tarde.
- Escolha uma validade (até 365 dias — não existe «nunca»).
- Defina uma política de acesso — ative exatamente os recursos de que este token precisa, em leitura ou em leitura e escrita. Por omissão não há acesso a nada.
- Adicione pelo menos um endereço IP ou CIDR à lista de permitidos (obrigatório — veja Lista de IP permitidos). O formulário pode adicionar o seu IP atual por si.
- Reveja e crie. O token completo é mostrado exatamente uma vez — copie-o de imediato. Apenas é guardado um hash, pelo que nunca poderá ser mostrado outra vez; se o perder, faça a rotação do token para obter um novo.
Mais tarde pode editar a política de acesso e a lista de permitidos de um token, fazer a sua rotação (emitir um novo segredo enquanto o antigo continua a funcionar durante um curto período de tolerância, para poder transitar sem indisponibilidade) e revogá-lo. Cada token mostra quando e de onde foi usado pela última vez, além de um registo da atividade recente.
Âmbitos
O acesso é de granularidade grossa e organizado por famílias de recursos. Um token transporta um conjunto fixo de âmbitos; cada operação de topo verifica um deles.
| Âmbito | Concede |
|---|---|
tickets:read | Ler tickets, mensagens, rascunhos, histórico, anexos, relatórios |
tickets:write | Criar / atualizar / eliminar tickets, publicar mensagens, carregar anexos. Implica tickets:read |
chat:read | Ler chats, conversas, mensagens, sessões |
chat:write | Enviar mensagens de agente, entrar / sair / fechar / reabrir conversas. Implica chat:read |
customers:read | Ler registos de clientes |
customers:write | Criar / atualizar / fundir registos de clientes. Implica customers:read |
settings:read | Ler as definições da conta (departamentos, estados, prioridades, caixas de correio — sem segredos) |
Os campos de credenciais das caixas de correio (nomes de utilizador, palavras-passe e servidores IMAP/SMTP) nunca são devolvidos a um token, qualquer que seja o âmbito — esses segredos pertencem ao seu fornecedor de email e ficam fora do alcance da API pública.
Taxonomia de erros
As respostas GraphQL usam errors[].extensions.code:
| Código | Significado | HTTP |
|---|---|---|
SCOPE_DENIED | Ao token falta o âmbito necessário. extensions.valid_values lista os âmbitos que satisfariam a operação | 200 |
RATE_LIMITED | O orçamento de pedidos por token esgotou-se. extensions.retryAfter são os segundos até à reposição, e o cabeçalho Retry-After traz o mesmo número | 429 |
INVALID_API_TOKEN | Token não encontrado, malformado ou inutilizável por outro motivo | 200 |
Tokens revogados, tokens expirados, incompatibilidades entre contas e recusas pela lista de IP permitidos são rejeitados antes de a query correr e surgem como HTTP 401 sem corpo GraphQL. Trate um 401 num pedido com token como «este token já não é válido para este pedido — verifique a validade, os âmbitos e a lista de IP permitidos».
Limites de taxa
Cada pedido com token traz cabeçalhos:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 96
X-RateLimit-Reset: 1715692800
O orçamento por omissão é de 120 pedidos por minuto por token. Cada pedido custa 1, quer leia quer escreva. Ultrapassá-lo devolve HTTP 429 com um cabeçalho Retry-After e extensions.code = "RATE_LIMITED"; um cliente bem comportado aguarda até ao momento da reposição.
Lista de IP permitidos
Todo o token criado em autosserviço tem de conter pelo menos um IP ou CIDR — não existem tokens de «qualquer IP». O IP de origem de cada pedido é comparado com a lista do token; uma não correspondência é rejeitada com HTTP 401 e extensions.sub_code = "ip_not_allowed".
- São aceites IPv4, IPv6 e gamas CIDR. Use
/32(IPv4) ou/128(IPv6) para um único servidor. - As gamas são validadas e normalizadas ao gravar.
- A lista de permitidos é editável depois da criação — editá-la não altera o segredo.
Use um token a partir de uma saída estável: um runner de CI, uma tarefa agendada, um NAT de escritório fixo ou os seus próprios servidores numa gama de IP conhecida. Um token divulgado é inútil a partir de qualquer sítio fora da sua lista de permitidos.
Atividade do token
Cada pedido autenticado feito por um token é registado: a hora, o nome da operação, o IP de origem, o resultado (sucesso, erro, limite de taxa, âmbito negado, revogado ou expirado) e a latência de ida e volta. É este o rasto a consultar se um token se comportar de forma inesperada.
Versionamento e descontinuação
A API é versionada com versões datadas YYYY-MM. Fixe uma no URL e mantém-se estável durante pelo menos 12 meses; as descontinuações são anunciadas no próprio canal antes de desaparecer algo que utilize. Veja Versionamento da API para a política completa.
Descoberta do schema
O schema é autodescritivo: use a introspeção GraphQL padrão sobre o endpoint versionado para gerar tipos e explorar a superfície. O GraphQL Playground interativo está disponível em …/backend/<subdomain>/playground.
Início rápido com curl
Estes exemplos assumem o servidor helpdesk.example.com, o subdomínio acme, a versão 2026-07 e um token em $TOKEN.
Ler o utilizador atual (qualquer âmbito)
curl -sS https://helpdesk.example.com/backend/acme/api/2026-07/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"{ currentUser { id email firstname lastname } }"}'
Listar tickets recentes (tickets:read)
curl -sS https://helpdesk.example.com/backend/acme/api/2026-07/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query ($first: Int!) {
ticketList(first: $first) {
edges { node { code subject status { name } updatedAt } }
}
}",
"variables": { "first": 10 }
}'
Publicar uma resposta pública (tickets:write)
curl -sS https://helpdesk.example.com/backend/acme/api/2026-07/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "mutation ($input: SaveTicketInput!) {
saveTicket(input: $input) {
ticket { code }
error { code message }
}
}",
"variables": {
"input": {
"id": "TICKET-UUID-HERE",
"message": "Thanks — fixing this now.",
"messageType": "PUBLIC"
}
}
}'
Para o dia a dia, a CLI hdmx envolve toda esta superfície atrás de comandos ergonómicos.