API pública de ChatISP
Integre ChatISP con los sistemas de su proveedor de internet: ERP, CRM, portal del suscriptor, monitoreo (NOC) y BI. Son 37 operaciones que cubren mensajes, conversaciones, contactos, órdenes de servicio, agenda e indicadores, con claves de permisos granulares, respuestas JSON estandarizadas y avisos en tiempo real mediante webhooks firmados.
Visión general
La API pública es el canal de máquina de ChatISP: permite que otro sistema del proveedor trabaje con la atención sin abrir el panel. Funciona en las dos direcciones:
- De su sistema hacia ChatISP: llamadas HTTPS autenticadas por clave para enviar mensajes (texto, plantilla aprobada de la API oficial y archivo), listar y consultar conversaciones con su historial, transferir, cerrar, etiquetar y anotar atenciones, abrir atenciones en la cola, consultar y renombrar contactos, abrir y mover órdenes de servicio, agendar compromisos y leer los indicadores de la atención.
- De ChatISP hacia su sistema: webhooks de salida. ChatISP hace un POST firmado a la dirección que usted registre cuando un mensaje llega o sale, cuando una conversación se crea, cambia de responsable o se cierra, y cuando una orden de servicio se abre o se actualiza. Vea Webhooks de salida.
Las 37 operaciones
Toda la API usa una única dirección; la operación se elige con el parámetro r, en el formato recurso/acao (recurso/acción). La columna Alcance muestra el permiso que la clave necesita tener (vea Permisos de la clave); "cualquier clave" significa que basta con que la clave esté activa.
Ruta (r) | Método | Alcance | Qué hace |
|---|---|---|---|
| Catálogos: los ids que el resto de la API solicita | |||
chave/info | GET | cualquier clave | Nombre, alcances y límite de la clave; versión de la API, zona horaria y plan del servidor. |
conexoes/listar | GET | cualquier clave | Números de WhatsApp (QR y API oficial), estado y par gemelo. |
departamentos/listar | GET | cualquier clave | Departamentos, activos e inactivos, y cuál recibe las conversaciones nuevas. |
atendentes/listar | GET | cualquier clave | Agentes con perfil, departamentos, presencia y pausa. |
modelos/listar | GET | cualquier clave | Plantillas de mensaje de la API oficial y si pueden enviarse por la API. |
etiquetas/listar | GET | cualquier clave | Etiquetas de conversación, con color. |
motivos/listar | GET | cualquier clave | Motivos de cierre. |
| Mensajes | |||
mensagens/enviar | POST | mensagens_enviar | Envía un texto a un teléfono o a una conversación. |
mensagens/enviar_modelo | POST | mensagens_enviar | Envía una plantilla aprobada por Meta (fuera de la ventana de 24 horas). |
mensagens/enviar_arquivo | POST | mensagens_enviar | Envía imagen, video, audio o documento, con leyenda opcional. |
mensagens/arquivo | GET | conversas_ler | Descarga el archivo de un mensaje (respuesta binaria, fuera del JSON). |
| Conversaciones | |||
conversas/listar | GET | conversas_ler | Lista conversaciones con filtros y paginación. |
conversas/consultar | GET | conversas_ler | Una conversación (por id, protocolo o teléfono) con los últimos mensajes. |
conversas/mensagens | GET | conversas_ler | Historial de mensajes paginado por cursor. |
conversas/transferir | POST | conversas_gerir | Transfiere a un departamento o agente. |
conversas/encerrar | POST | conversas_gerir | Cierra la atención, con motivo opcional. |
conversas/etiquetas | POST | conversas_gerir | Define, agrega o quita etiquetas. |
conversas/nota | POST | conversas_gerir | Guarda una nota interna (el equipo la ve, el cliente no). |
| Contactos y atenciones | |||
atendimentos/abrir | POST | atendimentos_abrir | Pone un número en la cola de un departamento o directo con un agente, sin enviar nada al cliente. |
contatos/listar | GET | contatos | Contactos (uno por número), con búsqueda y paginación. |
contatos/consultar | GET | contatos | Un contacto con el historial de atenciones. |
contatos/renomear | POST | contatos | Guarda el nombre del contacto para las conversaciones actuales y futuras. |
| Órdenes de servicio | |||
tickets/etapas | GET | tickets_ler | Etapas del tablero de órdenes de servicio. |
tickets/tipos | GET | tickets_ler | Tipos de OS. |
tickets/listar | GET | tickets_ler | Lista las OS con filtros y paginación. |
tickets/consultar | GET | tickets_ler | Una OS con su línea de tiempo. |
tickets/criar | POST | tickets_gerir | Abre una OS. |
tickets/mover | POST | tickets_gerir | Mueve la OS de etapa. |
tickets/atribuir | POST | tickets_gerir | Define o quita el responsable. |
tickets/comentar | POST | tickets_gerir | Agrega un comentario. |
| Agenda | |||
agenda/tipos | GET | agenda_ler | Tipos de compromiso. |
agenda/listar | GET | agenda_ler | Compromisos de un período. |
agenda/consultar | GET | agenda_ler | Un compromiso. |
agenda/criar | POST | agenda_gerir | Agenda un compromiso. |
agenda/concluir | POST | agenda_gerir | Concluye un compromiso, con resultado opcional. |
agenda/cancelar | POST | agenda_gerir | Cancela un compromiso. |
| Indicadores | |||
relatorios/resumo | GET | relatorios | Volúmenes, tiempos en horario hábil, satisfacción y números por departamento y agente. |
En la columna Método, GET indica una lectura: también acepta POST. Las operaciones marcadas con POST modifican algo y solo aceptan POST.
Casos de uso típicos de un proveedor
| Sistema | Qué integrar | Rutas y eventos |
|---|---|---|
| ERP / facturación | Confirmación de pago, segunda vía de factura, aviso de bloqueo y desbloqueo, boleto en PDF. | mensagens/enviar, mensagens/enviar_modelo, mensagens/enviar_arquivo |
| NOC / monitoreo | Aviso de corte de fibra o mantenimiento a los suscriptores de la región, OS automática para el equipo de campo. | mensagens/enviar_modelo, tickets/criar, tickets/comentar |
| Portal del suscriptor y sitio web | Un "contáctenos" que llega a la cola del departamento correcto; agendamiento de visita técnica. | atendimentos/abrir, agenda/criar |
| CRM | Historial de atenciones por cliente, registro de cada conversación cerrada con protocolo, resumen y motivo. | contatos/consultar, conversas/mensagens, webhook conversa_encerrada |
| Sistema de órdenes de servicio | Reflejar las órdenes de servicio de ChatISP, mover etapas cuando avanza el trabajo en el ERP, asignar técnico. | tickets/*, webhooks ticket_criado y ticket_atualizado |
| BI / panel de gestión | Indicadores diarios, sincronización incremental de conversaciones. | relatorios/resumo, conversas/listar con atualizadas_desde |
| Automatización interna | Etiquetar y transferir conversaciones con reglas propias, anotar datos del ERP en la conversación. | conversas/etiquetas, conversas/transferir, conversas/nota, webhook mensagem_recebida |
Programas completos para varios de estos casos están en Ejemplos prácticos.
Requisitos
| Requisito | Detalle |
|---|---|
| Plan con API pública Recurso del plan | La API pública y los webhooks forman parte de los planes PREMIUM, GOLD y ENTERPRISE, y están habilitados durante la prueba gratuita. En planes sin el recurso, las tarjetas de claves y de webhooks de la pantalla Integraciones aparecen bloqueadas con el aviso del plan necesario, y cualquier llamada responde HTTP 403 con "error":"plano". |
| Cantidad de claves Límite por plan | Claves activas al mismo tiempo: hasta 3 en PREMIUM, hasta 10 en GOLD, sin límite en ENTERPRISE y en la prueba. El medidor junto al título de la tarjeta muestra el uso; al llegar al límite, el botón Nueva clave deja de aparecer. Las claves inactivas no cuentan. |
| Licencia al día | Con la licencia bloqueada (prueba vencida, falta de pago, licencia desactivada o sin comunicación con la central), la API rechaza las llamadas con HTTP 403 plano, incluso en un plan elegible. |
| Permiso en el panel | Crear, editar, revelar y eliminar claves y webhooks requiere el permiso Integraciones en el perfil de acceso del usuario (vea Agentes, perfiles y permisos). |
| Conexión de WhatsApp | Las rutas de envío y de apertura de atención necesitan una conexión conectada. Vea Conexiones de WhatsApp. |
| Red | Acceso HTTPS a la dirección de su ChatISP desde el servidor que llamará a la API. |
Instalación propia y ChatISP Cloud
La API es la misma en las dos formas de uso; solo cambia la dirección.
- Instalación propia (servidor del proveedor): la dirección es el dominio por el que usted accede al panel. Sin dominio configurado, el servidor responde con un certificado autofirmado y su sistema tendría que aceptarlo explícitamente. Configure un dominio con Let's Encrypt en Servidor antes de poner la integración en producción.
- ChatISP Cloud: la dirección es la de su panel alojado por Ravi Systems, ya con certificado válido.
En los dos casos, la dirección exacta aparece en la tarjeta API de ChatISP, en Dirección de la API.
Crear una clave de API
La clave es la única credencial de la API: no hay usuario, contraseña ni sesión. Cree una clave para cada integración, solo con los permisos que esta usa y un límite de llamadas por minuto.
Paso a paso
- En el menú lateral, abra Integraciones.
- Ubique la tarjeta API de ChatISP ("Claves para que otros sistemas usen la API: mensajes, conversaciones, contactos, órdenes de servicio, agenda e indicadores, cada clave con sus permisos."). Justo debajo del título aparece la Dirección de la API, con el botón Documentación de la API: anote la dirección, es la URL que la integración va a llamar.
- Haga clic en Nueva clave.
- Complete el Nombre (hasta 120 caracteres) con algo que identifique la integración, por ejemplo "ERP de facturación" o "NOC". Este nombre aparece en el historial de todo lo que haga la clave.
- Active los permisos que usa la integración. Están en tres grupos: Atención, Órdenes de servicio y agenda y Gestión. En una clave nueva, Enviar mensajes, Consultar conversaciones y Abrir atenciones vienen activados; los demás vienen desactivados. La tabla completa está en Permisos de la clave.
- Ajuste el Límite por minuto ("Llamadas aceptadas por minuto. 0 desactiva el límite."). El valor predeterminado es 60 y el máximo es 10000.
- Haga clic en Guardar. La ventana Clave creada muestra la clave completa en el campo Clave de API. Haga clic en Copiar y guárdela en el sistema que usará la API.
cisp_7f3a9c21d84e0b56a1f2c3d4e5f60718293a4b5c6d7e8f90
Toda clave comienza con cisp_, seguido de 48 caracteres hexadecimales. La lista de la tarjeta muestra solo el comienzo (por ejemplo cisp_7f3a9…) para que usted reconozca cuál es cuál.
La lista de claves
| Columna | Qué muestra |
|---|---|
| Nombre | El nombre dado a la clave. |
| Clave de API | El comienzo de la clave, para reconocerla. |
| Permisos | Una etiqueta por cada permiso activado. |
| Usos | Total de llamadas autenticadas con la clave. Al pasar el mouse aparece el Último uso. |
| Situación | Activa o Inactiva. |
| Acciones | Editar, Revelar y Eliminar. |
Revelar, editar y eliminar
- Revelar muestra de nuevo la clave completa, con el botón Copiar, en cualquier momento, para quien tiene el permiso Integraciones.
- Editar cambia nombre, permisos, límite por minuto y el interruptor Activa. La clave en sí no cambia: la integración sigue funcionando con el mismo valor, ya con los permisos nuevos. Desactivar Activa suspende la clave de inmediato (HTTP 401
chave_invalida) sin borrarla, y deja de contar en el límite del plan. - Eliminar pide confirmación ("¿Eliminar esta clave? Las integraciones que la usan dejarán de funcionar.") y revoca la clave de inmediato.
Como las claves pueden revelarse en el panel, quien tiene el permiso Integraciones tiene acceso a todas ellas. Conceda este permiso solo a quien administra las integraciones.
Permisos de la clave (alcances)
Cada permiso de la pantalla corresponde a un alcance (scope), un código estable que la API usa para decidir qué puede hacer la clave. El código aparece en el campo escopos de chave/info y en el error permissao, que informa qué alcance faltó.
| Nombre en la pantalla | Alcance | Qué habilita | Rutas |
|---|---|---|---|
| Atención | |||
| Enviar mensajes | mensagens_enviar | Texto, plantillas aprobadas de la API oficial y archivos. | mensagens/enviar, mensagens/enviar_modelo, mensagens/enviar_arquivo |
| Consultar conversaciones | conversas_ler | Listar y consultar conversaciones, leer el historial de mensajes y descargar los archivos. | conversas/listar, conversas/consultar, conversas/mensagens, mensagens/arquivo |
| Abrir atenciones | atendimentos_abrir | Poner un número en la cola de un departamento o directo con un agente. | atendimentos/abrir |
| Gestionar conversaciones | conversas_gerir | Transferir, cerrar, etiquetar y anotar conversaciones. | conversas/transferir, conversas/encerrar, conversas/etiquetas, conversas/nota |
| Contactos | contatos | Listar, consultar y renombrar contactos. | contatos/listar, contatos/consultar, contatos/renomear |
| Órdenes de servicio y agenda | |||
| Consultar órdenes de servicio | tickets_ler | Listar las OS, ver la línea de tiempo, las etapas y los tipos. | tickets/etapas, tickets/tipos, tickets/listar, tickets/consultar |
| Gestionar órdenes de servicio | tickets_gerir | Abrir, mover de etapa, asignar y comentar OS. | tickets/criar, tickets/mover, tickets/atribuir, tickets/comentar |
| Consultar agenda | agenda_ler | Listar y consultar compromisos. | agenda/tipos, agenda/listar, agenda/consultar |
| Gestionar agenda | agenda_gerir | Agendar, concluir y cancelar compromisos. | agenda/criar, agenda/concluir, agenda/cancelar |
| Gestión | |||
| Indicadores | relatorios | Volúmenes, tiempos en horario hábil, satisfacción y números por departamento y agente. | relatorios/resumo |
Los alcances son independientes: Gestionar órdenes de servicio no incluye Consultar órdenes de servicio, por ejemplo. Una integración que abre órdenes de servicio y después sigue su avance necesita los dos.
Catálogos: habilitados para cualquier clave
Las rutas de catálogo (chave/info, conexoes/listar, departamentos/listar, atendentes/listar, modelos/listar, etiquetas/listar y motivos/listar) no requieren alcance: cualquier clave activa puede llamarlas, incluso con todos los permisos desactivados. Devuelven los ids que piden las demás rutas (conexao_id, departamento_id, atendente_id, modelo_id, etiqueta_id, motivo_id); sin ellos ninguna integración podría armar sus llamadas. La pantalla lo recuerda justo debajo de los permisos: "Conexiones, departamentos, agentes, plantillas, etiquetas y motivos están disponibles para cualquier clave activa." Referencia en Catálogos.
Cuántas claves crear
- Una por integración, con un nombre claro: así usted limita, suspende o revoca un sistema sin afectar a los demás, y el historial de las conversaciones muestra qué sistema realizó cada acción.
- Separe lectura de escritura cuando sistemas distintos hacen cada cosa. Un panel de BI solo necesita Consultar conversaciones e Indicadores; el ERP que envía boletos solo necesita Enviar mensajes.
Dirección y autenticación
Todas las llamadas van a la misma dirección, que se muestra en la tarjeta API de ChatISP:
https://<dirección de su panel>/api_publica.php?r=<recurso>/<acao>
La clave va en el encabezado HTTP Authorization, con el esquema Bearer. Nunca va en la URL ni en el cuerpo:
Authorization: Bearer cisp_7f3a9c21d84e0b56a1f2c3d4e5f60718293a4b5c6d7e8f90
| Elemento | Dónde va | Obligatorio | Descripción |
|---|---|---|---|
Authorization | encabezado HTTP | sí | Bearer, un espacio y la clave completa. La palabra Bearer acepta mayúsculas o minúsculas. |
r | query string (recomendado) o cuerpo de formulario | sí | La ruta, en el formato recurso/acao (letras minúsculas y guion bajo). Con cuerpo JSON, r debe estar en la URL: no se lee desde dentro del JSON. |
No hay inicio de sesión ni sesión: cada llamada es independiente.
Primera llamada
La ruta chave/info es la ideal para validar dirección y clave: no requiere permiso, no modifica nada y muestra lo que la clave puede hacer.
curl -s "https://atendimento.seuprovedor.com.br/api_publica.php?r=chave/info" \ -H "Authorization: Bearer $CHATISP_CHAVE"
<?php // Cliente mínimo reutilizable en las demás rutas 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("Error {$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"Error {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"
}
}Orden de validación
Toda llamada pasa por estas verificaciones, en este orden. La primera que falle define la respuesta:
rausente o fuera del formatorecurso/acao: HTTP 404rota.- Encabezado
Authorization: Bearer ...ausente o mal formado: HTTP 401autenticacao. - Clave inexistente, eliminada, inactiva o fuera del formato
cisp_...: HTTP 401chave_invalida. - Plan sin API pública o licencia bloqueada: HTTP 403
plano. - La llamada se cuenta en el uso de la clave. Si superó el límite por minuto: HTTP 429
cota_excedida. - Cuerpo declarado como JSON, pero inválido: HTTP 400
json_invalido. - Ruta inexistente: HTTP 404
rota. - Ruta de escritura llamada sin POST: HTTP 405
metodo. - Clave sin el alcance de la ruta: HTTP 403
permissao, con el alcance que faltó. - La operación valida sus propios parámetros y se ejecuta.
A partir del paso 5, toda llamada cuenta en el uso de la clave (columna Usos y límite por minuto), aunque termine en error de ruta, permiso o parámetro. Las llamadas con clave inválida no cuentan.
Llame a la API siempre desde su servidor (backend). Nunca coloque la clave en una página web, en una aplicación instalada en el celular ni en un script que se ejecute en el navegador: cualquier persona podría copiarla y actuar en nombre del proveedor.
Formato de la solicitud
Métodos
- Lectura (listar, consultar, catálogos, indicadores, descargar archivo): GET o POST.
- Escritura (enviar, transferir, cerrar, crear, mover...): solo POST. Con otro método, la respuesta es HTTP 405
metodocon"esperado":"POST".
Dónde van los parámetros
| Forma | Encabezado | Cuándo usarla |
|---|---|---|
| Query string | ninguno | Filtros de lectura en GET: ?r=conversas/listar&abertas=1&limite=20. |
| Formulario | application/x-www-form-urlencoded | El formato predeterminado de curl -d. Las listas repiten el campo con corchetes: variaveis[]=Maria&variaveis[]=R$ 99,90. |
| JSON | application/json | Todo el cuerpo es un objeto JSON. Recomendado para escritura. r va en la URL. |
| Multipart | multipart/form-data | Envío de archivo en mensagens/enviar_arquivo (campo arquivo). Alternativa en JSON: arquivo_base64. |
La query string vale con cualquier método. Cuando el mismo parámetro viene en la query y en el cuerpo, prevalece el cuerpo. Un cuerpo con Content-Type: application/json que no sea un objeto JSON válido se rechaza con HTTP 400 json_invalido.
# formulario 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=¡Hola! Su técnico está en camino." # 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":"¡Hola! Su técnico está en camino."}'
Tipos de parámetro
| Tipo | Acepta | Observaciones |
|---|---|---|
| entero | 42 o "42" | Ids, pagina, limite. Texto que no es un número entero: parametro_invalido con el campo. |
| booleano | true/false, 1/0, sim/nao, yes/no | Vacío equivale al valor predeterminado de la ruta. |
| lista | array JSON, campo[]=a&campo[]=b o texto separado por comas (3,7,9) | Etiquetas, estados. Una lista vacía ([] o "") es distinta de no enviar el campo. |
| fecha | ISO 8601, AAAA-MM-DD o AAAA-MM-DD HH:MM:SS | Vea Fechas y zona horaria. |
| texto | UTF-8 | Se quitan los espacios de los extremos. Cada ruta informa el tamaño máximo. |
Formato de la respuesta
Toda respuesta es JSON (Content-Type: application/json; charset=utf-8, Cache-Control: no-store) con un sobre igual en todas las rutas:
| Situación | Cuerpo |
|---|---|
| Éxito | {"ok": true, ...campos de la operación} |
| Error | {"ok": false, "error": "codigo", ...campos extra} |
El campo error es siempre un código estable, sin tildes y sin traducción, pensado para que su sistema decida qué hacer. Los campos extra ayudan a corregir la llamada: campo (qué parámetro), aceitos (valores permitidos), maximo, esperado, escopo, entre otros. Los caracteres acentuados vienen sin escape ("Suporte técnico"), al igual que las barras.
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"}Estado HTTP
El estado HTTP es real y coherente con el resultado: verifique el estado y el campo ok.
| HTTP | Cuándo |
|---|---|
| 200 | La operación se ejecutó. |
| 400 | Parámetro ausente o inválido, conexión inadecuada, JSON inválido. |
| 401 | Sin clave, encabezado mal formado o clave inválida. |
| 403 | Plan sin el recurso, licencia bloqueada o clave sin el alcance. |
| 404 | Ruta inexistente o registro no encontrado. |
| 405 | Ruta de escritura llamada sin POST. |
| 409 | Conflicto con el estado actual: conexión desconectada, conversación ya cerrada, ventana de 24 horas cerrada, tablero de órdenes de servicio sin etapas. |
| 410 | El archivo del mensaje existió, pero ya no está en el servidor. |
| 413 | Archivo demasiado grande. |
| 415 | Tipo de archivo no soportado. |
| 429 | Se superó el límite por minuto de la clave, con el encabezado Retry-After. |
| 500 | Falla interna al guardar un archivo. |
| 502 | WhatsApp no aceptó el mensaje (error envio). El intento queda registrado en la conversación. |
Respuestas que no son JSON
Solo mensagens/arquivo: en caso de éxito devuelve el propio archivo, con el Content-Type del archivo (imágenes y PDF) o application/octet-stream (demás tipos) y Content-Disposition con el nombre original. En caso de error, devuelve el sobre JSON normal.
Objetos que se repiten
Las rutas de mensajes, conversaciones y contactos devuelven la conversación y el mensaje siempre con los mismos campos (los detalles están en Conversaciones y Mensajes). Valores que encontrará:
| Campo | Valores |
|---|---|
conversación estado | fila (esperando agente), auto (en un flujo de atención), ia (con la IA), humano (con un agente), encerrada (cerrada). |
mensaje direcao | recebida (del cliente) o enviada (del proveedor). Las notas internas nunca aparecen en la API. |
mensaje autor | cliente, atendente, ia o sistema (flujos, avisos automáticos, campañas y envíos hechos por la API). |
mensaje tipo | texto, imagem, audio, video, documento, localizacao, contato. |
mensaje status | pendente, enviada, entregue, lida, erro. |
Paginación y cursor
Paginación numerada
Los listados grandes (conversas/listar, contatos/listar, tickets/listar y agenda/listar) usan página y límite:
| Parámetro | Tipo | Predeterminado | Descripción |
|---|---|---|---|
pagina | entero | 1 | Página deseada, a partir de 1. |
limite | entero | 50 | Elementos por página, de 1 a 100. Fuera del rango: parametro_invalido con "maximo":100. |
La respuesta trae el bloque paginacao:
"paginacao": {
"pagina": 2,
"limite": 50,
"total": 137,
"paginas": 3
}total es la cantidad de registros que cumplen los filtros y paginas es cuántas páginas existen con ese límite (0 cuando no hay registros). Para recorrer todo, llame hasta que pagina llegue a paginas. Una página posterior a la última devuelve la lista vacía, sin error.
Para sincronizar una base grande, prefiera filtros de fecha incrementales (atualizadas_desde en conversaciones, atualizados_desde en contactos) en lugar de recorrer todas las páginas en cada ejecución. Los registros nuevos que entran mientras usted pagina pueden desplazar elementos entre páginas.
Cursor del historial de mensajes
El historial de una conversación (conversas/mensagens) usa un cursor por el id del mensaje, que no se desplaza cuando llegan mensajes nuevos:
| Parámetro | Descripción |
|---|---|
| sin cursor | Los mensajes más recientes, en orden cronológico. |
antes_de | Mensajes con id menor que el informado: para recorrer el historial hacia atrás. |
depois_de | Mensajes con id mayor que el informado: para buscar lo que llegó desde la última lectura. |
limite | De 1 a 100, predeterminado 50. |
"tem_mais": true,
"cursor": {
"antes_de": 402801,
"depois_de": 402850
}tem_mais indica si todavía hay mensajes en la dirección solicitada. Para seguir retrocediendo, pase cursor.antes_de en el próximo antes_de; para seguir los nuevos, guarde cursor.depois_de y úselo como depois_de en la próxima consulta. Los mensajes vienen siempre en orden cronológico (del más antiguo al más nuevo).
Fechas y zona horaria
Fechas en la respuesta
Todas las fechas de salida vienen en ISO 8601 con la zona horaria del servidor, por ejemplo 2026-10-01T09:12:40-03:00. Las fechas ausentes vienen como null. La zona horaria del servidor aparece en chave/info (servidor.fuso_horario), junto con su reloj (servidor.agora), útil para verificar la diferencia horaria con su sistema.
Fechas en la solicitud
| Formato | Ejemplo | Interpretación |
|---|---|---|
| ISO 8601 con zona horaria | 2026-10-01T09:00:00-03:00, 2026-10-01T12:00:00Z | Convertida a la zona horaria del servidor. Recomendado. |
| Fecha y hora sin zona horaria | 2026-10-01 09:00:00 o 2026-10-01T09:00:00 | Se interpreta en la zona horaria del servidor. |
| Solo la fecha | 2026-10-01 | Inicio del día (00:00:00) en los filtros "desde" y "de"; fin del día (23:59:59) en los filtros "hasta". |
Años fuera de 2000 a 2100 o texto que no es una fecha responden HTTP 400 data_invalida con el campo. Los períodos con fin anterior al inicio, o mayores que lo permitido por la ruta (366 días en indicadores y agenda), responden periodo_invalido.
Teléfonos
El teléfono sigue la misma regla de la pantalla del panel. Se ignoran la puntuación, los espacios y los paréntesis.
| Cómo lo envía usted | Cómo lo interpreta ChatISP |
|---|---|
44999990000 o (44) 99999-0000 | Número brasileño: se agrega el código de país 55. Queda 5544999990000. |
4433330000 | Fijo brasileño con código de área (10 dígitos). Queda 554433330000. |
5544999990000 | Ya con el 55: se acepta tal cual. |
+55 44 99999-0000 | Con + y 55: se acepta como brasileño. |
+351 912 345 678 | Otro país: es obligatorio comenzar con +. Se acepta con 8 a 15 dígitos. |
Reglas de los números brasileños: código de área de 11 a 99 (sin cero) y, cuando el número tiene 11 dígitos, el tercero debe ser el 9 del celular. Fuera de eso, la respuesta es HTTP 400 telefone_invalido. Sin el +, un número que no encaja como brasileño también se rechaza, para no enviar el mensaje al país equivocado.
En las consultas por teléfono (conversaciones, contactos), ChatISP busca el número con y sin el noveno dígito, porque el WhatsApp de algunos celulares antiguos todavía usa el formato de 8 dígitos. En las respuestas, el teléfono viene solo con dígitos y con el código de país, en el formato en que la conversación está registrada.
Códigos de error
Lista completa de los valores posibles de error. Cada página de la referencia muestra qué errores puede devolver cada ruta.
error | HTTP | Significado y qué hacer |
|---|---|---|
| Acceso | ||
rota | 404 | r ausente, fuera del formato recurso/acao o ruta inexistente. Verifique la escritura y, con cuerpo JSON, recuerde que r va en la URL. |
autenticacao | 401 | Falta el encabezado Authorization o no está en el formato Bearer <clave>. |
chave_invalida | 401 | Clave inexistente, eliminada o inactiva; o copiada a medias, con un espacio o un salto de línea. |
plano | 403 | El plan no incluye la API pública o la licencia está bloqueada. El extra plano trae el nombre del plan vigente. |
cota_excedida | 429 | La clave superó el límite por minuto. Extra cota_minuto; espere los segundos del encabezado Retry-After. |
permissao | 403 | La clave no tiene el alcance de la ruta. El extra escopo indica cuál activar en la clave. |
metodo | 405 | Ruta de escritura llamada sin POST. Extra esperado. |
json_invalido | 400 | El cuerpo se declaró como application/json, pero no es un objeto JSON válido. |
| Parámetros | ||
parametro_obrigatorio | 400 | Falta un parámetro. El extra campo indica cuál; cuando hay alternativas, vienen separadas por una barra vertical ("modelo_id|modelo": informe uno de ellos). |
parametro_invalido | 400 | Valor en formato incorrecto (entero, booleano, lista) o fuera de lo permitido. Extras campo y, según el caso, aceitos o maximo. |
identificador_obrigatorio | 400 | La ruta necesita saber de qué registro se trata: informe el id (conversa_id, ticket_id...), el protocolo o el numero, según la ruta. |
data_invalida | 400 | Fecha que no se pudo leer. Extra campo. |
periodo_invalido | 400 | Fin anterior al inicio, o período mayor que el permitido (extra maximo_dias). |
telefone_invalido | 400 | Teléfono fuera de la regla. Vea Teléfonos. |
texto_invalido | 400 | Texto vacío o mayor que el límite de la ruta (mensaje, nota, comentario). Extra campo cuando no es texto. |
titulo_invalido | 400 | Título de OS o compromiso vacío o con más de 160 caracteres. |
nome_invalido | 400 | Nombre de contacto vacío o con más de 120 caracteres. |
legenda_invalida | 400 | Leyenda de archivo con más de 1024 caracteres. |
link_invalido | 400 | Enlace de compromiso que no comienza con http:// o https://, tiene espacios o supera los 500 caracteres. |
| Registros | ||
nao_encontrado | 404 | El registro solicitado no existe: conversación, mensaje (o mensaje sin archivo), contacto, orden de servicio o compromiso. |
conversa_invalida | 400 | La conversa_id informada para vincular una OS no existe. |
conversa_encerrada | 409 | Transferir o cerrar requiere una conversación abierta. |
departamento_invalido | 400 | Departamento inexistente o inactivo. |
atendente_invalido | 400 | Agente inexistente, inactivo o eliminado. |
motivo_invalido | 400 | Motivo de cierre inexistente o inactivo. |
etiqueta_invalida | 400 | Algún id de etiqueta no existe. Extra campo (etiquetas, adicionar o remover). |
etapa_invalida | 400 | Etapa de OS inexistente o inactiva. |
sem_etapas | 409 | El tablero de órdenes de servicio no tiene una etapa activa para recibir la OS nueva. Configure las etapas en el panel. |
| Conexión y envío | ||
sem_conexao | 400 | No se informó ningún conexao_id y no hay conexión conectada (del tipo que exige la ruta). |
conexao_id_obrigatorio | 400 | Hay más de un número conectado y la clave no tiene Número de origen: informe conexao_id (vea Conexiones) o defina el Número de origen en la clave de API (Integraciones, Claves de API). |
conexao_invalida | 400 | La conexión no existe o no es del tipo exigido (por ejemplo, plantilla en un número sin API oficial). Extra tipo_esperado cuando es una cuestión de tipo. |
conexao_desconectada | 409 | La conexión existe, pero no está conectada (en el número gemelo, ninguna de las dos lo está). |
modelo_invalido | 400 | Plantilla inexistente, de otra conexión o no aprobada por Meta. |
modelo_com_midia | 400 | La plantilla tiene un encabezado multimedia (imagen, video, documento), que la API no envía. |
variaveis_invalidas | 400 | variaveis no es una lista, o faltan valores. Extra esperadas con cuántas pide la plantilla. |
janela_fechada | 409 | En la API oficial, el texto libre solo se envía hasta 24 horas después del último mensaje del cliente. Use una plantilla aprobada. El intento queda registrado; extras conversa_id, protocolo, mensagem_id y mensagem. |
envio | 502 | WhatsApp no aceptó el mensaje. Extra detalhe con el motivo del canal, además de conversa_id, protocolo, mensagem_id y mensagem (el intento queda en la conversación, marcado con error). |
| Archivos | ||
arquivo_invalido | 400 | Falló la carga, archivo vacío o arquivo_base64 que no es base64 válido. |
arquivo_grande | 413 o 400 | Archivo de más de 45 MB (413, extra maximo_bytes). Cuando el propio servidor web rechaza la carga por el tamaño, la respuesta es 400 con el mismo código. |
tipo_nao_suportado | 415 | Tipo de archivo que WhatsApp no acepta (por ejemplo, ejecutables). Extra mimetype detectado por el contenido. |
arquivo_indisponivel | 410 | El mensaje tenía archivo, pero ya no está en el servidor (por ejemplo, se eliminó del disco). |
arquivo | 500 | Falla al guardar el archivo en el servidor. Repita más tarde; si persiste, comuníquese con soporte. |
Trate los errores por el código, nunca por el texto de detalhe (que viene del canal y puede cambiar). Ignore los campos extra que su sistema no conoce: pueden aparecer extras nuevos para ayudar en el diagnóstico.
Límites
Límite por minuto de la clave
Cada clave tiene su Límite por minuto (predeterminado 60, máximo 10000, 0 sin límite). El conteo es por minuto del reloj del servidor: se reinicia cuando cambia el minuto (a las 10:41:00, a las 10:42:00...), no en una ventana móvil de 60 segundos.
Con un límite definido, toda respuesta trae los encabezados:
| Encabezado | Contenido |
|---|---|
X-RateLimit-Limit | El límite por minuto de la clave. |
X-RateLimit-Remaining | Cuántas llamadas caben todavía en el minuto actual. |
Retry-After | Solo en la respuesta 429: segundos hasta el próximo minuto. |
Una clave con límite 0 no recibe los encabezados 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}La llamada rechazada no se ejecutó: espere el Retry-After y repita. Los rechazos también cuentan en el minuto, así que repetir en bucle sin esperar no sirve.
Tamaños y cantidades
| Elemento | Límite |
|---|---|
| Elementos por página | 1 a 100 (predeterminado 50). |
| Texto de mensaje | 4096 caracteres. |
| Leyenda de archivo | 1024 caracteres. |
| Archivo enviado | 45 MB. El servidor web de la instalación puede imponer un límite menor para la carga multipart; en ese caso use arquivo_base64 o reduzca el archivo. |
| Nota interna y nota de apertura de atención | 900 caracteres. |
| Título de OS o compromiso | 160 caracteres. |
| Período de indicadores y agenda | 366 días. |
| Claves activas | Según el plan: 3 (PREMIUM), 10 (GOLD), sin límite (ENTERPRISE y prueba). |
Ritmo de envío masivo
La API envía cada mensaje en el momento en que se llama. Para avisos a muchos suscriptores, distribuya los envíos en el tiempo en lugar de disparar cientos de llamadas simultáneas, y ajuste el límite por minuto de la clave a ese ritmo. Para listas grandes con seguimiento de entregas y respuestas, la pantalla Automatización de envíos ya controla el ritmo por sí sola.
Versión de la API
Toda respuesta, incluso las de error, trae el encabezado:
X-ChatISP-Api-Versao: 1
El mismo valor aparece en chave/info, en el campo servidor.api_versao. La versión actual es la 1. Registre el valor en los logs de la integración: ayuda a soporte a identificar con qué versión habló su sistema.
Las rutas, los nombres de campo y los códigos de error documentados aquí son estables. La API puede ganar rutas, parámetros opcionales y campos nuevos en las respuestas sin cambiar de versión; por eso su sistema debe ignorar los campos desconocidos en lugar de rechazar la respuesta. Los campos antiguos se mantienen para quien ya integró: por ejemplo, atendimentos/abrir sigue devolviendo conversa_id, protocolo, estado y ja_existia en el nivel superior, además del objeto conversa completo.
Seguridad y buenas prácticas
Lista de verificación
- Una clave por integración, con un Nombre claro y solo los alcances necesarios.
- Guarde la clave en una variable de entorno o en el almacén de secretos del servidor, nunca en el código versionado ni en logs.
- Use siempre HTTPS. En una instalación propia, configure un dominio con certificado válido antes de producción.
- Un límite por minuto compatible con el uso real: también protege contra un bucle descontrolado en su sistema.
- Verifique
oky el estado HTTP en toda respuesta; decida según el código deerror. - Ante un 429, respete el
Retry-After. Ante un error de red o HTTP 5xx, repita las lecturas con espera creciente. No repita envíos a ciegas: un mensaje que dio timeout puede haberse entregado, y repetir duplica el envío al cliente. Antes, verifique el historial conconversas/mensagens. - Guarde los ids devueltos (
conversa_id,mensagem_id,ticket_id) para cruzarlos con los webhooks. - Guarde en caché los catálogos (departamentos, agentes, etiquetas, motivos) y actualícelos de vez en cuando, en lugar de consultarlos en cada llamada.
- Prefiera los webhooks a consultar en bucle para saber qué cambió.
- Desactive o elimine las claves de integraciones apagadas. Para cambiar una clave, cree la nueva, actualice la integración y solo entonces elimine la antigua.
Qué queda registrado
Las acciones hechas por la API aparecen en el panel con el nombre de la clave: el evento "API" en la línea de tiempo de la conversación, las notas como "API (nombre de la clave): ...", las transferencias y cierres con "API: nombre de la clave", y los comentarios de OS con "[API: nombre de la clave]". Los mensajes enviados por la API salen con autor sistema, sin firma de agente.
Problemas frecuentes
| Síntoma | Causa probable y solución |
|---|---|
HTTP 401 autenticacao con la clave correcta | El encabezado no llegó como Authorization: Bearer cisp_.... Algunos proxies y bibliotecas descartan el encabezado en las redirecciones: llame directamente a la dirección https://. |
HTTP 401 chave_invalida | Clave eliminada, inactiva, o copiada con un espacio o salto de línea. Use Revelar y Copiar de nuevo. |
HTTP 404 rota en una llamada con JSON | r se colocó dentro del JSON. Muévalo a la URL. |
HTTP 403 permissao | Active en la clave el alcance informado en el campo escopo de la respuesta. |
HTTP 403 plano | Plan sin la API pública o licencia bloqueada. Verifique la situación de la licencia en Cuenta y licencia. |
HTTP 400 conexao_id_obrigatorio | Hay más de un número conectado y la clave no tiene Número de origen. Lístelos con conexoes/listar e informe conexao_id, o defina el Número de origen en la clave de API (Integraciones, Claves de API). |
HTTP 409 janela_fechada | Número de la API oficial sin mensaje del cliente en las últimas 24 horas. Envíe una plantilla aprobada con mensagens/enviar_modelo. |
| Error de certificado en su sistema | Una instalación propia sin dominio responde con un certificado autofirmado. Configure un dominio con Let's Encrypt en Servidor. |
Colección para Postman e Insomnia
Para probar la API sin escribir código, descargue la colección lista con las 37 rutas, ya con el método, parámetros de ejemplo y la descripción de cada una:
Descargar la colección (chatisp-api.postman_collection.json)
- En Postman, use Import y elija el archivo. En Insomnia, use Import en una colección; el formato de Postman se reconoce.
- En las variables de la colección, complete
base_urlcon la dirección de su panel (por ejemplohttps://atendimento.seuprovedor.com.br, sin barra al final) ychavecon su clavecisp_.... - Ejecute primero Informações da chave (información de la clave,
chave/info) para confirmar dirección, clave y alcances. - Use los catálogos para descubrir los ids reales de su instalación antes de probar las rutas de escritura.
Las rutas de escritura de la colección actúan de verdad: envían mensajes a clientes, cierran conversaciones, abren órdenes de servicio. Pruebe con su propio teléfono y con una clave de prueba que tenga solo los alcances necesarios.