Pular para o conteúdo principal

API pública

O helpdesk expõe uma única API pública: um endpoint GraphQL. Toda operação do schema é alcançável fora do navegador com um token de acesso pessoal (Personal Access Token, PAT).

Esta página é o contrato — o que é estável, como se autenticar, o que os escopos concedem e qual é o formato dos erros. A CLI hdmx é construída sobre ela, e o versionamento da API descreve como essa superfície evolui.

O endpoint​

POST https://<your-host>/backend/<subdomain>/api/<version>/graphql
  • <subdomain> identifica sua conta (o mesmo identificador que você usa para entrar).
  • <version> é uma versão datada da API, como 2026-07 — veja versionamento da API. Você também pode omitir o segmento de versão e chamar …/backend/<subdomain>/graphql; a requisição é então atendida pela versão mais antiga suportada, e cada resposta informa qual 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 expiração obrigatória), tem escopos, é restrito por IP e revogável. Ele está vinculado a uma conta: apresentar um token ao subdomínio de outra conta é rejeitado com HTTP 401.

Criar um token​

Crie e gerencie os tokens você mesmo no app do agente, em Settings → API tokens:

  1. Clique em New token.
  2. Dê a ele um nome que você reconheça depois.
  3. Escolha uma expiração (até 365 dias — não existe "nunca").
  4. Defina uma política de acesso — ative exatamente os recursos de que este token precisa, em leitura ou em leitura e escrita. Por padrão não há acesso a nada.
  5. Adicione pelo menos um endereço IP ou CIDR à lista de permitidos (obrigatório — veja Lista de IPs permitidos). O formulário pode adicionar seu IP atual para você.
  6. Revise e crie. O token completo é mostrado exatamente uma vez — copie-o imediatamente. Apenas um hash é armazenado, então ele nunca pode ser exibido de novo; se você o perder, faça a rotação do token para obter um novo.

Depois você pode editar a política de acesso e a lista de permitidos de um token, fazer sua rotação (emitir um novo segredo enquanto o antigo continua funcionando por um curto período de carência, para você migrar sem indisponibilidade) e revogá-lo. Cada token mostra quando e de onde foi usado pela última vez, além de um registro de atividade recente.

Escopos​

O acesso é de granularidade grossa e organizado por famílias de recursos. Um token carrega um conjunto fixo de escopos; toda operação de nível superior verifica um deles.

EscopoConcede
tickets:readLer tickets, mensagens, rascunhos, histórico, anexos, relatórios
tickets:writeCriar / atualizar / excluir tickets, publicar mensagens, enviar anexos. Implica tickets:read
chat:readLer chats, conversas, mensagens, sessões
chat:writeEnviar mensagens do agente, entrar / sair / fechar / reabrir conversas. Implica chat:read
customers:readLer registros de clientes
customers:writeCriar / atualizar / mesclar registros de clientes. Implica customers:read
settings:readLer configurações da conta (departamentos, status, prioridades, caixas de correio — sem segredos)

Os campos de credenciais das caixas de correio (usuários, senhas e hosts de IMAP/SMTP) nunca são devolvidos a um token, independentemente do escopo — esses segredos pertencem ao seu provedor de e-mail e permanecem fora do alcance da API pública.

Taxonomia de erros​

As respostas GraphQL usam errors[].extensions.code:

CódigoSignificadoHTTP
SCOPE_DENIEDO token não tem o escopo exigido. extensions.valid_values lista os escopos que satisfariam a operação200
RATE_LIMITEDO orçamento de requisições por token se esgotou. extensions.retryAfter são os segundos até a reinicialização, e o cabeçalho Retry-After traz o mesmo número429
INVALID_API_TOKENToken não encontrado, malformado ou inutilizável por outro motivo200

Tokens revogados, tokens expirados, incompatibilidades entre contas e recusas pela lista de IPs permitidos são rejeitados antes de a query rodar e aparecem como HTTP 401 sem corpo GraphQL. Trate um 401 em uma requisição com token como "este token não é mais válido para esta requisição — verifique sua expiração, seus escopos e sua lista de IPs permitidos".

Limites de taxa​

Toda requisição com token carrega cabeçalhos:

X-RateLimit-Limit: 120
X-RateLimit-Remaining: 96
X-RateLimit-Reset: 1715692800

O orçamento padrão é de 120 requisições por minuto por token. Cada requisição custa 1, seja de leitura ou de escrita. Ultrapassar retorna HTTP 429 com um cabeçalho Retry-After e extensions.code = "RATE_LIMITED"; um cliente bem-comportado espera até o instante de reinicialização.

Lista de IPs permitidos​

Todo token criado por autoatendimento precisa carregar pelo menos um IP ou CIDR — não existem tokens de "qualquer IP". O IP de origem de cada requisição é comparado com a lista do token; uma divergência é rejeitada com HTTP 401 e extensions.sub_code = "ip_not_allowed".

  • IPv4, IPv6 e faixas CIDR são todos aceitos. Use /32 (IPv4) ou /128 (IPv6) para um único host.
  • As faixas são validadas e normalizadas ao serem salvas.
  • A lista de permitidos pode ser editada após a 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 seus próprios servidores em uma faixa de IP conhecida. Um token vazado é inútil de qualquer lugar fora da sua lista de permitidos.

Atividade do token​

Toda requisição autenticada feita por um token é registrada: o horário, o nome da operação, o IP de origem, o resultado (sucesso, erro, limite de taxa, escopo negado, revogado ou expirado) e a latência de ida e volta. É esta a trilha 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 na URL e ela se mantém estável por no mínimo 12 meses; as descontinuações são anunciadas no próprio canal antes que algo que você usa desapareça. Veja Versionamento da API para a política completa.

Descoberta do schema​

O schema é autodescritivo: use a introspecção GraphQL padrão no 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 host helpdesk.example.com, o subdomínio acme, a versão 2026-07 e um token em $TOKEN.

Ler o usuário atual (qualquer escopo)​

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 essa superfície atrás de comandos ergonômicos.