API Gototem Partner — guia do desenvolvedor
Guia para o desenvolvedor do sistema parceiro: como abrir chamados no help desk da Gototem a partir do seu sistema.
Nesta página
Visão geral
A API permite que o seu sistema (por exemplo, um atendimento por chat) abra chamados no help desk da Gototem em nome do cliente atendido. O seu sistema escolhe a categoria, a prioridade, o nível de suporte e a natureza a partir de uma lista que a própria API fornece, e recebe de volta o número do chamado e o que foi gravado nele.
Endereço base de produção: https://api.gototem.com.br. Em homologação, o suporte informa o
endereço junto com a chave.
Só existe a versão 1, sempre com /v1/ no caminho, e sem barra no fim (help-desk-ticket-options/ não é rota e recebe 404).
As respostas são JSON em UTF-8, e as recusas da própria API vêm em application/problem+json, com type, title, status, detail e code. Algumas recusas vêm do servidor, antes da API e sem code (um 404 e um 400 do webhook), e um caminho fora da API recebe uma página HTML: por isso, confira o status antes de ler o corpo como JSON, como fazem os exemplos deste guia (ver Erros).
As rotas, uma a uma, com o corpo, a resposta e os erros de cada uma, estão na referência da API, gerada do contrato.
Autenticação
A API não tem usuário e senha, e não usa conta nem licença: cada sistema parceiro tem uma chave, que identifica o sistema e diz o que ele pode fazer.
Como obter a chave
O suporte da Gototem cadastra o seu sistema e entrega uma chave no formato gtes_ seguido de 43 caracteres.
A chave não é mostrada de novo: guarde-a como diz Onde a chave deve ficar.
Junto com a chave, o suporte informa os escopos liberados (abaixo) e o identificador do seu sistema, usado no webhook. Nenhuma rota devolve esses dois dados: guarde-os com a chave.
Como enviar a chave
Envie a chave em toda chamada, no cabeçalho Authorization:
Authorization: Bearer gtes_SuaChaveAqui
A palavra Bearer vale em maiúsculas ou minúsculas. Envie a chave só por HTTPS.
Envie só o Authorization: um cabeçalho de autenticação de outro sistema da Gototem é recusado (ver Erros).
Sem a chave, ou com uma chave que não vale, a resposta é 401 unauthorized; com a chave válida e
sem o escopo da rota, 403 forbidden_scope.
O que a chave libera
A chave também define o que o seu sistema pode fazer (abrir chamados, enviar leads). Chamada fora do que foi liberado recebe 403 forbidden_scope. Cada rota da referência diz, ao lado do endereço, o escopo que exige:
| Escopo | O que libera |
|---|---|
help-desk-ticket.create |
Consultar as opções (help-desk-ticket-options), abrir chamado (help-desk-ticket) e abrir chamado por webhook. |
lead.create |
Enviar lead (lead). Ainda não disponível: ver Enviar um lead. |
A primeira chamada
Os exemplos leem a chave de uma variável de ambiente, GOTOTEM_INTEGRATION_KEY. No seu servidor, ela vem do cofre de segredos; para testar, defina-a no terminal em que você vai rodar os exemplos:
export GOTOTEM_INTEGRATION_KEY="<a chave que o suporte entregou>"
$env:GOTOTEM_INTEGRATION_KEY = "<a chave que o suporte entregou>"
Os exemplos vêm em cinco linguagens: bash (o terminal do Linux, do macOS ou o Git Bash, com o comando curl), PowerShell (o Windows PowerShell 5.1 ou o PowerShell 7), Python (com a biblioteca requests), JavaScript (o fetch do Node 18 ou mais novo, num arquivo .mjs) e PHP (com a extensão curl). Escolha a sua numa aba: a escolha vale para todos os exemplos da página e fica guardada neste navegador. Os exemplos em Python, JavaScript e PHP leem a mesma variável de ambiente. Os ids dos exemplos são ilustrativos e variam por ambiente: use os que a sua consulta devolver.
A primeira chamada consulta as opções que o seu sistema pode usar ao abrir um chamado. É a chamada mais simples da API: não tem corpo e não cria nada.
curl -s https://api.gototem.com.br/v1/api-external-system/help-desk-ticket-options \ -H "Authorization: Bearer $GOTOTEM_INTEGRATION_KEY"
try {
$response = Invoke-WebRequest -UseBasicParsing `
-Uri 'https://api.gototem.com.br/v1/api-external-system/help-desk-ticket-options' `
-Headers @{ Authorization = "Bearer $env:GOTOTEM_INTEGRATION_KEY" }
# o corpo é UTF-8: lido assim, o acento sai certo também no Windows PowerShell 5.1
[Text.Encoding]::UTF8.GetString($response.RawContentStream.ToArray()) | ConvertFrom-Json
} catch {
$refusal = $_.Exception.Response
if ($null -eq $refusal) { throw }
"HTTP $([int]$refusal.StatusCode) (X-Request-Id $($refusal.Headers.GetValues('X-Request-Id')))"
}
import os
import requests
resp = requests.get(
"https://api.gototem.com.br/v1/api-external-system/help-desk-ticket-options",
headers={"Authorization": "Bearer " + os.environ["GOTOTEM_INTEGRATION_KEY"]},
timeout=30,
)
if resp.status_code == 200:
print(resp.json())
else:
print("HTTP", resp.status_code, resp.headers.get("X-Request-Id"), resp.text)
const response = await fetch('https://api.gototem.com.br/v1/api-external-system/help-desk-ticket-options', {
headers: { Authorization: 'Bearer ' + process.env.GOTOTEM_INTEGRATION_KEY },
});
if (response.status === 200) {
console.log(await response.json());
} else {
console.log('HTTP ' + response.status, response.headers.get('X-Request-Id'), await response.text());
}
<?php
$curl = curl_init('https://api.gototem.com.br/v1/api-external-system/help-desk-ticket-options');
curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('GOTOTEM_INTEGRATION_KEY')],
CURLOPT_TIMEOUT => 30,
]);
$raw = curl_exec($curl);
if ($raw === false) {
throw new RuntimeException('Rede: ' . curl_error($curl));
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
echo 'HTTP ', $status, PHP_EOL;
print_r($status === 200 ? json_decode($raw, true) : $raw . PHP_EOL);
No Windows PowerShell 5.1, se a chamada falhar com erro de conexão segura, rode antes [Net.ServicePointManager]::SecurityProtocol = 'Tls12'; e, se salvar o exemplo num arquivo .ps1, salve-o em UTF-8 com BOM, senão o acento do corpo do chamado chega trocado. No Git Bash do Windows, o acento escrito dentro do -d do curl sai na codificação do Windows e o corpo é recusado (422 invalid_body): grave o corpo num arquivo em UTF-8 e envie com --data-binary @corpo.json.
Veio 200? A chave funciona. A resposta traz as categorias liberadas para o seu sistema e as empresas, prioridades, níveis e naturezas ativas; o exemplo completo e o significado de cada campo estão na referência da rota. 401 quer dizer que a chave não foi aceita; 403, que o sistema está desativado ou sem o escopo (ver Erros).
O próximo passo é abrir o primeiro chamado: veja Abrir um chamado.
Contrato e ferramentas
Três arquivos acompanham este guia, publicados ao lado dele: o contrato OpenAPI, a coleção pronta para o Postman e o Insomnia e um resumo para agentes de IA. Nenhum deles precisa de chave.
Contrato OpenAPI
O contrato completo, com todos os campos e respostas, está em openapi.yaml e, em JSON, em openapi.json. Use-o para gerar um cliente ou validar chamadas.
Se você gerar cliente a partir dele, não transforme o code de erro ou de aviso em enumeração
fechada: no contrato ele é texto, com os valores conhecidos listados em x-extensible-enum, e um
código novo pode surgir a qualquer momento (ver Versões e compatibilidade).
Não gere cliente para a rota de lead, que ainda não está disponível.
Coleção do Postman e do Insomnia
Para chamar a API sem escrever código, use a coleção. Ela é gerada do contrato e traz uma requisição para cada rota que já está no ar, com o corpo de exemplo.
- Baixe o arquivo
postman.json. - Postman: clique em Import e escolha o arquivo. Insomnia: use Import e escolha o mesmo arquivo (o Insomnia lê coleções do Postman).
- Abra as variáveis da coleção e preencha
api_keycom a chave que o suporte entregou.base_urljá vem com o endereço de produção; em homologação, troque pelo endereço que o suporte informou. Na requisição do webhook, preencha a variável de caminhosystemcom o identificador do seu sistema. - Envie O que o seu sistema pode escolher ao abrir um chamado primeiro: os ids do corpo de exemplo de Abre um chamado no help desk são ilustrativos e têm de ser trocados pelos que essa consulta devolver.
A coleção chama a API de verdade: um chamado enviado por ela é aberto no help desk da Gototem.
llms.txt
O arquivo llms.txt é um resumo desta API em texto puro, para agentes de IA: o endereço base, de onde vem a chave, as rotas no ar e os links para o contrato e para este guia. Aponte o seu agente para ele antes de pedir que escreva a integração.
Segurança
Trate a chave como uma senha: quem a tem abre chamados no help desk da Gototem em nome do seu sistema.
Onde a chave deve ficar
Guarde a chave num cofre de segredos do seu servidor e entregue-a ao processo por variável de
ambiente, como fazem os exemplos deste guia (GOTOTEM_INTEGRATION_KEY). Ela nunca vai no
código-fonte, num repositório, no navegador nem num aplicativo distribuído. A chave é mostrada uma
única vez, na entrega: se ela se perder, peça uma chave nova ao suporte.
Rotação da chave
Quando o suporte gera uma chave nova, a anterior continua valendo por 24 horas (o padrão; se o suporte combinou outro prazo, vale o combinado): atualize os servidores um a um dentro desse prazo. Passado o prazo, o servidor que ainda usar a anterior recebe 401; troque a chave dele e não repita a chamada em laço (ver Os casos do 429).
Se a chave vazou, peça ao suporte que pare a anterior na hora: aí ela deixa de valer no mesmo instante.
Quem troca a chave é o suporte da Gototem: o seu sistema não a rotaciona nem a revoga por rota nenhuma.
Como saber o estado da chave
Não se aplica a esta API: nenhuma rota informa o estado ou a validade da chave. Chave que deixou de
valer responde 401 unauthorized, e sistema desativado responde 403 system_inactive (ver
Erros).
Para conferir a chave e o escopo sem abrir chamado, chame GET help-desk-ticket-options: 200
confirma os dois.
Glossário
| Termo | O que é |
|---|---|
| Sistema | O cadastro do seu sistema na Gototem, feito pelo suporte. A chave pertence a ele. |
| Identificador do sistema | O nome curto do seu cadastro (letras minúsculas, números, - e _), informado pelo suporte junto com a chave. Vai no endereço do webhook. |
| Chave | O segredo que autentica o seu sistema, no formato gtes_ seguido de 43 caracteres. |
| Escopo | O que a chave pode fazer: help-desk-ticket.create ou lead.create (ver O que a chave libera). |
| Chamado | O registro aberto no help desk da Gototem a partir do seu atendimento. |
external_id |
O id do atendimento no seu sistema. É por ele que um reenvio é reconhecido (ver Reenvio e idempotência). |
| Tipo | O grupo da categoria: Incidente, Problema, Solicitação de Serviço ou Solicitação de Mudança. Não vai no chamado: escolher a categoria já define o tipo. |
| Categoria | O assunto do chamado, dentro de um tipo. O seu sistema usa a categoria padrão e as que o suporte liberou. |
| Empresa, prioridade, nível de suporte e natureza | As outras escolhas do chamado, sempre a partir das listas de Consultar as opções. |
| Rotas JSON | As rotas que exigem o corpo em JSON: help-desk-ticket e lead (ver Formatos e convenções). |
| Webhook | O endereço para abrir chamado a partir de uma ferramenta de webhook (ver Abrir um chamado com webhook). |
applied |
O bloco da resposta com o que foi gravado no chamado (ver Ler a resposta). |
warnings |
Os avisos da resposta: escolha trocada pelo padrão, CNPJ ignorado, campos fora do contrato, solicitante cortado ou reenvio com outra descrição (ver Avisos). |
Formatos e convenções
As respostas são JSON em UTF-8.
Neste guia, rotas JSON são as que exigem o corpo em JSON: help-desk-ticket e lead. Nelas, envie Content-Type: application/json (; charset=utf-8 também vale, e também um tipo com o sufixo +json, como application/vnd.exemplo+json), com o tipo em minúsculas; sem ele, com outro ou em maiúsculas (Application/JSON), a resposta é 415 unsupported_media_type. O webhook aceita qualquer Content-Type.
Num campo opcional do corpo, null é o mesmo que não enviar o campo. Num campo obrigatório, null vale como ausente.
Datas e fuso
Não se aplica a esta API: nenhuma rota recebe nem devolve data.
Dinheiro
Não se aplica a esta API: nenhuma rota recebe nem devolve valor em dinheiro.
Identificadores
Os ids de categoria, de prioridade e de nível de suporte são números inteiros; o id de empresa
e o identifier da natureza são texto.
- Envie os ids como número inteiro:
"category": 3, nunca"category": "3". Um id enviado como texto ("3") ou com fração (3.5) não é reconhecido: o chamado é aberto com a opção padrão e a resposta traz um aviso de troca. O inteiro com casa decimal zero (3.0, que algumas bibliotecas produzem ao serializar número) vale como o inteiro. - Os ids mudam entre homologação e produção e podem mudar com o tempo: leia-os de
help-desk-ticket-optionse nunca os fixe no código. - O
tickete oidda resposta são opacos: guarde-os e mostre-os como vieram, sem deduzir nada da forma deles.
Paginação
Não se aplica a esta API: nenhuma rota devolve lista paginada.
Limites de uso
| O que | Limite |
|---|---|
| Chamadas por minuto, por sistema | 120 (o suporte pode combinar outro) |
| Corpo da chamada | 65.536 bytes em UTF-8 |
external_id |
120 caracteres |
description |
20.000 caracteres |
requester.name e requester.contact |
120 e 160 caracteres (o excedente é cortado, com o aviso requester_truncated) |
| Chamadas repetidas com chave errada, do mesmo IP | bloqueiam o IP por até um minuto |
Acima do limite, external_id e description recebem 422 field_too_long, sem corte. Só esses dois campos são recusados por tamanho: o requester é cortado, e a resposta traz o aviso requester_truncated. O corpo acima do teto recebe 413 payload_too_large; o teto é em bytes, e não em caracteres (ver Montar e enviar o corpo).
Toda resposta depois da conferência do limite (o chamado criado, o reenvio, as opções, e também o 403 forbidden_scope, os 422 dos campos e o próprio 429) traz o saldo em três cabeçalhos:
X-RateLimit-Limit: 120 X-RateLimit-Remaining: 117 X-RateLimit-Reset: 1791481927
X-RateLimit-Limité o limite por janela, eX-RateLimit-Remaining, quantas chamadas ainda cabem.X-RateLimit-Reseté o instante, em segundos Unix, em que a chamada mais antiga da janela deixa de contar e o saldo sobe; com saldo0, é quando a próxima chamada passa.- Sem os três cabeçalhos, o limite não está sendo medido naquela chamada: trate a ausência como "sem informação", nunca como limite zero.
Use-os para espaçar as chamadas antes de chegar ao 429.
O limite e o saldo são do sistema, não de cada servidor nem de cada chave: todos os seus servidores, e também a chave anterior durante uma troca, gastam o mesmo saldo. Por isso ele pode cair mais do que as chamadas de um servidor explicam.
Os casos do 429
Ao passar de um limite, a resposta é 429 rate_limited, com o cabeçalho Retry-After em segundos. São dois casos:
| Quem recusou | Retry-After |
X-RateLimit-* |
|---|---|---|
| A cota do seu sistema: 120 chamadas por minuto, ou o combinado com o suporte | a espera real até a próxima chamada passar | vêm, com X-RateLimit-Remaining: 0 |
| O IP bloqueado por chamadas repetidas com chave errada | a espera real, até um minuto | não vêm: o seu sistema ainda não foi identificado |
O Retry-After é a espera real, e não a janela inteira; só quando o servidor não consegue medir a espera ele manda a janela inteira. Espere esse tempo antes de tentar de novo, com o mesmo external_id; não reenvie em laço. No código, basta esperar o Retry-After: a diferença entre os casos serve para investigar.
O IP bloqueado. Chamadas repetidas com chave errada, vindas do mesmo IP, bloqueiam esse IP por até um minuto, mesmo com a chave certa. Pare de repetir, confira a chave e espere o Retry-After.
A chave anterior do seu sistema, depois do prazo da troca, recebe 401 mas não conta para o bloqueio do IP: numa troca, você pode atualizar os servidores um a um (ver Rotação da chave).
Erros
Toda recusa desta API traz code e tem o mesmo formato, em application/problem+json:
type: sempreabout:blank(o erro é identificado pelocode);title: o nome do status HTTP, em inglês (Unprocessable Entity);status: o status HTTP, como número;detail: a explicação, em inglês;code: o que o seu código usa.
Programe contra o code; o detail é para leitura humana, vem em inglês e pode mudar. O code é texto aberto: o que você não conhecer, trate pelo status HTTP, sem falhar (ver Contrato OpenAPI). As recusas que vêm do servidor, antes da API, chegam sem code: estão na tabela abaixo (linhas sem code) e em Os casos do 404.
Nos 422 de um campo do corpo vem também param, com o nome do campo (external_id, description, company, nature, requester.name ou requester.contact); no 403 forbidden_scope, vem required_scope, com o escopo que a rota exige e a chave não tem:
{
"type": "about:blank",
"title": "Unprocessable Entity",
"status": 422,
"detail": "Unknown company. Use one of: gototem, melhoretec.",
"code": "invalid_company",
"param": "company"
}
Toda resposta das rotas desta API traz o cabeçalho X-Request-Id, inclusive as recusas. Ao falar com o suporte sobre uma chamada, informe esse valor: é por ele que a achamos no nosso registro (ver O que enviar ao pedir ajuda). O 404 que vem sem code, e o único que não traz o X-Request-Id, estão em Os casos do 404.
| HTTP | code |
Quando | O que fazer |
|---|---|---|---|
| 400 | conflicting_credentials |
Veio um cabeçalho de autenticação de outro sistema da Gototem. O detail é informativo e pode mudar. |
Remova o cabeçalho e envie só o Authorization. |
| 400 | (application/problem+json, sem code) |
Só no webhook, com Content-Type JSON: o corpo não é objeto nem lista JSON (JSON quebrado, texto que não é UTF-8, ou um valor sozinho como "oi" ou 5). Quem recusa é o servidor, depois da chave. |
Corrija o corpo. |
| 401 | unauthorized |
Chave ausente, fora do formato ou que não vale; no webhook, também identificador desconhecido ou chave de outro sistema. Traz o cabeçalho WWW-Authenticate: Bearer. |
Confira o cabeçalho Authorization; se a chave foi trocada, use a nova. Não repita em laço (Os casos do 429). |
| 403 | system_inactive |
O seu sistema está desativado na Gototem. | Fale com o suporte e guarde o chamado (Corrigir, reenviar ou falar com o suporte). |
| 403 | forbidden_scope |
O seu sistema não tem o escopo da rota (O que a chave libera). O campo required_scope diz o escopo que falta. |
Peça a liberação desse escopo ao suporte e guarde o chamado. |
| 404 | not_found |
O endereço está errado: o caminho começa com /v1/api-external-system/, mas não é rota desta API, ou é desta API em outra versão ou sem versão. O 404 tem outros casos, sem code. |
Corrija o endereço; veja Os casos do 404. |
| 405 | method_not_allowed |
Método HTTP diferente do da rota. Traz o cabeçalho Allow com o método aceito. |
Use o método do Allow (ver abaixo). |
| 413 | payload_too_large |
Corpo acima de 65.536 bytes, contados como enviado. | Encurte a descrição, ou envie o JSON sem escapar o Unicode (Montar e enviar o corpo). |
| 415 | unsupported_media_type |
Numa rota JSON, corpo sem Content-Type: application/json (Formatos e convenções). |
Envie Content-Type: application/json. |
| 422 | invalid_body |
O corpo não é um objeto JSON: JSON quebrado, UTF-8 inválido, texto ("oi"), lista ou número. |
Envie um objeto JSON válido, em UTF-8. |
| 422 | invalid_field |
Um texto (external_id, description, requester.name ou requester.contact) tem o caractere NUL (\u0000). O param diz qual. |
Remova o caractere do campo. |
| 422 | missing_external_id |
Sem external_id. |
Envie o id do atendimento. |
| 422 | missing_description |
Sem description. |
Envie o relato. |
| 422 | missing_company |
Sem company (o detail lista as válidas). |
Envie um id de companies. |
| 422 | field_too_long |
external_id ou description acima do limite (Limites de uso). |
Encurte o campo. |
| 422 | invalid_company |
Empresa desconhecida ou inativa (o detail lista as válidas). |
Use um id de companies. |
| 422 | invalid_nature |
Natureza desconhecida ou inativa. | Consulte as opções de novo e use um identifier de natures, ou remova o campo. |
| 429 | rate_limited |
Limite de chamadas atingido. | Espere os segundos do Retry-After (Os casos do 429). |
| 500 | misconfigured_system |
O cadastro do seu sistema na Gototem está incompleto. | Fale com o suporte e guarde o chamado. |
| 500 | internal_error |
Falha inesperada do nosso lado. | Tente de novo em alguns minutos, com o mesmo external_id. |
| 501 | not_implemented |
Rota de lead, ainda não disponível. | Não integre a rota (Enviar um lead). |
| 503 | temporarily_unavailable |
A API está desligada por um tempo, em qualquer rota. Traz o cabeçalho Retry-After, em segundos. Sai antes da chave e não conta no limite de chamadas. |
Guarde o chamado e reenvie depois do Retry-After, com o mesmo external_id; nunca o descarte. Se durar, fale com o suporte. |
Método errado. Um método diferente do da rota (por exemplo, GET em help-desk-ticket) recebe 405 method_not_allowed, com o cabeçalho Allow dizendo o método aceito. HEAD numa rota GET também recebe 405: use GET. OPTIONS é diferente: ele exige a chave, conta no limite de chamadas e recebe 200 sem corpo, com o Allow.
Cabeçalho de outro sistema. Um cabeçalho de autenticação de outro sistema da Gototem é recusado com 400 conflicting_credentials ou com um 404 em application/problem+json, sem code. Nos dois casos, remova o cabeçalho e envie só o Authorization.
Os casos do 404
O 404 é sempre erro de endereço: corrija-o antes de reenviar. A API desligada não responde 404, e sim 503 temporarily_unavailable (ver Erros). O 404 tem três formas; separe-as pelo corpo:
| HTTP | Como vem | O que quer dizer | O que fazer |
|---|---|---|---|
| 404 | not_found |
Em application/problem+json, com o X-Request-Id. O caminho começa com /v1/api-external-system/, mas não é rota: erro de digitação, barra no fim (help-desk-ticket-options/) ou {system} fora do padrão no webhook. Ou o caminho é desta API em outra versão ou sem versão (/v2/api-external-system/..., /api-external-system/...). |
Confira o endereço contra a referência da API: só existe a versão 1, com /v1/. Reenviar igual não resolve. |
| 404 | (application/problem+json, sem code) |
Veio um cabeçalho de autenticação de outro sistema da Gototem. Quem recusa é o servidor, antes da API. Traz o X-Request-Id. |
Remova o cabeçalho e envie só o Authorization. |
| 404 | página HTML, sem X-Request-Id |
O caminho está fora desta API, como /v1/api-external-system sem a barra final ou /v1/outra-coisa: a chamada não chega a esta API. |
Corrija o endereço. |
Corrigir, reenviar ou falar com o suporte
Cada recusa cai num destes três grupos:
- Corrija antes de reenviar:
400,401, todo404(é sempre erro de endereço, em qualquer das três formas),405,413,415e422. Reenviar a mesma chamada não resolve. - Reenvie depois, com o mesmo
external_id:429(depois dos segundos doRetry-After),500 internal_error(em alguns minutos),503 temporarily_unavailable(a API está desligada por um tempo: depois dos segundos doRetry-After) e falha de rede ou tempo esgotado. - Fale com o suporte e guarde o chamado para reenviar depois da correção, com o mesmo
external_id:403 system_inactive,403 forbidden_scopee500 misconfigured_system. O501 not_implementedsó vem da rota de lead, que ainda não deve ser integrada.
Em nenhum desses casos o chamado do seu cliente precisa ser descartado: guardado, ele entra com o mesmo external_id quando a causa for resolvida, sem duplicar (Reenvio e idempotência).
Ordem das conferências
A API responde um problema por chamada. Quando há mais de um, corrigir um pode revelar o seguinte: por exemplo, um 415 corrigido vira 401 se a chave também estiver errada.
Antes de tudo, inclusive da chave, sai o 503 temporarily_unavailable: com a API desligada, toda chamada o recebe, sem contar no limite. Saem também antes da conferência da chave, e não contam no limite de chamadas do seu sistema: o 400 conflicting_credentials, o 404, 405, 413, 415 e, nas rotas JSON, o 422 invalid_body. O 413 sai antes da chave em toda rota, inclusive no webhook. Os 422 dos campos saem por último (no webhook, o invalid_body e o 400 do corpo que não é objeto nem lista JSON também saem depois da chave).
Versões e compatibilidade
A v1 só muda de forma aditiva: campo novo na resposta, aviso novo em warnings e code de erro novo podem surgir a qualquer momento, então ignore o que não conhecer (o erro desconhecido, trate pelo status HTTP). Remover um campo ou mudar o tipo dele só numa v2, avisada antes. Para quem gera cliente a partir do contrato, veja Contrato OpenAPI.
As mudanças de forma até 2026-10-15 vieram antes da primeira integração, quando nenhum sistema tinha chave: foram o último ajuste de forma da v1.
Histórico de mudanças
- 2026-10-15 — Quebra, feita antes da primeira integração: a API desligada passou a responder
503 temporarily_unavailablecomRetry-After(antes,404sem corpo); o caminho de outra versão ou sem versão passou a receber o404 not_found(antes,404sem corpo); toda recusa passou a vir emapplication/problem+json, comtype,title,status,detailecode(o campomessagedo erro saiu; o texto está emdetail); a frase do400 conflicting_credentialspassou a ser a do contrato. Acréscimos:required_scopeno403 forbidden_scope, o avisorequester_truncated(solicitante cortado) e o avisodescription_differs(reenvio com outra descrição). - 2026-10-14 — Nome: a API passou a se chamar API Gototem Partner (antes, API de integração). Nenhuma rota, chave ou endereço mudou.
- 2026-10-12 (9) — A documentação saiu da API e passou a ser publicada só no portal do
desenvolvedor: os endereços
/v1/api-external-system/docse/v1/api-external-system/docs/openapi.yamlrespondem404. Nenhuma rota da API mudou. - 2026-10-12 (8) — Comportamento: depois de uma troca de chave, a anterior continua valendo por 24 horas (antes parava no ato), e a anterior vencida não conta mais para o bloqueio do IP (ver Rotação da chave).
- 2026-10-12 (7) — Comportamento: o IP do bloqueio por chaves erradas passou a ser o do servidor
que se conecta à API, nunca um header que o cliente escreva; em IPv6, conta o bloco
/64inteiro. - 2026-10-12 (6) — Forma: o
404do caminho que começa com/v1/api-external-system/mas não é rota ganhou o corpo{"code", "message"}(not_found; antes, a página HTML do servidor). O404sem corpo, o que manda guardar e reenviar, não mudou. - 2026-10-12 (5) — Forma: o
405ganhou o corpo{"code", "message"}(method_not_allowed, comAllow) e passou a sair antes da chave, sem contar no limite. - 2026-10-12 (4) — Comportamento: caracteres invisíveis e de controle passaram a ser retirados de
external_ide dorequester(o NUL continua recusado). - 2026-10-12 (3) — Aditiva: o campo
paramnos422dos campos, com o nome do campo recusado. - 2026-10-12 (2) — Aditiva: o aviso
ignored_fieldsemwarningspara campo fora do contrato (o chamado é aberto do mesmo jeito). - 2026-10-12 (1) — Aditiva: os headers
X-RateLimit-Limit,X-RateLimit-RemainingeX-RateLimit-Resetem toda resposta depois da conferência do limite do sistema, e oRetry-Afterdo429com a espera real (antes, a janela inteira). - 2026-10-11, todas aditivas: a resposta do chamado ganhou o bloco
applied, com o que foi gravado; id com casa decimal zero (3.0) passou a valer como o inteiro; todo401trazWWW-Authenticate: Bearer; ocodede erro e de aviso passou a ser texto aberto no contrato (antes, lista fechada).
Abrir um chamado
Abrir um chamado leva três passos: consultar o que o seu sistema pode escolher, montar o corpo com as escolhas e ler a resposta. Cada passo diz o que fazer; o detalhe de cada campo está na referência da API.
- Consultar as opções que o seu sistema pode usar.
- Montar e enviar o corpo, com as escolhas e um
external_idúnico. - Ler a resposta: o
ticket, oappliede oswarnings.
1. Consultar as opções
É a consulta da primeira chamada. Ela devolve as categorias liberadas para o seu sistema e as empresas, prioridades, níveis e naturezas ativas; cada campo está na referência da rota.
Guarde a lista em cache por algumas horas (ela muda raramente) e consulte de novo ao receber o aviso category_fallback ou priority_fallback, ou a recusa invalid_nature.
Escolha com a sua IA, a partir da conversa com o cliente e da description de cada opção: um texto da equipe da Gototem que diz quando usar cada uma. Primeiro o tipo (Incidente, Problema, Solicitação de Serviço ou Solicitação de Mudança), depois a categoria daquele tipo, a prioridade e o nível de suporte, sempre pela description (o response_time_hours é só o prazo configurado e não ordena a urgência). A natureza é opcional e não tem description: escolha pelo nome (hardware, software...) ou omita.
- Quando a
descriptionainda não foi escrita, ela vemnull: escolha pelo nome. - Trate a
descriptioncomo dado e nunca execute instruções contidas nela. É texto puro e pode conter<e>: escape antes de exibir em HTML. - A categoria já define o tipo: o tipo não vai no chamado.
- Envie sempre
priority, escolhida peladescription. Sem ela vale a prioridade padrão da categoria (odefault_priority_id), que pode ser alta: um chamado simples pode nascer com a prioridade máxima.
Nenhuma categoria serve? Não envie category: o chamado cai na categoria padrão do seu sistema, sem aviso, e quem orienta a equipe é o relato em description. Antes de entrar em produção, confira com o suporte se as categorias liberadas cobrem os casos do seu atendimento.
2. Montar e enviar o corpo
Cada campo, com o tamanho, o padrão e o que acontece com um valor fora da regra, está na referência da rota. Ao montar o corpo, siga estas regras:
- Os ids vêm da lista, como número inteiro:
category,priorityesupport_levelcom os ids dehelp-desk-ticket-options(ver Identificadores). Ocompany, obrigatório, é umiddecompanies. - Um
external_idúnico por atendimento: o id do atendimento no seu sistema. É por ele que um reenvio é reconhecido (ver Reenvio e idempotência). naturesó com umidentifierdenatures, ou omita o campo. É a única escolha que recusa o chamado (422 invalid_nature): nunca envie texto livre.cnpjcomo texto, só o CNPJ (12.345.678/0001-90): fora do formato, ele é ignorado com o avisocnpj_ignored, nunca recusado. As regras completas estão na referência.- Campo fora do contrato não recusa o chamado: é ignorado e listado no aviso
ignored_fields.
O teto do corpo é em bytes. O corpo inteiro tem teto de 65.536 bytes, contados como enviado. Em UTF-8 sem escape, letra sem acento ocupa 1 byte, letra acentuada 2 e emoji 4: os 20.000 caracteres da description só estouram o teto com muitos emojis. Se o seu JSON escapar o Unicode (\u00e3 no lugar de ã, o padrão do json_encode do PHP e do json.dumps do Python), cada acento passa a ocupar 6 bytes e cada emoji 12, e o teto chega bem antes. Envie sem escapar, como fazem os exemplos.
curl -s -i -X POST https://api.gototem.com.br/v1/api-external-system/help-desk-ticket \
-H "Authorization: Bearer $GOTOTEM_INTEGRATION_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_id": "conv-8841",
"company": "gototem",
"description": "Cliente relata que o totem não imprime o cupom.",
"category": 3,
"priority": 3,
"support_level": 1,
"nature": "hardware",
"requester": {"name": "Maria Souza", "contact": "maria@loja.com.br"},
"cnpj": "12.345.678/0001-90"
}'
# -i mostra o status e os cabeçalhos (inclusive o X-Request-Id) antes do corpo
$body = [ordered]@{
external_id = 'conv-8841'
company = 'gototem'
description = 'Cliente relata que o totem não imprime o cupom.'
category = 3
priority = 3
support_level = 1
nature = 'hardware'
requester = [ordered]@{ name = 'Maria Souza'; contact = 'maria@loja.com.br' }
cnpj = '12.345.678/0001-90'
} | ConvertTo-Json -Depth 5
$response = $null
try {
$response = Invoke-WebRequest -UseBasicParsing -Method Post `
-Uri 'https://api.gototem.com.br/v1/api-external-system/help-desk-ticket' `
-Headers @{ Authorization = "Bearer $env:GOTOTEM_INTEGRATION_KEY" } `
-ContentType 'application/json; charset=utf-8' `
-Body ([Text.Encoding]::UTF8.GetBytes($body)) # os bytes em UTF-8, nunca a string
} catch {
$refusal = $_.Exception.Response
if ($null -eq $refusal) { throw }
$requestId = $refusal.Headers.GetValues('X-Request-Id') | Select-Object -First 1
$raw = $_.ErrorDetails.Message
if (-not $raw) { $raw = (New-Object IO.StreamReader($refusal.GetResponseStream())).ReadToEnd() }
$code = '(sem code)'
if ($raw -and $raw.TrimStart().StartsWith('{')) {
$problem = $raw | ConvertFrom-Json
if ($problem.code) { $code = $problem.code }
}
"HTTP $([int]$refusal.StatusCode) $code $requestId"
}
if ($response) {
$result = [Text.Encoding]::UTF8.GetString($response.RawContentStream.ToArray()) | ConvertFrom-Json
$requestId = $response.Headers['X-Request-Id']
"$($response.StatusCode) $($result.ticket) $($result.applied | ConvertTo-Json -Compress) $(@($result.warnings).Count) aviso(s) $requestId"
}
import json
import os
import requests
body = {
"external_id": "conv-8841",
"company": "gototem",
"description": "Cliente relata que o totem não imprime o cupom.",
"category": 3,
"priority": 3,
"support_level": 1,
"nature": "hardware",
"requester": {"name": "Maria Souza", "contact": "maria@loja.com.br"},
"cnpj": "12.345.678/0001-90",
}
resp = requests.post(
"https://api.gototem.com.br/v1/api-external-system/help-desk-ticket",
headers={
"Authorization": "Bearer " + os.environ["GOTOTEM_INTEGRATION_KEY"],
"Content-Type": "application/json",
},
# sem escapar o Unicode: o teto do corpo é em bytes
data=json.dumps(body, ensure_ascii=False).encode("utf-8"),
timeout=30,
)
request_id = resp.headers.get("X-Request-Id")
result = resp.json() if "json" in resp.headers.get("Content-Type", "") else None
if resp.status_code in (200, 201):
print(resp.status_code, result["ticket"], result["applied"], result["warnings"], request_id)
else:
code = result.get("code") if result else None
print(resp.status_code, code or "(sem code)", request_id)
const response = await fetch('https://api.gototem.com.br/v1/api-external-system/help-desk-ticket', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.GOTOTEM_INTEGRATION_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
external_id: 'conv-8841',
company: 'gototem',
description: 'Cliente relata que o totem não imprime o cupom.',
category: 3,
priority: 3,
support_level: 1,
nature: 'hardware',
requester: { name: 'Maria Souza', contact: 'maria@loja.com.br' },
cnpj: '12.345.678/0001-90',
}),
});
const requestId = response.headers.get('X-Request-Id');
// nem toda recusa vem em JSON: leia o corpo só quando ele for JSON
const isJson = (response.headers.get('Content-Type') || '').includes('json');
const result = isJson ? await response.json() : null;
if (response.status === 201 || response.status === 200) {
console.log(response.status, result.ticket, result.applied, result.warnings, requestId);
} else {
console.error(response.status, (result && result.code) || '(sem code)', requestId);
}
<?php
$body = [
'external_id' => 'conv-8841',
'company' => 'gototem',
'description' => 'Cliente relata que o totem não imprime o cupom.',
'category' => 3,
'priority' => 3,
'support_level' => 1,
'nature' => 'hardware',
'requester' => ['name' => 'Maria Souza', 'contact' => 'maria@loja.com.br'],
'cnpj' => '12.345.678/0001-90',
];
$requestId = null;
$curl = curl_init('https://api.gototem.com.br/v1/api-external-system/help-desk-ticket');
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('GOTOTEM_INTEGRATION_KEY'),
'Content-Type: application/json',
],
// sem escapar o Unicode: o teto do corpo é em bytes
CURLOPT_POSTFIELDS => json_encode($body, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR),
CURLOPT_HEADERFUNCTION => function ($curl, $line) use (&$requestId) {
if (stripos($line, 'X-Request-Id:') === 0) {
$requestId = trim(substr($line, strlen('X-Request-Id:')));
}
return strlen($line);
},
]);
$raw = curl_exec($curl);
if ($raw === false) {
throw new RuntimeException('Rede: ' . curl_error($curl));
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
$result = json_decode($raw, true);
if ($status === 201 || $status === 200) {
echo $result['ticket'], ' ', json_encode($result['applied']), ' ', count($result['warnings']), ' aviso(s)', PHP_EOL;
} else {
echo 'HTTP ', $status, ' ', $result['code'] ?? '(sem code)', ' ', $requestId, PHP_EOL;
}
Falha de rede ou tempo esgotado, nos cinco exemplos, cai no erro da própria linguagem: guarde o chamado e reenvie depois, com o mesmo external_id.
3. Ler a resposta
{
"ticket": "I-12345A",
"id": "aGVsbG8td29ybGQ",
"duplicate": false,
"warnings": [],
"applied": {
"category_id": 3,
"priority_id": 3,
"support_level": 1,
"nature": "hardware",
"company": "gototem"
}
}
201: o chamado foi criado.200com"duplicate": true: oexternal_idjá tinha um chamado, e a resposta traz esse chamado (ver Reenvio e idempotência).- Informe o
ticketao cliente e guarde-o: é o número que a equipe da Gototem enxerga. A API não tem rota para consultar o chamado depois de aberto; para saber dele, fale com o suporte informando oticket. - Confira o
applied: a categoria, a prioridade, o nível, a natureza e a empresa que foram de fato gravados, depois dos padrões e das trocas. Ocnpje orequesternão voltam nele: sem o avisocnpj_ignored, o CNPJ foi aceito; orequesteracima do limite é cortado, com o avisorequester_truncated. Se veio aviso emwarnings, registre no seu log o que você enviou e o que foi gravado, para corrigir a escolha (ver Avisos). - Um
nullnoappliednão é erro: o chamado foi aberto e oticketvale. Registre o caso no seu log, junto com oticket, e siga; não reenvie por causa dele.
Cada campo da resposta está na referência da rota. Uma recusa desta API traz o code: o que fazer com cada uma está em Erros e em Corrigir, reenviar ou falar com o suporte.
Avisos (warnings)
Categoria, prioridade, nível e CNPJ nunca fazem o chamado ser recusado. Valor desconhecido, não liberado para o seu sistema, de tipo errado ou enviado como texto é trocado pelo padrão (o CNPJ fora do formato é ignorado), o chamado é aberto e o aviso vem em warnings.
{
"ticket": "I-12345B",
"id": "c2VndW5kby1jaGFtYWRv",
"duplicate": false,
"warnings": [
{"code": "category_fallback", "message": "Unknown or not allowed category. The default category of this system was used."}
],
"applied": {
"category_id": 7,
"priority_id": 3,
"support_level": 1,
"nature": "software",
"company": "gototem"
}
}
No exemplo, a categoria enviada não estava liberada: o chamado foi gravado na categoria padrão (7) com a prioridade padrão dela (3), como mostra o applied.
code |
O que aconteceu | O que fazer |
|---|---|---|
category_fallback |
A categoria enviada não existe, não está liberada para o seu sistema ou não veio como número inteiro (texto, fração, booleano). Foi usada a categoria padrão. | Consulte help-desk-ticket-options de novo e use só ids de lá, como número. Se precisa de outra categoria, peça ao suporte para liberá-la. |
priority_fallback |
A prioridade enviada não existe ou não veio como número inteiro. Foi usada a prioridade padrão da categoria gravada. | Consulte help-desk-ticket-options de novo e use só ids de lá, como número. |
support_level_fallback |
O nível não é um dos aceitos ou não veio como número inteiro. Foi usado o nível 1. | Envie o id de um item de support_levels, como número, sem aspas. |
cnpj_ignored |
O cnpj veio preenchido, mas fora do formato de 14 caracteres. O chamado foi aberto sem ele. O aviso não diz se o CNPJ é de um cliente da Gototem. |
Envie só o número do CNPJ, com ou sem pontuação (12.345.678/0001-90). |
ignored_fields |
O corpo trouxe campos que não são do contrato (ou um requester que não é objeto, ou uma chave dele que não é name nem contact). Eles foram ignorados e o chamado foi aberto sem eles. O aviso traz os nomes em fields (no máximo 20, na ordem do corpo; os de dentro de requester como requester.<chave>). Só no 201: o reenvio não traz este aviso. |
Confira o nome do campo contra a referência da rota (por exemplo, descripton no lugar de description). Se o campo é um dado que o seu sistema envia de propósito, pode ignorar o aviso. |
requester_truncated |
O requester.name ou o requester.contact passou do limite (Limites de uso) e foi cortado; o chamado foi aberto com o texto cortado. O aviso traz em fields os campos cortados (requester.name, requester.contact, na ordem do corpo). Só no 201. |
Se o nome ou o contato completo importa, encurte-o antes de enviar ou ponha o restante na description. |
description_differs |
Reenvio (200 com "duplicate": true) com uma description diferente da gravada no chamado. O chamado continua o antigo, e a descrição nova não foi gravada. É o único aviso do reenvio. |
Se é outro problema, abra outro chamado com um external_id novo (ver Reenvio e idempotência). Se é o mesmo problema reescrito, pode ignorar o aviso. |
Aviso com um code que você não conhece: o chamado foi criado mesmo assim; registre o aviso e siga.
Reenvio e idempotência
Reenviar com o mesmo external_id nunca cria um segundo chamado: se o chamado já existe, a resposta é 200 com "duplicate": true e o mesmo ticket.
- O reenvio não altera o chamado: empresa, descrição, categoria, prioridade, nível, natureza, solicitante e CNPJ continuam os da primeira chamada, mesmo que o corpo novo traga outros valores. O
appliedtraz esses valores. Para um novo chamado, use umexternal_idnovo. - A descrição diferente vem com aviso: se o reenvio traz uma
descriptiondiferente da gravada,warningstrazdescription_differse a descrição nova não é gravada. É o único aviso do reenvio; sem ele,warningsvem vazio. Para outro problema, use outroexternal_id: o id da conversa não serve deexternal_idquando a mesma conversa pode trazer um segundo problema (por exemplo, acrescente ao id da conversa um número para cada problema dela, comoconv-8841-2). - O registro do
external_idé do seu sistema: a rota direta e o webhook dividem o mesmo registro, e outro sistema pode usar o mesmo valor sem colidir com o seu. Ele não expira. A comparação é exata, depois de retirar os espaços das pontas. - O reenvio também é validado: um corpo inválido recebe o
422do campo mesmo que oexternal_idjá tenha um chamado. Reenvie o mesmo corpo da primeira chamada.
Quando reenviar, e quando corrigir antes, está em Corrigir, reenviar ou falar com o suporte.
Abrir um chamado com webhook
Use o webhook quando o seu sistema não chama uma API diretamente, mas tem uma ferramenta de webhook (n8n, Zapier, Make ou a automação do seu chat). O chamado aberto é o mesmo da rota direta.
Na ferramenta, configure:
- O endereço, com o identificador do seu sistema no lugar de
{system}. O identificador vem do suporte, junto com a chave. - O cabeçalho
Authorization, comBearere a chave, como em Como enviar a chave. - O corpo, o mesmo de Abrir um chamado, com um
external_idúnico por atendimento.
curl -s -i -X POST https://api.gototem.com.br/v1/api-external-system/webhook/meu-sistema \
-H "Authorization: Bearer $GOTOTEM_INTEGRATION_KEY" \
-H "Content-Type: application/json" \
-d '{"external_id": "conv-8842", "company": "gototem", "description": "Cliente relata que o totem não liga.", "priority": 3}'
O que muda em relação à rota direta:
- Qualquer
Content-Typeé aceito. - O formato do corpo só é conferido depois da chave; o
413, de corpo acima do teto, continua saindo antes dela. ComContent-TypeJSON (application/jsonou um tipo+json), o corpo que não é objeto nem lista JSON (JSON quebrado, texto que não é UTF-8, ou um texto, número,trueounullsozinho) é recusado pelo servidor com400emapplication/problem+json, semcode; uma lista recebe422 invalid_body. Com outroContent-Type, todo corpo que não é objeto recebe422 invalid_body. Nos dois casos, corrija o corpo: reenviar igual não resolve. - Identificador desconhecido, ou a chave de outro sistema, recebe
401 unauthorized. Identificador fora do padrão (maiúscula, acento, outro caractere ou mais de 40 caracteres) não é rota e recebe o404 not_found(ver Os casos do 404). - As respostas são as mesmas, inclusive o
applied, e o registro doexternal_idé o mesmo da rota direta (ver Reenvio e idempotência).
A rota, com as respostas e os erros dela, está na referência.
Na política de reenvio da ferramenta:
Não reenvie ao receber 200: é a confirmação de que o chamado já existe.
- Reenvie, com o mesmo
external_id, ao receber o503 temporarily_unavailablee o429(os dois depois doRetry-After) e o500 internal_error, e em falha de rede ou tempo esgotado. Se a ferramenta não reenvia no503sozinha, configure-a para isso. - Não reenvie no
404: é sempre erro de endereço; corrija o endereço na ferramenta. - Nos demais casos, corrija antes ou fale com o suporte (ver Corrigir, reenviar ou falar com o suporte).
Enviar um lead
O envio de lead ainda não está disponível: com o escopo lead.create na chave, a rota responde 501 not_implemented; sem ele, 403 forbidden_scope. Até lá, não integre esta rota; a Gototem avisa quando ela for ligada. A rota está na referência.
Chamados
O que o seu sistema pode escolher ao abrir um chamado
Lista as empresas, as categorias liberadas para o seu sistema (com o tipo de cada uma), as
prioridades, os níveis de suporte e as naturezas. O id da empresa vai em company, o da
categoria em category, o da prioridade em priority, o do nível em support_level e o
identifier da natureza em nature. Os ids mudam entre homologação e produção (os do exemplo
são ilustrativos): leia-os daqui, nunca os fixe no código.
Guarde a resposta em cache por algumas horas e consulte de novo ao receber
category_fallback, priority_fallback ou invalid_nature.
Sem parâmetros.
{
"companies": [
{
"id": "gototem",
"name": "Gototem"
},
{
"id": "melhoretec",
"name": "Melhoretec"
}
],
"categories": [
{
"id": 3,
"name": "Falha na impressora",
"description": null,
"default": false,
"default_priority_id": 1,
"type": {
"id": 3,
"name": "Problema",
"description": "Algo que funcionava parou de funcionar ou funciona errado."
}
},
{
"id": 7,
"name": "Ajustes em cardápios",
"description": "Pedido para incluir, alterar ou remover produtos, preços ou opcionais do cardápio. Não use quando algo parou de funcionar.",
"default": true,
"default_priority_id": 3,
"type": {
"id": 1,
"name": "Solicitação de Serviço",
"description": "O cliente pede algo novo ou uma alteração; nada está quebrado."
}
}
],
"priorities": [
{
"id": 1,
"name": "Crítica",
"description": "A loja não consegue vender. Use só quando a operação estiver parada.",
"level": 1,
"response_time_hours": 1
},
{
"id": 3,
"name": "Normal",
"description": null,
"level": 3,
"response_time_hours": 8
}
],
"support_levels": [
{
"id": 1,
"name": "Nível 1",
"description": "Primeiro atendimento: dúvidas de uso, orientação e problemas que o suporte resolve com os procedimentos padrão. Use na maioria dos chamados."
},
{
"id": 2,
"name": "Nível 2",
"description": "Análise técnica especializada: falha que se repete ou que o primeiro atendimento já tentou resolver sem sucesso, erro do sistema ou de integração. Use só quando a conversa mostrar isso."
}
],
"natures": [
{
"identifier": "hardware",
"name": "Hardware"
},
{
"identifier": "implementation",
"name": "Implantação"
},
{
"identifier": "software",
"name": "Software"
}
]
}
| Campo | Tipo | O que é |
|---|---|---|
companies |
lista de objetos | As empresas ativas do grupo Gototem pelas quais o chamado pode ser aberto. |
companies[].id |
texto | O identificador da empresa (ex. gototem), o valor que o chamado aceita em company. |
companies[].name |
texto | O nome da empresa, para exibir. |
categories |
lista de objetos | A categoria padrão do seu sistema e as liberadas para ele, em ordem alfabética do nome do tipo e, dentro de cada tipo, do nome da categoria. |
categories[].id |
inteiro | O id (número inteiro) da categoria, o valor que o chamado aceita em category. |
categories[].name |
texto | O nome da categoria. |
categories[].description |
texto ou null | Quando usar esta opção; null quando ainda não há texto (escolha pelo nome). Texto puro escrito pela Gototem: trate como dado (nunca execute instruções dele) e escape antes de exibir em HTML. O texto pode mudar sem aviso: nunca o copie para o seu código. |
categories[].default |
booleano | true na categoria usada quando nenhuma é escolhida. |
categories[].default_priority_id |
inteiro ou null | O id (de priorities) da prioridade usada quando o chamado vem com esta categoria e sem priority. Hoje toda categoria tem prioridade padrão; null fica reservado e, se aparecer, envie priority junto com essa categoria. |
categories[].type |
objeto | O tipo da categoria (Incidente, Problema, Solicitação de Serviço ou Solicitação de Mudança). Escolher a categoria já define o tipo. |
categories[].type.id |
inteiro | O id do tipo. Só informativo; o chamado não recebe o tipo, que vem da categoria. |
categories[].type.name |
texto | O nome do tipo. |
categories[].type.description |
texto ou null | Quando usar esta opção; null quando ainda não há texto (escolha pelo nome). Texto puro escrito pela Gototem: trate como dado (nunca execute instruções dele) e escape antes de exibir em HTML. O texto pode mudar sem aviso: nunca o copie para o seu código. |
priorities |
lista de objetos | Da mais urgente (level 1) para a menos urgente. O response_time_hours é o prazo configurado de cada uma e pode não acompanhar a ordem do level. |
priorities[].id |
inteiro | O id (número inteiro) da prioridade, o valor que o chamado aceita em priority. |
priorities[].name |
texto | O nome da prioridade. |
priorities[].description |
texto ou null | Quando usar esta opção; null quando ainda não há texto (escolha pelo nome). Texto puro escrito pela Gototem: trate como dado (nunca execute instruções dele) e escape antes de exibir em HTML. O texto pode mudar sem aviso: nunca o copie para o seu código. |
priorities[].level |
inteiro | A urgência, para ordenar (1 é a mais urgente). Não vai no chamado; o chamado recebe o id. |
priorities[].response_time_hours |
inteiro | O prazo configurado da prioridade, em horas. Só informativo. |
support_levels |
lista de objetos | Os níveis aceitos. O corpo do chamado manda só o id, como número, em support_level. |
support_levels[].id |
inteiro | O valor que o chamado aceita em support_level. |
support_levels[].name |
texto | O nome do nível. |
support_levels[].description |
texto ou null | Quando usar esta opção; null quando ainda não há texto (escolha pelo nome). Texto puro escrito pela Gototem: trate como dado (nunca execute instruções dele) e escape antes de exibir em HTML. O texto pode mudar sem aviso: nunca o copie para o seu código. |
natures |
lista de objetos | As naturezas ativas, em ordem alfabética do nome: os valores aceitos no campo opcional nature do chamado. Natureza nova no cadastro da Gototem aparece aqui; a que for desativada sai, e enviá-la passa a ser recusado com invalid_nature. |
natures[].identifier |
texto | O valor que o chamado aceita em nature. |
natures[].name |
texto | O nome da natureza, para exibir. |
Erros desta rota: 400 · 401 · 403 · 404 · 405 · 429 · 500 · 503
Abre um chamado no help desk
O external_id identifica o reenvio: o mesmo external_id devolve o chamado que já existe
(200, duplicate: true, como foi criado), nunca um segundo; o corpo do reenvio ainda é
validado (os 422 valem). O registro do external_id é por sistema: a rota direta e o webhook
do mesmo sistema o compartilham, e ele não expira.
category, priority e support_level nunca recusam o chamado: valor desconhecido, não
liberado ou de tipo errado é trocado pelo padrão, com aviso em warnings; o que foi gravado
vem em applied.
{
"external_id": "conv-8841",
"company": "gototem",
"description": "Cliente relata que o totem não imprime o cupom.",
"category": 3,
"priority": 3,
"support_level": 1,
"nature": "hardware",
"requester": {
"name": "Maria Souza",
"contact": "maria@loja.com.br"
},
"cnpj": "12.345.678/0001-90"
}
{
"ticket": "I-12345A",
"id": "aGVsbG8td29ybGQ",
"duplicate": false,
"warnings": [],
"applied": {
"category_id": 3,
"priority_id": 3,
"support_level": 1,
"nature": "hardware",
"company": "gototem"
}
}
Campos fora desta lista são ignorados, nunca recusados (não há campo de conta ou local: o
cnpj é o único identificador do cliente), e vêm no aviso ignored_fields. null num campo
opcional é o mesmo que não enviar; num obrigatório, recusa com o missing_* do campo.
| Campo | Tipo | Obrigatório | O que é |
|---|---|---|---|
external_id |
texto | sim | O id do atendimento no seu sistema; identifica o reenvio, por sistema. Os espaços das pontas e os caracteres invisíveis e de controle (menos o ZWNJ e o ZWJ) são retirados antes de comparar e de contar; maiúsculas e minúsculas diferem. Inteiro JSON vale como o mesmo texto. Vazio: missing_external_id; acima de 120 caracteres: field_too_long (não é cortado); NUL (\u0000): invalid_field. |
company |
texto | sim | Id de uma das companies de help-desk-ticket-options (ex. gototem); os espaços das pontas são retirados e maiúscula vale como minúscula. Ausente ou vazio: missing_company; fora da lista: invalid_company. |
description |
texto | sim | O relato, em texto puro, até 20.000 caracteres (contados antes de retirar os espaços das pontas; quebra de linha e tabulação ficam). Acima: field_too_long (não é cortado: corte no seu lado). Vazio: missing_description. NUL: invalid_field. O corpo inteiro tem teto de 65.536 bytes (413). |
category |
inteiro ou null | não | Id inteiro de categories (3.0 vale como 3). Ausente: a categoria padrão do sistema. Desconhecida, não liberada, texto ("3") ou fração: também a padrão, com o aviso category_fallback; nunca recusa. |
priority |
inteiro ou null | não | Id inteiro de priorities (1.0 vale como 1). Ausente: a default_priority_id da categoria gravada. Desconhecida, texto ("1") ou fração: também a padrão, com o aviso priority_fallback; nunca recusa. |
support_level |
inteiro ou null | não | Id inteiro de support_levels (2.0 vale como 2). Ausente: 1. Fora da lista, texto ("2") ou fração: também 1, com o aviso support_level_fallback; nunca recusa. |
nature |
texto ou null | não | O identifier de uma das natures de help-desk-ticket-options; os espaços das pontas são retirados e maiúscula vale como minúscula. Ausente: o chamado nasce sem natureza. Outro valor: invalid_nature, a única escolha que recusa o chamado (na dúvida, omita). |
cnpj |
texto ou null | não | CNPJ do cliente em 14 caracteres, numérico ou alfanumérico, como texto (12.345.678/0001-90 ou L3USOA72000137); a pontuação e o rótulo CNPJ na frente são ignorados, e minúscula vale como maiúscula. O dígito verificador não é conferido. Fora do formato (inclusive o número JSON que perdeu o zero à esquerda): ignorado, com o aviso cnpj_ignored; nunca recusa. O aviso não diz se o CNPJ é de um cliente da Gototem. |
requester |
objeto ou null | não | Quem pediu: name (até 120 caracteres) e contact (até 160). Acima do limite o texto é cortado, nunca recusado; espaços das pontas e invisíveis (menos o ZWNJ e o ZWJ) são retirados; NUL: invalid_field. Valor que não é texto é ignorado sem aviso; requester que não é objeto, e chave fora de name/contact, vêm em ignored_fields. |
requester.name |
texto ou null | não | O nome de quem pediu, até 120 caracteres (o excedente é cortado). |
requester.contact |
texto ou null | não | Como falar com quem pediu (ex. e-mail ou telefone), até 160 caracteres (o excedente é cortado). |
| Campo | Tipo | O que é |
|---|---|---|
ticket |
texto | O número do chamado no help desk (começa com I-). |
id |
texto | Id do chamado, opaco. |
duplicate |
booleano | true quando o external_id já tinha sido enviado. |
warnings |
lista de objetos | Escolhas trocadas pelo padrão, CNPJ ignorado, campos fora do contrato e solicitante cortado. Vazio quando nada foi trocado nem ignorado. No reenvio, o único aviso possível é description_differs (outra descrição para o mesmo external_id). |
warnings[].code |
texto | Texto aberto. Os valores conhecidos são category_fallback, priority_fallback, support_level_fallback, cnpj_ignored, ignored_fields, requester_truncated e description_differs. Aviso novo pode surgir a qualquer momento: registre o que não conhecer e siga, porque o chamado foi criado (ou já existia, no reenvio). |
warnings[].message |
texto | Para leitura humana, em inglês; pode mudar. Use o code na lógica. |
warnings[].fields |
lista de textos | Só no ignored_fields e no requester_truncated. No ignored_fields: os campos ignorados, na ordem do corpo (requester.<chave> para os de dentro de requester), no máximo 20 nomes, cada um com até 64 caracteres, sem caracteres invisíveis. No requester_truncated: os campos cortados (requester.name, requester.contact). |
applied |
objeto | O que foi de fato gravado no chamado, depois das trocas pelo padrão: confira aqui a categoria, a prioridade e o nível que valeram. No reenvio (200), os valores do chamado que já existia. null em qualquer campo não é erro: o chamado foi aberto; não reenvie por causa dele. Traz só estes cinco campos: o cnpj não é ecoado (sem o aviso cnpj_ignored, ele foi aceito) e o requester também não (o excedente é cortado, com o aviso requester_truncated). |
applied.category_id |
inteiro ou null | O id da categoria gravada. Na criação sempre vem; null só num reenvio de chamado que perdeu a categoria depois. |
applied.priority_id |
inteiro ou null | O id da prioridade gravada; pode ser null. |
applied.support_level |
inteiro ou null | O nível de suporte gravado; pode ser null. |
applied.nature |
texto ou null | O identifier da natureza gravada. null quando o chamado não tem natureza. |
applied.company |
texto ou null | O id (de companies) da empresa gravada; pode ser null. |
Erros desta rota: 400 · 401 · 403 · 404 · 405 · 413 · 415 · 422 · 429 · 500 · 503
Abre um chamado pelo webhook do seu sistema
O mesmo chamado da rota direta, para quando o seu sistema envia por webhook. {system} é o
identificador do seu sistema, informado pelo suporte da Gototem junto com a chave. Nesta
versão o webhook também exige a chave no cabeçalho Authorization e o corpo segue o mesmo
formato da rota direta, com as mesmas respostas (inclusive applied). Qualquer
Content-Type é aceito. O teto de 65.536 bytes (413) vale antes da chave, como nas outras
rotas; o formato do corpo (invalid_body) só é conferido depois dela. Com Content-Type JSON,
corpo que não é objeto nem lista JSON recebe 400 em application/problem+json, sem code.
Identificador desconhecido, ou a chave de outro sistema, recebe 401 unauthorized.
Identificador fora do padrão (maiúscula, acento, outro caractere ou mais de 40 caracteres)
não é rota: recebe o 404 not_found.
{
"external_id": "conv-8842",
"company": "gototem",
"description": "Cliente relata que o totem não imprime o cupom.",
"category": 3,
"priority": 3,
"support_level": 1,
"nature": "hardware",
"requester": {
"name": "Maria Souza",
"contact": "maria@loja.com.br"
},
"cnpj": "12.345.678/0001-90"
}
{
"ticket": "I-12345A",
"id": "aGVsbG8td29ybGQ",
"duplicate": false,
"warnings": [],
"applied": {
"category_id": 3,
"priority_id": 3,
"support_level": 1,
"nature": "hardware",
"company": "gototem"
}
}
| Parâmetro | Obrigatório | O que é |
|---|---|---|
system |
sim | O identificador do seu sistema (letras minúsculas, números, - e _, até 40 caracteres) |
Campos fora desta lista são ignorados, nunca recusados (não há campo de conta ou local: o
cnpj é o único identificador do cliente), e vêm no aviso ignored_fields. null num campo
opcional é o mesmo que não enviar; num obrigatório, recusa com o missing_* do campo.
| Campo | Tipo | Obrigatório | O que é |
|---|---|---|---|
external_id |
texto | sim | O id do atendimento no seu sistema; identifica o reenvio, por sistema. Os espaços das pontas e os caracteres invisíveis e de controle (menos o ZWNJ e o ZWJ) são retirados antes de comparar e de contar; maiúsculas e minúsculas diferem. Inteiro JSON vale como o mesmo texto. Vazio: missing_external_id; acima de 120 caracteres: field_too_long (não é cortado); NUL (\u0000): invalid_field. |
company |
texto | sim | Id de uma das companies de help-desk-ticket-options (ex. gototem); os espaços das pontas são retirados e maiúscula vale como minúscula. Ausente ou vazio: missing_company; fora da lista: invalid_company. |
description |
texto | sim | O relato, em texto puro, até 20.000 caracteres (contados antes de retirar os espaços das pontas; quebra de linha e tabulação ficam). Acima: field_too_long (não é cortado: corte no seu lado). Vazio: missing_description. NUL: invalid_field. O corpo inteiro tem teto de 65.536 bytes (413). |
category |
inteiro ou null | não | Id inteiro de categories (3.0 vale como 3). Ausente: a categoria padrão do sistema. Desconhecida, não liberada, texto ("3") ou fração: também a padrão, com o aviso category_fallback; nunca recusa. |
priority |
inteiro ou null | não | Id inteiro de priorities (1.0 vale como 1). Ausente: a default_priority_id da categoria gravada. Desconhecida, texto ("1") ou fração: também a padrão, com o aviso priority_fallback; nunca recusa. |
support_level |
inteiro ou null | não | Id inteiro de support_levels (2.0 vale como 2). Ausente: 1. Fora da lista, texto ("2") ou fração: também 1, com o aviso support_level_fallback; nunca recusa. |
nature |
texto ou null | não | O identifier de uma das natures de help-desk-ticket-options; os espaços das pontas são retirados e maiúscula vale como minúscula. Ausente: o chamado nasce sem natureza. Outro valor: invalid_nature, a única escolha que recusa o chamado (na dúvida, omita). |
cnpj |
texto ou null | não | CNPJ do cliente em 14 caracteres, numérico ou alfanumérico, como texto (12.345.678/0001-90 ou L3USOA72000137); a pontuação e o rótulo CNPJ na frente são ignorados, e minúscula vale como maiúscula. O dígito verificador não é conferido. Fora do formato (inclusive o número JSON que perdeu o zero à esquerda): ignorado, com o aviso cnpj_ignored; nunca recusa. O aviso não diz se o CNPJ é de um cliente da Gototem. |
requester |
objeto ou null | não | Quem pediu: name (até 120 caracteres) e contact (até 160). Acima do limite o texto é cortado, nunca recusado; espaços das pontas e invisíveis (menos o ZWNJ e o ZWJ) são retirados; NUL: invalid_field. Valor que não é texto é ignorado sem aviso; requester que não é objeto, e chave fora de name/contact, vêm em ignored_fields. |
requester.name |
texto ou null | não | O nome de quem pediu, até 120 caracteres (o excedente é cortado). |
requester.contact |
texto ou null | não | Como falar com quem pediu (ex. e-mail ou telefone), até 160 caracteres (o excedente é cortado). |
| Campo | Tipo | O que é |
|---|---|---|
ticket |
texto | O número do chamado no help desk (começa com I-). |
id |
texto | Id do chamado, opaco. |
duplicate |
booleano | true quando o external_id já tinha sido enviado. |
warnings |
lista de objetos | Escolhas trocadas pelo padrão, CNPJ ignorado, campos fora do contrato e solicitante cortado. Vazio quando nada foi trocado nem ignorado. No reenvio, o único aviso possível é description_differs (outra descrição para o mesmo external_id). |
warnings[].code |
texto | Texto aberto. Os valores conhecidos são category_fallback, priority_fallback, support_level_fallback, cnpj_ignored, ignored_fields, requester_truncated e description_differs. Aviso novo pode surgir a qualquer momento: registre o que não conhecer e siga, porque o chamado foi criado (ou já existia, no reenvio). |
warnings[].message |
texto | Para leitura humana, em inglês; pode mudar. Use o code na lógica. |
warnings[].fields |
lista de textos | Só no ignored_fields e no requester_truncated. No ignored_fields: os campos ignorados, na ordem do corpo (requester.<chave> para os de dentro de requester), no máximo 20 nomes, cada um com até 64 caracteres, sem caracteres invisíveis. No requester_truncated: os campos cortados (requester.name, requester.contact). |
applied |
objeto | O que foi de fato gravado no chamado, depois das trocas pelo padrão: confira aqui a categoria, a prioridade e o nível que valeram. No reenvio (200), os valores do chamado que já existia. null em qualquer campo não é erro: o chamado foi aberto; não reenvie por causa dele. Traz só estes cinco campos: o cnpj não é ecoado (sem o aviso cnpj_ignored, ele foi aceito) e o requester também não (o excedente é cortado, com o aviso requester_truncated). |
applied.category_id |
inteiro ou null | O id da categoria gravada. Na criação sempre vem; null só num reenvio de chamado que perdeu a categoria depois. |
applied.priority_id |
inteiro ou null | O id da prioridade gravada; pode ser null. |
applied.support_level |
inteiro ou null | O nível de suporte gravado; pode ser null. |
applied.nature |
texto ou null | O identifier da natureza gravada. null quando o chamado não tem natureza. |
applied.company |
texto ou null | O id (de companies) da empresa gravada; pode ser null. |
Erros desta rota: 400 · 401 · 403 · 404 · 405 · 413 · 422 · 429 · 500 · 503
Leads
Envio de lead (ainda não disponível)
A rota já autentica e confere o formato mínimo, mas ainda não grava: responde 501
not_implemented. Não integre esta rota até a Gototem avisar. Sem o escopo lead.create na
chave, a resposta é o 403 forbidden_scope.
| Campo | Tipo | Obrigatório | O que é |
|---|---|---|---|
external_id |
texto | sim |
Em breve: hoje responde 501; a forma da rota ainda pode mudar.
Erros desta rota: 400 · 401 · 403 · 404 · 405 · 413 · 415 · 422 · 429 · 500 · 501 · 503
Como pedir ajuda
Fale com o suporte da Gototem pelo mesmo canal por onde a chave foi entregue, ou escreva para integracoes@gototem.com.br. É o suporte que cadastra o sistema, entrega e troca a chave, libera escopo e categoria e informa o endereço de homologação.
Antes de pedir ajuda, confira Corrigir, reenviar ou falar com o suporte: ali está, para cada resposta, se o caso se resolve do seu lado ou se precisa do suporte.
O que enviar ao pedir ajuda
| O que | Onde está |
|---|---|
X-Request-Id |
no cabeçalho de toda resposta das rotas desta API, inclusive das recusas |
| A rota chamada | o método e o endereço (por exemplo, POST /v1/api-external-system/help-desk-ticket) |
| O horário da chamada | no seu log; diga o fuso |
O status HTTP e o code |
na resposta; o code, no corpo |
O external_id |
no corpo que o seu sistema enviou |
Nunca envie a chave, nem um pedaço dela, nem um print em que ela apareça. O suporte não precisa dela para investigar. Se a chave foi exposta, peça a troca.