API pública do ChatISP
Integre o ChatISP aos sistemas do seu provedor: ERP, CRM, portal do assinante, monitoramento (NOC) e BI. São 37 operações que cobrem mensagens, conversas, contatos, ordens de serviço, agenda e indicadores, com chaves de permissões granulares, respostas JSON padronizadas e avisos em tempo real por webhooks assinados.
Visão geral
A API pública é o canal de máquina do ChatISP: permite que outro sistema do provedor trabalhe com o atendimento sem abrir o painel. Ela funciona nas duas direções:
- Do seu sistema para o ChatISP: chamadas HTTPS autenticadas por chave para enviar mensagens (texto, modelo aprovado da API oficial e arquivo), listar e consultar conversas com o histórico, transferir, encerrar, etiquetar e anotar atendimentos, abrir atendimentos na fila, consultar e renomear contatos, abrir e movimentar ordens de serviço, marcar compromissos na agenda e ler os indicadores do atendimento.
- Do ChatISP para o seu sistema: webhooks de saída. O ChatISP faz um POST assinado para o endereço que você cadastrar quando uma mensagem chega ou sai, quando uma conversa nasce, muda de dono ou é encerrada, e quando uma OS é aberto ou atualizado. Veja Webhooks de saída.
As 37 operações
Toda a API usa um endereço único; a operação é escolhida pelo parâmetro r, no formato recurso/acao. A coluna Escopo mostra a permissão que a chave precisa ter (veja Permissões da chave); "qualquer chave" quer dizer que basta a chave estar ativa.
Rota (r) | Método | Escopo | O que faz |
|---|---|---|---|
| Catálogos: os ids que o resto da API pede | |||
chave/info | GET | qualquer chave | Nome, escopos e limite da chave; versão da API, fuso horário e plano do servidor. |
conexoes/listar | GET | qualquer chave | Números de WhatsApp (QR e API oficial), estado e par gêmeo. |
departamentos/listar | GET | qualquer chave | Departamentos, ativos e inativos, e qual recebe as conversas novas. |
atendentes/listar | GET | qualquer chave | Atendentes com perfil, departamentos, presença e pausa. |
modelos/listar | GET | qualquer chave | Modelos de mensagem da API oficial e se podem ser enviados pela API. |
etiquetas/listar | GET | qualquer chave | Etiquetas de conversa, com cor. |
motivos/listar | GET | qualquer chave | Motivos de encerramento. |
| Mensagens | |||
mensagens/enviar | POST | mensagens_enviar | Envia um texto para um telefone ou uma conversa. |
mensagens/enviar_modelo | POST | mensagens_enviar | Envia um modelo aprovado pela Meta (fora da janela de 24 horas). |
mensagens/enviar_arquivo | POST | mensagens_enviar | Envia imagem, vídeo, áudio ou documento, com legenda opcional. |
mensagens/arquivo | GET | conversas_ler | Baixa o arquivo de uma mensagem (resposta binária, fora do JSON). |
| Conversas | |||
conversas/listar | GET | conversas_ler | Lista conversas com filtros e paginação. |
conversas/consultar | GET | conversas_ler | Uma conversa (por id, protocolo ou telefone) com as últimas mensagens. |
conversas/mensagens | GET | conversas_ler | Histórico de mensagens paginado por cursor. |
conversas/transferir | POST | conversas_gerir | Transfere para um departamento ou atendente. |
conversas/encerrar | POST | conversas_gerir | Encerra o atendimento, com motivo opcional. |
conversas/etiquetas | POST | conversas_gerir | Define, acrescenta ou remove etiquetas. |
conversas/nota | POST | conversas_gerir | Grava uma nota interna (a equipe vê, o cliente não). |
| Contatos e atendimentos | |||
atendimentos/abrir | POST | atendimentos_abrir | Coloca um número na fila de um departamento ou direto com um atendente, sem enviar nada ao cliente. |
contatos/listar | GET | contatos | Contatos (um por número), com busca e paginação. |
contatos/consultar | GET | contatos | Um contato com o histórico de atendimentos. |
contatos/renomear | POST | contatos | Grava o nome do contato para as conversas atuais e futuras. |
| Ordens de serviço | |||
tickets/etapas | GET | tickets_ler | Etapas do quadro de ordens de serviço. |
tickets/tipos | GET | tickets_ler | Tipos de OS. |
tickets/listar | GET | tickets_ler | Lista ordens de serviço com filtros e paginação. |
tickets/consultar | GET | tickets_ler | Uma OS com a linha do tempo. |
tickets/criar | POST | tickets_gerir | Abre uma OS. |
tickets/mover | POST | tickets_gerir | Move a OS de etapa. |
tickets/atribuir | POST | tickets_gerir | Define ou retira o responsável. |
tickets/comentar | POST | tickets_gerir | Acrescenta um comentário. |
| Agenda | |||
agenda/tipos | GET | agenda_ler | Tipos de compromisso. |
agenda/listar | GET | agenda_ler | Compromissos de um período. |
agenda/consultar | GET | agenda_ler | Um compromisso. |
agenda/criar | POST | agenda_gerir | Marca um compromisso. |
agenda/concluir | POST | agenda_gerir | Conclui um compromisso, com desfecho opcional. |
agenda/cancelar | POST | agenda_gerir | Cancela um compromisso. |
| Indicadores | |||
relatorios/resumo | GET | relatorios | Volumes, tempos em horário útil, satisfação e números por departamento e atendente. |
Na coluna Método, GET indica uma leitura: ela também aceita POST. As operações marcadas com POST alteram algo e só aceitam POST.
Casos de uso típicos de um provedor
| Sistema | O que integrar | Rotas e eventos |
|---|---|---|
| ERP / financeiro | Confirmação de pagamento, segunda via, aviso de bloqueio e desbloqueio, boleto em PDF. | mensagens/enviar, mensagens/enviar_modelo, mensagens/enviar_arquivo |
| NOC / monitoramento | Aviso de rompimento ou manutenção aos assinantes da região, OS automático para a equipe de campo. | mensagens/enviar_modelo, tickets/criar, tickets/comentar |
| Portal do assinante e site | "Fale conosco" que cai na fila do departamento certo; agendamento de visita técnica. | atendimentos/abrir, agenda/criar |
| CRM | Histórico de atendimentos por cliente, registro de cada conversa encerrada com protocolo, resumo e motivo. | contatos/consultar, conversas/mensagens, webhook conversa_encerrada |
| Sistema de ordens de serviço | Espelhar ordens de serviço do ChatISP, mover etapas quando a OS anda, atribuir técnico. | tickets/*, webhooks ticket_criado e ticket_atualizado |
| BI / painel de gestão | Indicadores diários, sincronização incremental de conversas. | relatorios/resumo, conversas/listar com atualizadas_desde |
| Automação interna | Etiquetar e transferir conversas por regra própria, anotar dados do ERP na conversa. | conversas/etiquetas, conversas/transferir, conversas/nota, webhook mensagem_recebida |
Programas completos para vários desses casos estão em Exemplos práticos.
Requisitos
| Requisito | Detalhe |
|---|---|
| Plano com API pública Recurso de plano | A API pública e os webhooks fazem parte dos planos PREMIUM, GOLD e ENTERPRISE, e ficam liberados durante o teste grátis. Em planos sem o recurso, os cards de chaves e de webhooks da tela de Integrações aparecem trancados com o aviso do plano necessário, e qualquer chamada responde HTTP 403 com "error":"plano". |
| Quantidade de chaves Limite por plano | Chaves ativas ao mesmo tempo: até 3 no PREMIUM, até 10 no GOLD, sem limite no ENTERPRISE e no teste. O medidor ao lado do título do card mostra o uso; no limite, o botão Nova chave deixa de aparecer. Chaves inativas não contam. |
| Licença em dia | Com a licença bloqueada (teste expirado, inadimplência, licença desativada ou sem comunicação com a central), a API recusa as chamadas com HTTP 403 plano, mesmo em plano elegível. |
| Permissão no painel | Criar, editar, revelar e excluir chaves e webhooks exige a permissão Integrações no perfil de acesso do usuário (veja Usuários e perfis). |
| Conexão de WhatsApp | As rotas de envio e de abertura de atendimento precisam de uma conexão conectada. Veja Conexões de WhatsApp. |
| Rede | Acesso HTTPS ao endereço do seu ChatISP a partir do servidor que vai chamar a API. |
Instalação própria e ChatISP Cloud
A API é a mesma nas duas formas de uso; muda só o endereço.
- Instalação própria (servidor do provedor): o endereço é o domínio pelo qual você acessa o painel. Sem domínio configurado, o servidor responde com certificado autoassinado e o seu sistema teria de aceitá-lo explicitamente. Configure um domínio com Let's Encrypt em Servidor antes de colocar a integração em produção.
- ChatISP Cloud: o endereço é o do seu painel hospedado pela Ravi Systems, já com certificado válido.
Nos dois casos, o endereço exato aparece no card API do ChatISP, em Endereço da API.
Criar uma chave de API
A chave é a única credencial da API: não há usuário, senha nem sessão. Crie uma chave para cada integração, com só as permissões que ela usa e um limite de chamadas por minuto.
Passo a passo
- No menu lateral, abra Integrações.
- Localize o card API do ChatISP ("Chaves para outros sistemas usarem a API: mensagens, conversas, contatos, ordens de serviço, agenda e indicadores, cada chave com as suas permissões."). Logo abaixo do título aparece o Endereço da API, com o botão Documentação da API: anote o endereço, é a URL que a integração vai chamar.
- Clique em Nova chave.
- Preencha o Nome (até 120 caracteres) com algo que identifique a integração, por exemplo "ERP financeiro" ou "NOC". Esse nome aparece no histórico de tudo o que a chave fizer.
- Ligue as permissões que a integração usa. Elas estão em três grupos: Atendimento, Ordens de serviço e agenda e Gestão. Numa chave nova, Enviar mensagens, Consultar conversas e Abrir atendimentos vêm ligadas; as demais vêm desligadas. A tabela completa está em Permissões da chave.
- Ajuste o Limite por minuto ("Chamadas aceitas por minuto. 0 desliga o limite."). O padrão é 60 e o máximo é 10000.
- Clique em Salvar. A janela Chave criada mostra a chave completa no campo Chave de API. Clique em Copiar e guarde-a no sistema que vai usar a API.
cisp_7f3a9c21d84e0b56a1f2c3d4e5f60718293a4b5c6d7e8f90
Toda chave começa com cisp_, seguido de 48 caracteres hexadecimais. A lista do card mostra só o começo (por exemplo cisp_7f3a9…) para você reconhecer qual é qual.
A lista de chaves
| Coluna | O que mostra |
|---|---|
| Nome | O nome dado à chave. |
| Chave de API | O começo da chave, para reconhecimento. |
| Permissões | Uma etiqueta para cada permissão ligada. |
| Usos | Total de chamadas autenticadas com a chave. Ao passar o mouse, aparece o Último uso. |
| Situação | Ativa ou Inativa. |
| Ações | Editar, Revelar e Excluir. |
Revelar, editar e excluir
- Revelar mostra de novo a chave completa, com o botão Copiar, a qualquer momento, para quem tem a permissão Integrações.
- Editar muda nome, permissões, limite por minuto e o switch Ativa. A chave em si não muda: a integração segue funcionando com o mesmo valor, já com as permissões novas. Desligar Ativa suspende a chave na hora (HTTP 401
chave_invalida) sem apagá-la, e ela deixa de contar no limite do plano. - Excluir pede confirmação ("Excluir esta chave? As integrações que a usam param de funcionar.") e revoga a chave imediatamente.
Como as chaves podem ser reveladas no painel, quem tem a permissão Integrações tem acesso a todas elas. Conceda essa permissão só a quem administra as integrações.
Permissões da chave (escopos)
Cada permissão da tela corresponde a um escopo, um código estável que a API usa para decidir o que a chave pode fazer. O código aparece no campo escopos de chave/info e no erro permissao, que informa qual escopo faltou.
| Nome na tela | Escopo | O que libera | Rotas |
|---|---|---|---|
| Atendimento | |||
| Enviar mensagens | mensagens_enviar | Texto, modelos aprovados da API oficial e arquivos. | mensagens/enviar, mensagens/enviar_modelo, mensagens/enviar_arquivo |
| Consultar conversas | conversas_ler | Listar e consultar conversas, ler o histórico de mensagens e baixar os arquivos. | conversas/listar, conversas/consultar, conversas/mensagens, mensagens/arquivo |
| Abrir atendimentos | atendimentos_abrir | Colocar um número na fila de um departamento ou direto com um atendente. | atendimentos/abrir |
| Gerenciar conversas | conversas_gerir | Transferir, encerrar, etiquetar e anotar conversas. | conversas/transferir, conversas/encerrar, conversas/etiquetas, conversas/nota |
| Contatos | contatos | Listar, consultar e renomear contatos. | contatos/listar, contatos/consultar, contatos/renomear |
| Ordens de serviço e agenda | |||
| Consultar ordens de serviço | tickets_ler | Listar ordens de serviço, ver a linha do tempo, as etapas e os tipos. | tickets/etapas, tickets/tipos, tickets/listar, tickets/consultar |
| Gerenciar ordens de serviço | tickets_gerir | Abrir, mover de etapa, atribuir e comentar ordens de serviço. | tickets/criar, tickets/mover, tickets/atribuir, tickets/comentar |
| Consultar agenda | agenda_ler | Listar e consultar compromissos. | agenda/tipos, agenda/listar, agenda/consultar |
| Gerenciar agenda | agenda_gerir | Marcar, concluir e cancelar compromissos. | agenda/criar, agenda/concluir, agenda/cancelar |
| Gestão | |||
| Indicadores | relatorios | Volumes, tempos em horário útil, satisfação e números por departamento e atendente. | relatorios/resumo |
Os escopos são independentes: Gerenciar ordens de serviço não inclui Consultar ordens de serviço, por exemplo. Uma integração que abre ordens de serviço e depois acompanha o andamento deles precisa dos dois.
Catálogos: liberados para qualquer chave
As rotas de catálogo (chave/info, conexoes/listar, departamentos/listar, atendentes/listar, modelos/listar, etiquetas/listar e motivos/listar) não exigem escopo: qualquer chave ativa pode chamá-las, mesmo com todas as permissões desligadas. Elas devolvem os ids que as outras rotas pedem (conexao_id, departamento_id, atendente_id, modelo_id, etiqueta_id, motivo_id); sem eles nenhuma integração conseguiria montar as chamadas. A tela lembra isso logo abaixo das permissões: "Conexões, departamentos, atendentes, modelos, etiquetas e motivos ficam disponíveis para qualquer chave ativa." Referência em Catálogos.
Quantas chaves criar
- Uma por integração, com nome claro: assim você limita, suspende ou revoga um sistema sem derrubar os outros, e o histórico das conversas mostra qual sistema fez cada ação.
- Separe leitura de escrita quando sistemas diferentes fazem cada coisa. Um painel de BI só precisa de Consultar conversas e Indicadores; o ERP que manda boletos só precisa de Enviar mensagens.
Endereço e autenticação
Todas as chamadas vão para o mesmo endereço, mostrado no card API do ChatISP:
https://<endereço do seu painel>/api_publica.php?r=<recurso>/<acao>
A chave vai no cabeçalho HTTP Authorization, no esquema Bearer. Nunca vai na URL nem no corpo:
Authorization: Bearer cisp_7f3a9c21d84e0b56a1f2c3d4e5f60718293a4b5c6d7e8f90
| Item | Onde vai | Obrigatório | Descrição |
|---|---|---|---|
Authorization | cabeçalho HTTP | sim | Bearer, um espaço e a chave completa. A palavra Bearer aceita maiúsculas ou minúsculas. |
r | query string (recomendado) ou corpo de formulário | sim | A rota, no formato recurso/acao (letras minúsculas e sublinhado). Com corpo JSON, o r precisa estar na URL: ele não é lido de dentro do JSON. |
Não há login nem sessão: cada chamada é independente.
Primeira chamada
A rota chave/info é a ideal para validar endereço e chave: não exige permissão, não altera nada e mostra o que a chave pode fazer.
curl -s "https://atendimento.seuprovedor.com.br/api_publica.php?r=chave/info" \ -H "Authorization: Bearer $CHATISP_CHAVE"
<?php // Cliente mínimo reaproveitável nas outras rotas function chatisp(string $rota, array $dados = [], string $metodo = 'GET'): array { $base = 'https://atendimento.seuprovedor.com.br/api_publica.php'; $chave = getenv('CHATISP_CHAVE'); $url = $base . '?r=' . $rota; $ch = curl_init(); $opcoes = [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30, CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $chave, 'Content-Type: application/json'], ]; if ($metodo === 'POST') { $opcoes[CURLOPT_POST] = true; $opcoes[CURLOPT_POSTFIELDS] = json_encode($dados); } elseif ($dados) { $url .= '&' . http_build_query($dados); } $opcoes[CURLOPT_URL] = $url; curl_setopt_array($ch, $opcoes); $corpo = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $resposta = json_decode((string) $corpo, true) ?? ['ok' => false, 'error' => 'resposta_invalida']; $resposta['_http'] = $status; return $resposta; } $info = chatisp('chave/info'); if (!$info['ok']) { die("Erro {$info['_http']}: {$info['error']}\n"); } echo $info['chave']['nome'], ': ', implode(', ', $info['chave']['escopos']), PHP_EOL;
import os, requests BASE = "https://atendimento.seuprovedor.com.br/api_publica.php" CHAVE = os.environ["CHATISP_CHAVE"] def chatisp(rota, dados=None, metodo="GET"): cab = {"Authorization": f"Bearer {CHAVE}"} if metodo == "POST": r = requests.post(BASE, params={"r": rota}, json=dados or {}, headers=cab, timeout=30) else: r = requests.get(BASE, params={"r": rota, **(dados or {})}, headers=cab, timeout=30) corpo = r.json() corpo["_http"] = r.status_code return corpo info = chatisp("chave/info") if not info["ok"]: raise SystemExit(f"Erro {info['_http']}: {info['error']}") print(info["chave"]["nome"], info["chave"]["escopos"])
{
"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"
}
}Ordem de validação
Toda chamada passa por estas verificações, nesta ordem. A primeira que falhar define a resposta:
rausente ou fora do formatorecurso/acao: HTTP 404rota.- Cabeçalho
Authorization: Bearer ...ausente ou malformado: HTTP 401autenticacao. - Chave inexistente, excluída, inativa ou fora do formato
cisp_...: HTTP 401chave_invalida. - Plano sem API pública ou licença bloqueada: HTTP 403
plano. - A chamada é contada no uso da chave. Se passou do limite por minuto: HTTP 429
cota_excedida. - Corpo declarado como JSON, mas inválido: HTTP 400
json_invalido. - Rota inexistente: HTTP 404
rota. - Rota de escrita chamada sem POST: HTTP 405
metodo. - Chave sem o escopo da rota: HTTP 403
permissao, com o escopo que faltou. - A operação valida os próprios parâmetros e executa.
A partir do passo 5, toda chamada conta no uso da chave (coluna Usos e limite por minuto), mesmo que termine em erro de rota, permissão ou parâmetro. Chamadas com chave inválida não contam.
Chame a API sempre do seu servidor (backend). Nunca coloque a chave em página web, aplicativo instalado no celular ou script que rode no navegador: qualquer pessoa conseguiria copiá-la e agir em nome do provedor.
Formato da requisição
Métodos
- Leitura (listar, consultar, catálogos, indicadores, baixar arquivo): GET ou POST.
- Escrita (enviar, transferir, encerrar, criar, mover...): só POST. Com outro método, a resposta é HTTP 405
metodocom"esperado":"POST".
Onde vão os parâmetros
| Forma | Cabeçalho | Quando usar |
|---|---|---|
| Query string | nenhum | Filtros de leitura em GET: ?r=conversas/listar&abertas=1&limite=20. |
| Formulário | application/x-www-form-urlencoded | O formato padrão do curl -d. Listas repetem o campo com colchetes: variaveis[]=Maria&variaveis[]=R$ 99,90. |
| JSON | application/json | O corpo inteiro é um objeto JSON. Recomendado para escrita. O r vai na URL. |
| Multipart | multipart/form-data | Envio de arquivo em mensagens/enviar_arquivo (campo arquivo). Alternativa em JSON: arquivo_base64. |
A query string vale em qualquer método. Quando o mesmo parâmetro vem na query e no corpo, o corpo vence. Um corpo com Content-Type: application/json que não seja um objeto JSON válido é recusado com HTTP 400 json_invalido.
# formulário curl -s -X POST "https://atendimento.seuprovedor.com.br/api_publica.php?r=mensagens/enviar" \ -H "Authorization: Bearer $CHATISP_CHAVE" \ -d "telefone=44999990000" -d "texto=Olá! Seu técnico está a caminho." # JSON curl -s -X POST "https://atendimento.seuprovedor.com.br/api_publica.php?r=mensagens/enviar" \ -H "Authorization: Bearer $CHATISP_CHAVE" \ -H "Content-Type: application/json" \ -d '{"telefone":"44999990000","texto":"Olá! Seu técnico está a caminho."}'
Tipos de parâmetro
| Tipo | Aceita | Observações |
|---|---|---|
| inteiro | 42 ou "42" | Ids, pagina, limite. Texto que não é número inteiro: parametro_invalido com o campo. |
| booleano | true/false, 1/0, sim/nao, yes/no | Vazio vale o padrão da rota. |
| lista | array JSON, campo[]=a&campo[]=b ou texto separado por vírgula (3,7,9) | Etiquetas, estados. Lista vazia ([] ou "") é diferente de não enviar o campo. |
| data | ISO 8601, AAAA-MM-DD ou AAAA-MM-DD HH:MM:SS | Veja Datas e fuso horário. |
| texto | UTF-8 | Espaços nas pontas são removidos. Cada rota informa o tamanho máximo. |
Formato da resposta
Toda resposta é JSON (Content-Type: application/json; charset=utf-8, Cache-Control: no-store) com um envelope igual em todas as rotas:
| Situação | Corpo |
|---|---|
| Sucesso | {"ok": true, ...campos da operação} |
| Erro | {"ok": false, "error": "codigo", ...campos extras} |
O campo error é sempre um código estável, sem acento e sem tradução, pensado para o seu sistema decidir o que fazer. Os campos extras ajudam a corrigir a chamada: campo (qual parâmetro), aceitos (valores permitidos), maximo, esperado, escopo, entre outros. Acentos vêm sem escape ("Suporte técnico") e barras também.
HTTP 400 {"ok":false,"error":"parametro_invalido","campo":"estado","aceitos":["ia","fila","humano","encerrada","auto"]}
HTTP 403 {"ok":false,"error":"permissao","escopo":"tickets_gerir"}
HTTP 404 {"ok":false,"error":"nao_encontrado"}Status HTTP
O status HTTP é real e coerente com o resultado: confira o status e o campo ok.
| HTTP | Quando |
|---|---|
| 200 | A operação foi executada. |
| 400 | Parâmetro ausente ou inválido, conexão inadequada, JSON inválido. |
| 401 | Sem chave, cabeçalho malformado ou chave inválida. |
| 403 | Plano sem o recurso, licença bloqueada ou chave sem o escopo. |
| 404 | Rota inexistente ou registro não encontrado. |
| 405 | Rota de escrita chamada sem POST. |
| 409 | Conflito com o estado atual: conexão desconectada, conversa já encerrada, janela de 24 horas fechada, quadro de ordens de serviço sem etapas. |
| 410 | O arquivo da mensagem existiu, mas não está mais no servidor. |
| 413 | Arquivo grande demais. |
| 415 | Tipo de arquivo não suportado. |
| 429 | Limite por minuto da chave estourado, com o cabeçalho Retry-After. |
| 500 | Falha interna ao gravar um arquivo. |
| 502 | O WhatsApp não aceitou a mensagem (erro envio). A tentativa fica registrada na conversa. |
Respostas que não são JSON
Só mensagens/arquivo: em caso de sucesso devolve o próprio arquivo, com Content-Type do arquivo (imagens e PDF) ou application/octet-stream (demais tipos) e Content-Disposition com o nome original. Em caso de erro, devolve o envelope JSON normal.
Objetos que se repetem
As rotas de mensagens, conversas e contatos devolvem a conversa e a mensagem sempre com os mesmos campos (os detalhes estão em Conversas e Mensagens). Valores que você vai encontrar:
| Campo | Valores |
|---|---|
conversa estado | fila (aguardando atendente), auto (num fluxo de atendimento), ia (com a IA), humano (com um atendente), encerrada. |
mensagem direcao | recebida (do cliente) ou enviada (do provedor). Notas internas nunca aparecem na API. |
mensagem autor | cliente, atendente, ia ou sistema (fluxos, avisos automáticos, campanhas e envios feitos pela API). |
mensagem tipo | texto, imagem, audio, video, documento, localizacao, contato. |
mensagem status | pendente, enviada, entregue, lida, erro. |
Paginação e cursor
Paginação numerada
As listagens grandes (conversas/listar, contatos/listar, tickets/listar e agenda/listar) usam página e limite:
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
pagina | inteiro | 1 | Página desejada, a partir de 1. |
limite | inteiro | 50 | Itens por página, de 1 a 100. Fora da faixa: parametro_invalido com "maximo":100. |
A resposta traz o bloco paginacao:
"paginacao": {
"pagina": 2,
"limite": 50,
"total": 137,
"paginas": 3
}total é a quantidade de registros que atendem aos filtros e paginas é quantas páginas existem com esse limite (0 quando não há registros). Para percorrer tudo, chame até pagina chegar em paginas. Página além da última devolve a lista vazia, sem erro.
Para sincronizar uma base grande, prefira filtros de data incrementais (atualizadas_desde em conversas, atualizados_desde em contatos) a varrer todas as páginas a cada execução. Registros novos que entram enquanto você pagina podem deslocar itens entre páginas.
Cursor do histórico de mensagens
O histórico de uma conversa (conversas/mensagens) usa cursor pelo id da mensagem, que não se desloca quando chegam mensagens novas:
| Parâmetro | Descrição |
|---|---|
| sem cursor | As mensagens mais recentes, em ordem cronológica. |
antes_de | Mensagens com id menor que o informado: para rolar o histórico para trás. |
depois_de | Mensagens com id maior que o informado: para buscar o que chegou desde a última leitura. |
limite | De 1 a 100, padrão 50. |
"tem_mais": true,
"cursor": {
"antes_de": 402801,
"depois_de": 402850
}tem_mais diz se ainda há mensagens na direção pedida. Para continuar rolando para trás, passe cursor.antes_de no próximo antes_de; para acompanhar as novas, guarde cursor.depois_de e use-o como depois_de na próxima consulta. As mensagens vêm sempre em ordem cronológica (da mais antiga para a mais nova).
Datas e fuso horário
Datas na resposta
Todas as datas de saída vêm em ISO 8601 com o fuso do servidor, por exemplo 2026-10-01T09:12:40-03:00. Datas ausentes vêm como null. O fuso do servidor aparece em chave/info (servidor.fuso_horario), junto com o relógio dele (servidor.agora), útil para conferir diferença de horário com o seu sistema.
Datas na requisição
| Formato | Exemplo | Interpretação |
|---|---|---|
| ISO 8601 com fuso | 2026-10-01T09:00:00-03:00, 2026-10-01T12:00:00Z | Convertida para o fuso do servidor. Recomendado. |
| Data e hora sem fuso | 2026-10-01 09:00:00 ou 2026-10-01T09:00:00 | Entendida no fuso do servidor. |
| Só a data | 2026-10-01 | Início do dia (00:00:00) nos filtros "desde" e "de"; fim do dia (23:59:59) nos filtros "até". |
Anos fora de 2000 a 2100 ou texto que não é data respondem HTTP 400 data_invalida com o campo. Períodos com fim antes do início, ou maiores que o permitido pela rota (366 dias em indicadores e agenda), respondem periodo_invalido.
Telefones
O telefone segue a mesma regra da tela do painel. Pontuação, espaços e parênteses são ignorados.
| Como você envia | Como o ChatISP entende |
|---|---|
44999990000 ou (44) 99999-0000 | Número brasileiro: o código do país 55 é acrescentado. Vira 5544999990000. |
4433330000 | Fixo brasileiro com DDD (10 dígitos). Vira 554433330000. |
5544999990000 | Já com o 55: aceito como está. |
+55 44 99999-0000 | Com + e 55: aceito como brasileiro. |
+351 912 345 678 | Outro país: obrigatório começar com +. Aceito com 8 a 15 dígitos. |
Regras dos números brasileiros: DDD de 11 a 99 (sem zero) e, quando o número tem 11 dígitos, o terceiro precisa ser o 9 do celular. Fora disso, a resposta é HTTP 400 telefone_invalido. Sem o +, um número que não se encaixa como brasileiro também é recusado, para não enviar mensagem ao país errado.
Nas consultas por telefone (conversas, contatos), o ChatISP procura o número com e sem o nono dígito, porque o WhatsApp de alguns celulares antigos ainda usa o formato de 8 dígitos. Nas respostas, o telefone vem só com dígitos e com o código do país, no formato em que a conversa está registrada.
Códigos de erro
Lista completa dos valores possíveis de error. Cada página da referência mostra quais erros cada rota pode devolver.
error | HTTP | Significado e o que fazer |
|---|---|---|
| Acesso | ||
rota | 404 | r ausente, fora do formato recurso/acao ou rota inexistente. Confira a grafia e, com corpo JSON, lembre que r vai na URL. |
autenticacao | 401 | Faltou o cabeçalho Authorization ou ele não está no formato Bearer <chave>. |
chave_invalida | 401 | Chave inexistente, excluída ou inativa; ou copiada pela metade, com espaço ou quebra de linha. |
plano | 403 | O plano não inclui a API pública ou a licença está bloqueada. O extra plano traz o nome do plano em vigor. |
cota_excedida | 429 | A chave passou do limite por minuto. Extra cota_minuto; espere os segundos do cabeçalho Retry-After. |
permissao | 403 | A chave não tem o escopo da rota. O extra escopo diz qual ligar na chave. |
metodo | 405 | Rota de escrita chamada sem POST. Extra esperado. |
json_invalido | 400 | O corpo foi declarado application/json, mas não é um objeto JSON válido. |
| Parâmetros | ||
parametro_obrigatorio | 400 | Faltou um parâmetro. O extra campo diz qual; quando há alternativas, vem separado por barra vertical ("modelo_id|modelo": informe um deles). |
parametro_invalido | 400 | Valor em formato errado (inteiro, booleano, lista) ou fora do permitido. Extras campo e, conforme o caso, aceitos ou maximo. |
identificador_obrigatorio | 400 | A rota precisa saber de qual registro se trata: informe o id (conversa_id, ticket_id...), o protocolo ou o numero, conforme a rota. |
data_invalida | 400 | Data que não pôde ser lida. Extra campo. |
periodo_invalido | 400 | Fim antes do início, ou período maior que o permitido (extra maximo_dias). |
telefone_invalido | 400 | Telefone fora da regra. Veja Telefones. |
texto_invalido | 400 | Texto vazio ou maior que o limite da rota (mensagem, nota, comentário). Extra campo quando não é o texto. |
titulo_invalido | 400 | Título de OS ou compromisso vazio ou com mais de 160 caracteres. |
nome_invalido | 400 | Nome de contato vazio ou com mais de 120 caracteres. |
legenda_invalida | 400 | Legenda de arquivo com mais de 1024 caracteres. |
link_invalido | 400 | Link de compromisso que não começa com http:// ou https://, tem espaço ou passa de 500 caracteres. |
| Registros | ||
nao_encontrado | 404 | O registro pedido não existe: conversa, mensagem (ou mensagem sem arquivo), contato, OS ou compromisso. |
conversa_invalida | 400 | A conversa_id informada para vincular uma OS não existe. |
conversa_encerrada | 409 | Transferir ou encerrar exige conversa aberta. |
departamento_invalido | 400 | Departamento inexistente ou inativo. |
atendente_invalido | 400 | Atendente inexistente, inativo ou excluído. |
motivo_invalido | 400 | Motivo de encerramento inexistente ou inativo. |
etiqueta_invalida | 400 | Algum id de etiqueta não existe. Extra campo (etiquetas, adicionar ou remover). |
etapa_invalida | 400 | Etapa de OS inexistente ou inativa. |
sem_etapas | 409 | O quadro de ordens de serviço não tem etapa ativa para receber o OS nova. Configure as etapas no painel. |
| Conexão e envio | ||
sem_conexao | 400 | Nenhum conexao_id foi informado e não há conexão conectada (do tipo exigido pela rota). |
conexao_id_obrigatorio | 400 | Há mais de um número conectado e a chave não tem Número de origem: informe conexao_id (veja Conexões) ou defina o Número de origem na chave de API (Integrações, Chaves de API). |
conexao_invalida | 400 | A conexão não existe ou não é do tipo exigido (por exemplo, modelo em número sem API oficial). Extra tipo_esperado quando é questão de tipo. |
conexao_desconectada | 409 | A conexão existe, mas não está conectada (no número gêmeo, nenhuma das duas está). |
modelo_invalido | 400 | Modelo inexistente, de outra conexão ou não aprovado pela Meta. |
modelo_com_midia | 400 | O modelo tem cabeçalho de mídia (imagem, vídeo, documento), que a API não envia. |
variaveis_invalidas | 400 | variaveis não é lista, ou faltam valores. Extra esperadas com quantas o modelo pede. |
janela_fechada | 409 | Na API oficial, texto livre só vai até 24 horas depois da última mensagem do cliente. Use um modelo aprovado. A tentativa fica registrada; extras conversa_id, protocolo, mensagem_id e mensagem. |
envio | 502 | O WhatsApp não aceitou a mensagem. Extra detalhe com o motivo do canal, além de conversa_id, protocolo, mensagem_id e mensagem (a tentativa fica na conversa, marcada com erro). |
| Arquivos | ||
arquivo_invalido | 400 | Upload falhou, arquivo vazio ou arquivo_base64 que não é base64 válido. |
arquivo_grande | 413 ou 400 | Arquivo acima de 45 MB (413, extra maximo_bytes). Quando o próprio servidor web recusa o upload pelo tamanho, a resposta é 400 com o mesmo código. |
tipo_nao_suportado | 415 | Tipo de arquivo que o WhatsApp não aceita (por exemplo, executáveis). Extra mimetype detectado pelo conteúdo. |
arquivo_indisponivel | 410 | A mensagem tinha arquivo, mas ele não está mais no servidor (por exemplo, removido do disco). |
arquivo | 500 | Falha ao gravar o arquivo no servidor. Repita mais tarde; persistindo, fale com o suporte. |
Trate os erros pelo código, nunca pelo texto de detalhe (que vem do canal e pode mudar). Ignore campos extras que o seu sistema não conhece: novos extras podem aparecer para ajudar no diagnóstico.
Limites
Limite por minuto da chave
Cada chave tem o seu Limite por minuto (padrão 60, máximo 10000, 0 sem limite). A contagem é por minuto do relógio do servidor: zera quando o minuto vira (às 10:41:00, às 10:42:00...), não numa janela móvel de 60 segundos.
Com limite definido, toda resposta traz os cabeçalhos:
| Cabeçalho | Conteúdo |
|---|---|
X-RateLimit-Limit | O limite por minuto da chave. |
X-RateLimit-Remaining | Quantas chamadas ainda cabem no minuto atual. |
Retry-After | Só na resposta 429: segundos até o próximo minuto. |
Chave com limite 0 não recebe os cabeçalhos X-RateLimit-*.
HTTP/1.1 429 Too Many Requests
Retry-After: 23
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
Content-Type: application/json; charset=utf-8
{"ok":false,"error":"cota_excedida","cota_minuto":60}A chamada recusada não foi executada: espere o Retry-After e repita. As recusas também contam no minuto, então repetir em laço sem esperar não adianta.
Tamanhos e quantidades
| Item | Limite |
|---|---|
| Itens por página | 1 a 100 (padrão 50). |
| Texto de mensagem | 4096 caracteres. |
| Legenda de arquivo | 1024 caracteres. |
| Arquivo enviado | 45 MB. O servidor web da instalação pode impor um limite menor para upload multipart; nesse caso use arquivo_base64 ou reduza o arquivo. |
| Nota interna e nota de abertura de atendimento | 900 caracteres. |
| Título de OS ou compromisso | 160 caracteres. |
| Período de indicadores e agenda | 366 dias. |
| Chaves ativas | Conforme o plano: 3 (PREMIUM), 10 (GOLD), sem limite (ENTERPRISE e teste). |
Ritmo de envio em massa
A API envia cada mensagem na hora em que é chamada. Para avisos a muitos assinantes, espalhe os envios no tempo em vez de disparar centenas de chamadas simultâneas, e ajuste o limite por minuto da chave a esse ritmo. Para listas grandes com acompanhamento de entregas e respostas, a tela Automação de envios já faz o ritmo sozinha.
Versão da API
Toda resposta, inclusive as de erro, traz o cabeçalho:
X-ChatISP-Api-Versao: 1
O mesmo valor aparece em chave/info, no campo servidor.api_versao. A versão atual é a 1. Registre o valor nos logs da integração: ele ajuda o suporte a identificar com qual versão o seu sistema conversou.
As rotas, os nomes de campo e os códigos de erro documentados aqui são estáveis. A API pode ganhar rotas, parâmetros opcionais e campos novos nas respostas sem mudar de versão; por isso o seu sistema deve ignorar campos desconhecidos em vez de recusar a resposta. Campos antigos são mantidos para quem já integrou: por exemplo, atendimentos/abrir segue devolvendo conversa_id, protocolo, estado e ja_existia no nível de cima, além do objeto conversa completo.
Segurança e boas práticas
Checklist
- Uma chave por integração, com Nome claro e só os escopos necessários.
- Guarde a chave em variável de ambiente ou cofre de segredos do servidor, nunca no código versionado nem em logs.
- Use sempre HTTPS. Em instalação própria, configure domínio com certificado válido antes da produção.
- Limite por minuto compatível com o uso real: ele também protege contra um laço descontrolado no seu sistema.
- Confira
oke o status HTTP em toda resposta; decida pelo código deerror. - Em 429, respeite o
Retry-After. Em erro de rede ou HTTP 5xx, repita leituras com espera crescente. Não repita envios às cegas: uma mensagem que deu timeout pode ter sido entregue, e repetir duplica o envio ao cliente. Antes, confira o histórico comconversas/mensagens. - Guarde os ids devolvidos (
conversa_id,mensagem_id,ticket_id) para cruzar com os webhooks. - Faça cache dos catálogos (departamentos, atendentes, etiquetas, motivos) e atualize de tempos em tempos, em vez de consultá-los a cada chamada.
- Prefira webhooks a consultar em laço para saber o que mudou.
- Desative ou exclua as chaves de integrações desligadas. Para trocar uma chave, crie a nova, atualize a integração e só então exclua a antiga.
O que fica registrado
As ações feitas pela API aparecem no painel com o nome da chave: o evento "API" na linha do tempo da conversa, as notas como "API (nome da chave): ...", as transferências e encerramentos com "API: nome da chave", e os comentários de OS com "[API: nome da chave]". As mensagens enviadas pela API saem como autor sistema, sem assinatura de atendente.
Problemas frequentes
| Sintoma | Causa provável e solução |
|---|---|
HTTP 401 autenticacao com a chave certa | O cabeçalho não chegou como Authorization: Bearer cisp_.... Alguns proxies e bibliotecas descartam o cabeçalho em redirecionamentos: chame direto o endereço https://. |
HTTP 401 chave_invalida | Chave excluída, inativa, ou copiada com espaço ou quebra de linha. Use Revelar e Copiar de novo. |
HTTP 404 rota numa chamada com JSON | O r foi colocado dentro do JSON. Mova para a URL. |
HTTP 403 permissao | Ligue na chave o escopo informado no campo escopo da resposta. |
HTTP 403 plano | Plano sem a API pública ou licença bloqueada. Confira a situação da licença em Conta e licença. |
HTTP 400 conexao_id_obrigatorio | Há mais de um número conectado e a chave não tem Número de origem. Liste com conexoes/listar e informe conexao_id, ou defina o Número de origem na chave de API (Integrações, Chaves de API). |
HTTP 409 janela_fechada | Número da API oficial sem mensagem do cliente nas últimas 24 horas. Envie um modelo aprovado com mensagens/enviar_modelo. |
| Erro de certificado no seu sistema | Instalação própria sem domínio responde com certificado autoassinado. Configure um domínio com Let's Encrypt em Servidor. |
Coleção para Postman e Insomnia
Para testar a API sem escrever código, baixe a coleção pronta com as 37 rotas, já com método, parâmetros de exemplo e descrição de cada uma:
Baixar a coleção (chatisp-api.postman_collection.json)
- No Postman, use Import e escolha o arquivo. No Insomnia, use Import em uma coleção; o formato do Postman é reconhecido.
- Nas variáveis da coleção, preencha
base_urlcom o endereço do seu painel (por exemplohttps://atendimento.seuprovedor.com.br, sem barra no final) echavecom a sua chavecisp_.... - Rode primeiro Informações da chave (
chave/info) para confirmar endereço, chave e escopos. - Use os catálogos para descobrir os ids reais da sua instalação antes de testar as rotas de escrita.
As rotas de escrita da coleção agem de verdade: enviam mensagens a clientes, encerram conversas, abrem ordens de serviço. Teste com o seu próprio telefone e com uma chave de teste, com só os escopos necessários.