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étodoEscopoO que faz
Catálogos: os ids que o resto da API pede
chave/infoGETqualquer chaveNome, escopos e limite da chave; versão da API, fuso horário e plano do servidor.
conexoes/listarGETqualquer chaveNúmeros de WhatsApp (QR e API oficial), estado e par gêmeo.
departamentos/listarGETqualquer chaveDepartamentos, ativos e inativos, e qual recebe as conversas novas.
atendentes/listarGETqualquer chaveAtendentes com perfil, departamentos, presença e pausa.
modelos/listarGETqualquer chaveModelos de mensagem da API oficial e se podem ser enviados pela API.
etiquetas/listarGETqualquer chaveEtiquetas de conversa, com cor.
motivos/listarGETqualquer chaveMotivos de encerramento.
Mensagens
mensagens/enviarPOSTmensagens_enviarEnvia um texto para um telefone ou uma conversa.
mensagens/enviar_modeloPOSTmensagens_enviarEnvia um modelo aprovado pela Meta (fora da janela de 24 horas).
mensagens/enviar_arquivoPOSTmensagens_enviarEnvia imagem, vídeo, áudio ou documento, com legenda opcional.
mensagens/arquivoGETconversas_lerBaixa o arquivo de uma mensagem (resposta binária, fora do JSON).
Conversas
conversas/listarGETconversas_lerLista conversas com filtros e paginação.
conversas/consultarGETconversas_lerUma conversa (por id, protocolo ou telefone) com as últimas mensagens.
conversas/mensagensGETconversas_lerHistórico de mensagens paginado por cursor.
conversas/transferirPOSTconversas_gerirTransfere para um departamento ou atendente.
conversas/encerrarPOSTconversas_gerirEncerra o atendimento, com motivo opcional.
conversas/etiquetasPOSTconversas_gerirDefine, acrescenta ou remove etiquetas.
conversas/notaPOSTconversas_gerirGrava uma nota interna (a equipe vê, o cliente não).
Contatos e atendimentos
atendimentos/abrirPOSTatendimentos_abrirColoca um número na fila de um departamento ou direto com um atendente, sem enviar nada ao cliente.
contatos/listarGETcontatosContatos (um por número), com busca e paginação.
contatos/consultarGETcontatosUm contato com o histórico de atendimentos.
contatos/renomearPOSTcontatosGrava o nome do contato para as conversas atuais e futuras.
Ordens de serviço
tickets/etapasGETtickets_lerEtapas do quadro de ordens de serviço.
tickets/tiposGETtickets_lerTipos de OS.
tickets/listarGETtickets_lerLista ordens de serviço com filtros e paginação.
tickets/consultarGETtickets_lerUma OS com a linha do tempo.
tickets/criarPOSTtickets_gerirAbre uma OS.
tickets/moverPOSTtickets_gerirMove a OS de etapa.
tickets/atribuirPOSTtickets_gerirDefine ou retira o responsável.
tickets/comentarPOSTtickets_gerirAcrescenta um comentário.
Agenda
agenda/tiposGETagenda_lerTipos de compromisso.
agenda/listarGETagenda_lerCompromissos de um período.
agenda/consultarGETagenda_lerUm compromisso.
agenda/criarPOSTagenda_gerirMarca um compromisso.
agenda/concluirPOSTagenda_gerirConclui um compromisso, com desfecho opcional.
agenda/cancelarPOSTagenda_gerirCancela um compromisso.
Indicadores
relatorios/resumoGETrelatoriosVolumes, 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

SistemaO que integrarRotas e eventos
ERP / financeiroConfirmação de pagamento, segunda via, aviso de bloqueio e desbloqueio, boleto em PDF.mensagens/enviar, mensagens/enviar_modelo, mensagens/enviar_arquivo
NOC / monitoramentoAviso 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
CRMHistó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çoEspelhar 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ãoIndicadores diários, sincronização incremental de conversas.relatorios/resumo, conversas/listar com atualizadas_desde
Automação internaEtiquetar 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

RequisitoDetalhe
Plano com API pública Recurso de planoA 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 planoChaves 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 diaCom 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 painelCriar, 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 WhatsAppAs rotas de envio e de abertura de atendimento precisam de uma conexão conectada. Veja Conexões de WhatsApp.
RedeAcesso 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

  1. No menu lateral, abra Integrações.
  2. 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.
  3. Clique em Nova chave.
  4. 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.
  5. 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.
  6. Ajuste o Limite por minuto ("Chamadas aceitas por minuto. 0 desliga o limite."). O padrão é 60 e o máximo é 10000.
  7. 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.
formato da chave
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

ColunaO que mostra
NomeO nome dado à chave.
Chave de APIO começo da chave, para reconhecimento.
PermissõesUma etiqueta para cada permissão ligada.
UsosTotal de chamadas autenticadas com a chave. Ao passar o mouse, aparece o Último uso.
SituaçãoAtiva ou Inativa.
AçõesEditar, 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 telaEscopoO que liberaRotas
Atendimento
Enviar mensagensmensagens_enviarTexto, modelos aprovados da API oficial e arquivos.mensagens/enviar, mensagens/enviar_modelo, mensagens/enviar_arquivo
Consultar conversasconversas_lerListar e consultar conversas, ler o histórico de mensagens e baixar os arquivos.conversas/listar, conversas/consultar, conversas/mensagens, mensagens/arquivo
Abrir atendimentosatendimentos_abrirColocar um número na fila de um departamento ou direto com um atendente.atendimentos/abrir
Gerenciar conversasconversas_gerirTransferir, encerrar, etiquetar e anotar conversas.conversas/transferir, conversas/encerrar, conversas/etiquetas, conversas/nota
ContatoscontatosListar, consultar e renomear contatos.contatos/listar, contatos/consultar, contatos/renomear
Ordens de serviço e agenda
Consultar ordens de serviçotickets_lerListar 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çotickets_gerirAbrir, mover de etapa, atribuir e comentar ordens de serviço.tickets/criar, tickets/mover, tickets/atribuir, tickets/comentar
Consultar agendaagenda_lerListar e consultar compromissos.agenda/tipos, agenda/listar, agenda/consultar
Gerenciar agendaagenda_gerirMarcar, concluir e cancelar compromissos.agenda/criar, agenda/concluir, agenda/cancelar
Gestão
IndicadoresrelatoriosVolumes, 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:

URL base
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:

cabeçalho
Authorization: Bearer cisp_7f3a9c21d84e0b56a1f2c3d4e5f60718293a4b5c6d7e8f90
ItemOnde vaiObrigatórioDescrição
Authorizationcabeçalho HTTPsimBearer, um espaço e a chave completa. A palavra Bearer aceita maiúsculas ou minúsculas.
rquery string (recomendado) ou corpo de formuláriosimA 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.

terminal
curl -s "https://atendimento.seuprovedor.com.br/api_publica.php?r=chave/info" \
  -H "Authorization: Bearer $CHATISP_CHAVE"
PHP
<?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;
Python
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"])
resposta (HTTP 200)
{
  "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:

  1. r ausente ou fora do formato recurso/acao: HTTP 404 rota.
  2. Cabeçalho Authorization: Bearer ... ausente ou malformado: HTTP 401 autenticacao.
  3. Chave inexistente, excluída, inativa ou fora do formato cisp_...: HTTP 401 chave_invalida.
  4. Plano sem API pública ou licença bloqueada: HTTP 403 plano.
  5. A chamada é contada no uso da chave. Se passou do limite por minuto: HTTP 429 cota_excedida.
  6. Corpo declarado como JSON, mas inválido: HTTP 400 json_invalido.
  7. Rota inexistente: HTTP 404 rota.
  8. Rota de escrita chamada sem POST: HTTP 405 metodo.
  9. Chave sem o escopo da rota: HTTP 403 permissao, com o escopo que faltou.
  10. 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 metodo com "esperado":"POST".

Onde vão os parâmetros

FormaCabeçalhoQuando usar
Query stringnenhumFiltros de leitura em GET: ?r=conversas/listar&abertas=1&limite=20.
Formulárioapplication/x-www-form-urlencodedO formato padrão do curl -d. Listas repetem o campo com colchetes: variaveis[]=Maria&variaveis[]=R$ 99,90.
JSONapplication/jsonO corpo inteiro é um objeto JSON. Recomendado para escrita. O r vai na URL.
Multipartmultipart/form-dataEnvio 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.

a mesma chamada em formulário e em JSON
# 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

TipoAceitaObservações
inteiro42 ou "42"Ids, pagina, limite. Texto que não é número inteiro: parametro_invalido com o campo.
booleanotrue/false, 1/0, sim/nao, yes/noVazio vale o padrão da rota.
listaarray 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.
dataISO 8601, AAAA-MM-DD ou AAAA-MM-DD HH:MM:SSVeja Datas e fuso horário.
textoUTF-8Espaç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çãoCorpo
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.

exemplos de erro
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.

HTTPQuando
200A operação foi executada.
400Parâmetro ausente ou inválido, conexão inadequada, JSON inválido.
401Sem chave, cabeçalho malformado ou chave inválida.
403Plano sem o recurso, licença bloqueada ou chave sem o escopo.
404Rota inexistente ou registro não encontrado.
405Rota de escrita chamada sem POST.
409Conflito com o estado atual: conexão desconectada, conversa já encerrada, janela de 24 horas fechada, quadro de ordens de serviço sem etapas.
410O arquivo da mensagem existiu, mas não está mais no servidor.
413Arquivo grande demais.
415Tipo de arquivo não suportado.
429Limite por minuto da chave estourado, com o cabeçalho Retry-After.
500Falha interna ao gravar um arquivo.
502O 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:

CampoValores
conversa estadofila (aguardando atendente), auto (num fluxo de atendimento), ia (com a IA), humano (com um atendente), encerrada.
mensagem direcaorecebida (do cliente) ou enviada (do provedor). Notas internas nunca aparecem na API.
mensagem autorcliente, atendente, ia ou sistema (fluxos, avisos automáticos, campanhas e envios feitos pela API).
mensagem tipotexto, imagem, audio, video, documento, localizacao, contato.
mensagem statuspendente, 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âmetroTipoPadrãoDescrição
paginainteiro1Página desejada, a partir de 1.
limiteinteiro50Itens por página, de 1 a 100. Fora da faixa: parametro_invalido com "maximo":100.

A resposta traz o bloco paginacao:

bloco de paginação
"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âmetroDescrição
sem cursorAs mensagens mais recentes, em ordem cronológica.
antes_deMensagens com id menor que o informado: para rolar o histórico para trás.
depois_deMensagens com id maior que o informado: para buscar o que chegou desde a última leitura.
limiteDe 1 a 100, padrão 50.
fim da resposta de conversas/mensagens
"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

FormatoExemploInterpretação
ISO 8601 com fuso2026-10-01T09:00:00-03:00, 2026-10-01T12:00:00ZConvertida para o fuso do servidor. Recomendado.
Data e hora sem fuso2026-10-01 09:00:00 ou 2026-10-01T09:00:00Entendida no fuso do servidor.
Só a data2026-10-01Iní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ê enviaComo o ChatISP entende
44999990000 ou (44) 99999-0000Número brasileiro: o código do país 55 é acrescentado. Vira 5544999990000.
4433330000Fixo brasileiro com DDD (10 dígitos). Vira 554433330000.
5544999990000Já com o 55: aceito como está.
+55 44 99999-0000Com + e 55: aceito como brasileiro.
+351 912 345 678Outro 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.

errorHTTPSignificado e o que fazer
Acesso
rota404r ausente, fora do formato recurso/acao ou rota inexistente. Confira a grafia e, com corpo JSON, lembre que r vai na URL.
autenticacao401Faltou o cabeçalho Authorization ou ele não está no formato Bearer <chave>.
chave_invalida401Chave inexistente, excluída ou inativa; ou copiada pela metade, com espaço ou quebra de linha.
plano403O 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_excedida429A chave passou do limite por minuto. Extra cota_minuto; espere os segundos do cabeçalho Retry-After.
permissao403A chave não tem o escopo da rota. O extra escopo diz qual ligar na chave.
metodo405Rota de escrita chamada sem POST. Extra esperado.
json_invalido400O corpo foi declarado application/json, mas não é um objeto JSON válido.
Parâmetros
parametro_obrigatorio400Faltou um parâmetro. O extra campo diz qual; quando há alternativas, vem separado por barra vertical ("modelo_id|modelo": informe um deles).
parametro_invalido400Valor em formato errado (inteiro, booleano, lista) ou fora do permitido. Extras campo e, conforme o caso, aceitos ou maximo.
identificador_obrigatorio400A rota precisa saber de qual registro se trata: informe o id (conversa_id, ticket_id...), o protocolo ou o numero, conforme a rota.
data_invalida400Data que não pôde ser lida. Extra campo.
periodo_invalido400Fim antes do início, ou período maior que o permitido (extra maximo_dias).
telefone_invalido400Telefone fora da regra. Veja Telefones.
texto_invalido400Texto vazio ou maior que o limite da rota (mensagem, nota, comentário). Extra campo quando não é o texto.
titulo_invalido400Título de OS ou compromisso vazio ou com mais de 160 caracteres.
nome_invalido400Nome de contato vazio ou com mais de 120 caracteres.
legenda_invalida400Legenda de arquivo com mais de 1024 caracteres.
link_invalido400Link de compromisso que não começa com http:// ou https://, tem espaço ou passa de 500 caracteres.
Registros
nao_encontrado404O registro pedido não existe: conversa, mensagem (ou mensagem sem arquivo), contato, OS ou compromisso.
conversa_invalida400A conversa_id informada para vincular uma OS não existe.
conversa_encerrada409Transferir ou encerrar exige conversa aberta.
departamento_invalido400Departamento inexistente ou inativo.
atendente_invalido400Atendente inexistente, inativo ou excluído.
motivo_invalido400Motivo de encerramento inexistente ou inativo.
etiqueta_invalida400Algum id de etiqueta não existe. Extra campo (etiquetas, adicionar ou remover).
etapa_invalida400Etapa de OS inexistente ou inativa.
sem_etapas409O 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_conexao400Nenhum conexao_id foi informado e não há conexão conectada (do tipo exigido pela rota).
conexao_id_obrigatorio400Há 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_invalida400A 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_desconectada409A conexão existe, mas não está conectada (no número gêmeo, nenhuma das duas está).
modelo_invalido400Modelo inexistente, de outra conexão ou não aprovado pela Meta.
modelo_com_midia400O modelo tem cabeçalho de mídia (imagem, vídeo, documento), que a API não envia.
variaveis_invalidas400variaveis não é lista, ou faltam valores. Extra esperadas com quantas o modelo pede.
janela_fechada409Na 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.
envio502O 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_invalido400Upload falhou, arquivo vazio ou arquivo_base64 que não é base64 válido.
arquivo_grande413 ou 400Arquivo 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_suportado415Tipo de arquivo que o WhatsApp não aceita (por exemplo, executáveis). Extra mimetype detectado pelo conteúdo.
arquivo_indisponivel410A mensagem tinha arquivo, mas ele não está mais no servidor (por exemplo, removido do disco).
arquivo500Falha 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çalhoConteúdo
X-RateLimit-LimitO limite por minuto da chave.
X-RateLimit-RemainingQuantas chamadas ainda cabem no minuto atual.
Retry-AfterSó na resposta 429: segundos até o próximo minuto.

Chave com limite 0 não recebe os cabeçalhos X-RateLimit-*.

resposta HTTP 429
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

ItemLimite
Itens por página1 a 100 (padrão 50).
Texto de mensagem4096 caracteres.
Legenda de arquivo1024 caracteres.
Arquivo enviado45 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 atendimento900 caracteres.
Título de OS ou compromisso160 caracteres.
Período de indicadores e agenda366 dias.
Chaves ativasConforme 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:

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 ok e o status HTTP em toda resposta; decida pelo código de error.
  • 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 com conversas/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

SintomaCausa provável e solução
HTTP 401 autenticacao com a chave certaO 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_invalidaChave excluída, inativa, ou copiada com espaço ou quebra de linha. Use Revelar e Copiar de novo.
HTTP 404 rota numa chamada com JSONO r foi colocado dentro do JSON. Mova para a URL.
HTTP 403 permissaoLigue na chave o escopo informado no campo escopo da resposta.
HTTP 403 planoPlano 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_obrigatorioHá 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_fechadaNú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 sistemaInstalaçã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)

  1. No Postman, use Import e escolha o arquivo. No Insomnia, use Import em uma coleção; o formato do Postman é reconhecido.
  2. Nas variáveis da coleção, preencha base_url com o endereço do seu painel (por exemplo https://atendimento.seuprovedor.com.br, sem barra no final) e chave com a sua chave cisp_....
  3. Rode primeiro Informações da chave (chave/info) para confirmar endereço, chave e escopos.
  4. 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.