Catálogos
As rotas de catálogo devolvem os identificadores que o resto da API pede: conexões (números de WhatsApp), departamentos, atendentes, modelos de mensagem da API oficial, etiquetas e motivos de encerramento, além das informações da própria chave. Todas são de leitura e ficam liberadas para qualquer chave ativa.
Visão geral
Antes de enviar uma mensagem por um número específico, transferir para um departamento, atribuir um atendente ou encerrar com um motivo, a integração precisa dos ids desses cadastros. As sete rotas desta página existem para isso:
| Rota | Devolve | Usado em |
|---|---|---|
chave/info | A própria chave e o servidor | Teste de conexão, conferência de escopos e fuso horário |
conexoes/listar | Números de WhatsApp | conexao_id em envios, abertura de atendimento, filtros e modelos |
departamentos/listar | Departamentos | departamento_id em transferência, abertura de atendimento, ordens de serviço, agenda, filtros e indicadores |
atendentes/listar | Atendentes | atendente_id em transferência e abertura; responsavel_id em ordens de serviço e agenda |
modelos/listar | Modelos da API oficial | modelo_id em mensagens/enviar_modelo |
etiquetas/listar | Etiquetas de conversa | conversas/etiquetas e o filtro etiqueta_id |
motivos/listar | Motivos de encerramento | motivo_id em conversas/encerrar |
- Escopo: nenhum. Qualquer chave ativa pode chamar, mesmo com todas as permissões desligadas.
- Método: GET (POST também é aceito).
- Paginação: não há. Cada rota devolve a lista inteira, que em um provedor costuma ter de alguns a algumas dezenas de itens.
- Contagem: as chamadas de catálogo contam no uso e no limite por minuto da chave, como qualquer outra.
Os exemplos em PHP e Python desta página usam a função chatisp() apresentada em Endereço e autenticação: ela monta a URL, envia a chave no cabeçalho e devolve a resposta decodificada.
Informações da chave
/api_publica.php?r=chave/info
Mostra a chave que fez a chamada (nome, escopos e limite por minuto) e dados do servidor (versão da API, fuso horário, relógio e plano). É a melhor rota para testar endereço e chave, e para a integração conferir na inicialização se tem os escopos de que precisa.
Parâmetros: nenhum.
curl -s "https://atendimento.seuprovedor.com.br/api_publica.php?r=chave/info" \ -H "Authorization: Bearer $CHATISP_CHAVE"
$info = chatisp('chave/info'); $faltando = array_diff(['mensagens_enviar', 'tickets_gerir'], $info['chave']['escopos']); if ($faltando) { die('Ligue na chave: ' . implode(', ', $faltando) . PHP_EOL); }
info = chatisp("chave/info") faltando = {"mensagens_enviar", "tickets_gerir"} - set(info["chave"]["escopos"]) if faltando: raise SystemExit(f"Ligue na chave: {', '.join(faltando)}")
{
"ok": true,
"chave": {
"id": 3,
"nome": "ERP financeiro",
"prefixo": "cisp_7f3a9…",
"escopos": ["mensagens_enviar", "conversas_ler", "atendimentos_abrir"],
"cota_minuto": 60
},
"servidor": {
"api_versao": "1",
"fuso_horario": "America/Sao_Paulo",
"agora": "2026-10-01T09:30:12-03:00",
"plano": "PREMIUM"
}
}| Campo | Tipo | Descrição |
|---|---|---|
chave.id | inteiro | Identificador da chave no painel. |
chave.nome | string | O Nome dado à chave. É o nome que aparece no histórico das ações feitas por ela. |
chave.prefixo | string | O começo da chave, igual ao mostrado na lista do painel. A chave completa nunca é devolvida pela API. |
chave.escopos | lista | Escopos ligados, na ordem da tela. Veja a tabela em Permissões da chave. |
chave.cota_minuto | inteiro | Limite por minuto. 0 = sem limite. |
servidor.api_versao | string | Versão da API, a mesma do cabeçalho X-ChatISP-Api-Versao. |
servidor.fuso_horario | string | Fuso horário do servidor (nome IANA). Datas sem fuso enviadas à API são lidas nele. |
servidor.agora | string | Relógio do servidor em ISO 8601. Útil para medir a diferença para o relógio do seu sistema. |
servidor.plano | string | Nome do plano em vigor (PREMIUM, GOLD, ENTERPRISE, CUSTOM ou TRIAL durante o teste). |
Erros: só os de acesso, comuns a todas as rotas (autenticacao, chave_invalida, plano, cota_excedida).
Conexões (números de WhatsApp)
/api_publica.php?r=conexoes/listar
Lista todas as conexões cadastradas, conectadas ou não, em ordem de nome. Cada conexão é um número de WhatsApp ligado ao ChatISP por QR Code ou pela API oficial da Meta (veja Conexões de WhatsApp).
Parâmetros: nenhum.
curl -s "https://atendimento.seuprovedor.com.br/api_publica.php?r=conexoes/listar" \ -H "Authorization: Bearer $CHATISP_CHAVE"
// Um número = uma linha: descarta a perna não principal dos gêmeos $numeros = array_filter(chatisp('conexoes/listar')['conexoes'], fn($c) => $c['principal']); foreach ($numeros as $c) { echo "{$c['id']} {$c['nome']} {$c['telefone']} {$c['estado']}\n"; }
# Um número = uma linha: descarta a perna não principal dos gêmeos for c in chatisp("conexoes/listar")["conexoes"]: if c["principal"]: print(c["id"], c["nome"], c["telefone"], c["estado"])
{
"ok": true,
"conexoes": [
{
"id": 1,
"nome": "Atendimento",
"tipo": "qr",
"estado": "conectada",
"telefone": "5544999990000",
"nome_conta": "Fibra Exemplo",
"gemea_id": 2,
"principal": true
},
{
"id": 2,
"nome": "Atendimento (API oficial)",
"tipo": "api_oficial",
"estado": "conectada",
"telefone": "5544999990000",
"nome_conta": "Fibra Exemplo",
"gemea_id": 1,
"principal": false
},
{
"id": 4,
"nome": "Comercial",
"tipo": "qr",
"estado": "desconectada",
"telefone": "5544999991111",
"nome_conta": "Fibra Exemplo Vendas",
"gemea_id": null,
"principal": true
}
]
}| Campo | Tipo | Descrição |
|---|---|---|
id | inteiro | O conexao_id usado nas outras rotas. |
nome | string | Nome dado à conexão no painel. |
tipo | string | qr (conectada pelo QR Code do aplicativo) ou api_oficial (API oficial da Meta). |
estado | string | conectada, conectando, desconectada ou erro. Só conexões conectada enviam mensagens. |
telefone | string | O número do WhatsApp, só dígitos. Pode vir vazio numa conexão que ainda não foi pareada. |
nome_conta | string | Nome do perfil do WhatsApp (o que o cliente vê). |
gemea_id | inteiro ou null | Na conexão gêmea, o id da outra perna do mesmo número. null nas conexões simples. |
principal | booleano | Se é a perna onde nascem as conversas novas do número. Sempre true nas conexões simples. |
Erros: só os de acesso.
Número gêmeo: QR e API oficial no mesmo número
Um mesmo número de WhatsApp pode estar ligado ao ChatISP pelos dois caminhos ao mesmo tempo: pelo QR Code (o aplicativo do celular) e pela API oficial da Meta (no modo de coexistência). No painel, esse par aparece como um único canal; na API, aparece como duas conexões que apontam uma para a outra por gemea_id. Regras que valem para a integração:
- As duas pernas são o mesmo número. Para listar números, considere só as conexões com
principal: true, como no exemplo acima. - Conversas novas nascem na perna principal, que é a do QR quando ela existe. O
conexao_idque aparece nas conversas e nos webhooks é, em geral, o da perna principal. - Envio: o ChatISP escolhe a perna que vai entregar cada mensagem, como faz no painel. Se uma das pernas cair, a outra segue enviando: a chamada só responde
conexao_desconectadaquando as duas estão fora do ar. - Modelos: só a perna da API oficial envia modelos. Em
mensagens/enviar_modeloe emmodelos/listar, você pode informar o id de qualquer uma das pernas: o ChatISP usa a perna oficial do mesmo número. - Filtros: em
conversas/listar, filtrar porconexao_idde qualquer perna traz as conversas do número inteiro.
Quando informar conexao_id
| Situação | Sem conexao_id |
|---|---|
| Um único número conectado (o par gêmeo conta como um número) | A API usa esse número. Pode omitir. |
| Mais de um número conectado | A API usa o Número de origem da chave de API (Integrações, Chaves de API). Chave sem Número de origem: HTTP 400 conexao_id_obrigatorio, informe qual número usar. |
| Nenhum número conectado | HTTP 400 sem_conexao. |
mensagens/enviar_modelo | A regra acima vale só para conexões da API oficial: com um único número oficial conectado, pode omitir. |
Envio para uma conversa existente (conversa_id ou protocolo) | Não precisa: a mensagem sai pelo número da conversa. |
Mesmo com um único número hoje, guarde o conexao_id na configuração da integração e envie-o sempre. Assim, quando o provedor conectar um segundo número (comercial, cobrança), a integração continua funcionando sem mudar nada.
Departamentos
/api_publica.php?r=departamentos/listar
Lista todos os departamentos, ativos e inativos, na ordem definida no painel (veja Departamentos).
Parâmetros: nenhum.
curl -s "https://atendimento.seuprovedor.com.br/api_publica.php?r=departamentos/listar" \ -H "Authorization: Bearer $CHATISP_CHAVE"
// Mapa nome => id dos departamentos ativos $deps = []; foreach (chatisp('departamentos/listar')['departamentos'] as $d) { if ($d['ativo']) $deps[$d['nome']] = $d['id']; } $suporte = $deps['Suporte técnico'] ?? null;
deps = {d["nome"]: d["id"] for d in chatisp("departamentos/listar")["departamentos"] if d["ativo"]}
suporte = deps.get("Suporte técnico"){
"ok": true,
"departamentos": [
{ "id": 1, "nome": "Suporte técnico", "ativo": true, "padrao": true },
{ "id": 2, "nome": "Financeiro", "ativo": true, "padrao": false },
{ "id": 3, "nome": "Comercial", "ativo": true, "padrao": false },
{ "id": 5, "nome": "Retenção", "ativo": false, "padrao": false }
]
}| Campo | Tipo | Descrição |
|---|---|---|
id | inteiro | O departamento_id usado nas outras rotas. |
nome | string | Nome do departamento. |
ativo | booleano | Departamento inativo não recebe transferências nem atendimentos: usá-lo responde departamento_invalido. Ele aparece na lista porque conversas antigas podem estar ligadas a ele. |
padrao | booleano | true no departamento que recebe as conversas novas (opção Departamento das novas conversas, em Configurações). Nenhum vem marcado quando a opção está vazia ou aponta para um departamento inativo. |
Erros: só os de acesso.
Atendentes
/api_publica.php?r=atendentes/listar
Lista os usuários do painel em ordem alfabética, com perfil de acesso, departamentos, presença e pausa. Usuários excluídos não aparecem; usuários inativos aparecem com ativo: false.
Parâmetros: nenhum.
curl -s "https://atendimento.seuprovedor.com.br/api_publica.php?r=atendentes/listar" \ -H "Authorization: Bearer $CHATISP_CHAVE"
// Quem do departamento 1 está online e fora de pausa agora $livres = array_filter(chatisp('atendentes/listar')['atendentes'], fn($a) => $a['ativo'] && $a['online'] && !$a['em_pausa'] && in_array(1, $a['departamentos'], true));
# Quem do departamento 1 está online e fora de pausa agora livres = [a for a in chatisp("atendentes/listar")["atendentes"] if a["ativo"] and a["online"] and not a["em_pausa"] and 1 in a["departamentos"]]
{
"ok": true,
"atendentes": [
{
"id": 7,
"nome": "Ana Ribeiro",
"perfil": "Atendente",
"ativo": true,
"departamentos": [1, 2],
"online": true,
"em_pausa": false
},
{
"id": 4,
"nome": "Carlos Mendes",
"perfil": "Supervisor",
"ativo": true,
"departamentos": [1],
"online": true,
"em_pausa": true
}
]
}| Campo | Tipo | Descrição |
|---|---|---|
id | inteiro | O atendente_id (transferência, abertura de atendimento, filtros) e o responsavel_id (ordens de serviço e agenda). |
nome | string | Nome do usuário. |
perfil | string | Nome do perfil de acesso (veja Usuários e perfis). Vazio se o usuário não tem perfil. |
ativo | booleano | Usuário inativo não pode receber conversas, ordens de serviço nem compromissos: usá-lo responde atendente_invalido. |
departamentos | lista de inteiros | Ids dos departamentos em que o usuário atende. |
online | booleano | Se o usuário esteve com o painel aberto nos últimos 2 minutos. |
em_pausa | booleano | Se está online e com uma pausa aberta (almoço, intervalo). Sempre false para quem está offline. |
Erros: só os de acesso.
Transferir pela API direto para um atendente funciona mesmo que ele esteja offline ou em pausa: a conversa fica com ele. Se a intenção é que alguém disponível pegue logo, transfira para o departamento e deixe a distribuição do ChatISP escolher.
Modelos de mensagem (API oficial)
/api_publica.php?r=modelos/listar
Lista os modelos de mensagem (templates) das conexões da API oficial da Meta, em ordem de nome e idioma. Modelo aprovado é o único jeito de falar com o cliente fora da janela de 24 horas. A lista reflete a última sincronização com a Meta, feita pelo botão Sincronizar com a Meta no card Modelos da conexão (veja Conexões de WhatsApp): modelo criado ou aprovado na Meta só aparece aqui depois de sincronizar.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
conexao_id | inteiro | não | Só os modelos dessa conexão. Pode ser o id de qualquer perna de um número gêmeo: a perna QR responde pelos modelos da perna oficial. Sem o parâmetro, vêm os modelos de todas as conexões. |
curl -s "https://atendimento.seuprovedor.com.br/api_publica.php?r=modelos/listar&conexao_id=2" \ -H "Authorization: Bearer $CHATISP_CHAVE"
// Só os que a API consegue enviar $enviaveis = array_filter(chatisp('modelos/listar', ['conexao_id' => 2])['modelos'], fn($m) => $m['enviavel']); foreach ($enviaveis as $m) { echo "{$m['id']} {$m['nome']} ({$m['idioma']}): {$m['variaveis']} variável(is)\n"; }
modelos = chatisp("modelos/listar", {"conexao_id": 2})["modelos"] for m in (m for m in modelos if m["enviavel"]): print(m["id"], m["nome"], m["idioma"], m["variaveis"])
{
"ok": true,
"modelos": [
{
"id": 12,
"conexao_id": 2,
"nome": "aviso_manutencao",
"idioma": "pt_BR",
"categoria": "UTILITY",
"status": "APPROVED",
"corpo": "Olá, {{1}}! Haverá manutenção programada na sua região em {{2}}, das {{3}}. Pedimos desculpas pelo transtorno.",
"variaveis": 3,
"cabecalho": null,
"enviavel": true,
"atualizado_em": "2026-09-28T14:02:11-03:00"
},
{
"id": 15,
"conexao_id": 2,
"nome": "fatura_disponivel",
"idioma": "pt_BR",
"categoria": "UTILITY",
"status": "APPROVED",
"corpo": "Olá, {{1}}. Sua fatura de {{2}} está disponível. Vencimento: {{3}}.",
"variaveis": 3,
"cabecalho": "DOCUMENT",
"enviavel": false,
"atualizado_em": "2026-09-28T14:02:11-03:00"
}
]
}| Campo | Tipo | Descrição |
|---|---|---|
id | inteiro | O modelo_id de mensagens/enviar_modelo. |
conexao_id | inteiro | A conexão da API oficial a que o modelo pertence. |
nome | string | Nome do modelo na Meta. Também aceito em enviar_modelo pelo parâmetro modelo, com idioma. |
idioma | string | Código de idioma na Meta, por exemplo pt_BR. O mesmo nome pode existir em vários idiomas. |
categoria | string | Categoria na Meta: UTILITY, MARKETING ou AUTHENTICATION. Ela define o preço da conversa cobrado pela Meta. |
status | string | Situação na Meta, como devolvida por ela (por exemplo APPROVED, PENDING, REJECTED). Só APPROVED pode ser enviado. |
corpo | string | Texto do corpo, com as variáveis no formato {{1}}, {{2}}... |
variaveis | inteiro | Quantas variáveis o corpo tem. Em enviar_modelo, a lista variaveis precisa ter esse número de valores, na ordem. |
cabecalho | string ou null | Tipo do cabeçalho do modelo: null (sem cabeçalho), TEXT, ou de mídia (IMAGE, VIDEO, DOCUMENT...). |
enviavel | booleano | true quando a API consegue enviar o modelo: aprovado e sem cabeçalho de mídia. Modelos com cabeçalho de mídia respondem modelo_com_midia no envio. |
atualizado_em | string | Data da última sincronização deste modelo. |
Erros:
error | HTTP | Quando |
|---|---|---|
conexao_invalida | 400 | O conexao_id informado não existe. |
parametro_invalido | 400 | conexao_id não é um número inteiro. |
Uma conexão QR sem perna oficial devolve a lista vazia, sem erro: números conectados só por QR não usam modelos.
Etiquetas
/api_publica.php?r=etiquetas/listar
Lista as etiquetas de conversa cadastradas no painel (veja Cadastros), na ordem definida lá.
Parâmetros: nenhum.
curl -s "https://atendimento.seuprovedor.com.br/api_publica.php?r=etiquetas/listar" \ -H "Authorization: Bearer $CHATISP_CHAVE"
$etiquetas = array_column(chatisp('etiquetas/listar')['etiquetas'], 'id', 'nome'); // marca a conversa como "Visita técnica" sem tirar as outras etiquetas chatisp('conversas/etiquetas', ['conversa_id' => 18342, 'adicionar' => [$etiquetas['Visita técnica']]], 'POST');
etiquetas = {e["nome"]: e["id"] for e in chatisp("etiquetas/listar")["etiquetas"]}
# marca a conversa como "Visita técnica" sem tirar as outras etiquetas
chatisp("conversas/etiquetas", {"conversa_id": 18342, "adicionar": [etiquetas["Visita técnica"]]}, "POST"){
"ok": true,
"etiquetas": [
{ "id": 3, "nome": "Visita técnica", "cor": "#f59e0b" },
{ "id": 1, "nome": "Cliente novo", "cor": "#10b981" },
{ "id": 6, "nome": "Cancelamento", "cor": "#ef4444" }
]
}| Campo | Tipo | Descrição |
|---|---|---|
id | inteiro | Id usado em conversas/etiquetas e no filtro etiqueta_id de conversas/listar. |
nome | string | Nome da etiqueta. |
cor | string | Cor em hexadecimal (#rrggbb), a mesma do painel. |
Erros: só os de acesso.
Motivos de encerramento
/api_publica.php?r=motivos/listar
Lista os motivos de encerramento cadastrados no painel (veja Cadastros), ativos e inativos, na ordem definida lá.
Parâmetros: nenhum.
curl -s "https://atendimento.seuprovedor.com.br/api_publica.php?r=motivos/listar" \ -H "Authorization: Bearer $CHATISP_CHAVE"
$motivos = array_column(array_filter(chatisp('motivos/listar')['motivos'], fn($m) => $m['ativo']), 'id', 'nome'); chatisp('conversas/encerrar', ['conversa_id' => 18342, 'motivo_id' => $motivos['Problema resolvido']], 'POST');
motivos = {m["nome"]: m["id"] for m in chatisp("motivos/listar")["motivos"] if m["ativo"]}
chatisp("conversas/encerrar", {"conversa_id": 18342, "motivo_id": motivos["Problema resolvido"]}, "POST"){
"ok": true,
"motivos": [
{ "id": 1, "nome": "Problema resolvido", "ativo": true },
{ "id": 2, "nome": "Dúvida esclarecida", "ativo": true },
{ "id": 4, "nome": "Cliente não respondeu", "ativo": true },
{ "id": 7, "nome": "Engano", "ativo": false }
]
}| Campo | Tipo | Descrição |
|---|---|---|
id | inteiro | O motivo_id de conversas/encerrar. |
nome | string | Nome do motivo. É o texto que aparece em motivo_encerramento nas conversas e no campo motivo do webhook conversa_encerrada. |
ativo | booleano | Motivo inativo não pode ser usado para encerrar (motivo_invalido), mas segue aparecendo nas conversas antigas. |
Erros: só os de acesso.
Guardar e atualizar os catálogos
Os catálogos mudam pouco: departamentos, etiquetas e motivos só mudam quando alguém edita os cadastros no painel. Boas práticas:
- Guarde em cache no seu sistema e atualize em intervalos (por exemplo, a cada hora) ou ao iniciar a integração. Consultar o catálogo a cada envio gasta o limite por minuto à toa.
- Prefira ids a nomes. Nomes podem ser editados no painel a qualquer momento; o id continua o mesmo. Se a sua configuração usa nomes (como nos exemplos acima), resolva o id ao iniciar e avise quando um nome não for encontrado.
- Trate os erros de cadastro (
departamento_invalido,atendente_invalido,motivo_invalido,etiqueta_invalida) como sinal para recarregar o catálogo: algo foi desativado ou excluído no painel. - Presença muda o tempo todo. Os campos
onlineeem_pausadeatendentes/listarvalem para o momento da consulta; não os guarde em cache. - Estado da conexão também. Antes de um disparo grande, confira em
conexoes/listarse o número estáconectada.