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étodoAlcanceQué hace
Catálogos: los ids que el resto de la API solicita
chave/infoGETcualquier claveNombre, alcances y límite de la clave; versión de la API, zona horaria y plan del servidor.
conexoes/listarGETcualquier claveNúmeros de WhatsApp (QR y API oficial), estado y par gemelo.
departamentos/listarGETcualquier claveDepartamentos, activos e inactivos, y cuál recibe las conversaciones nuevas.
atendentes/listarGETcualquier claveAgentes con perfil, departamentos, presencia y pausa.
modelos/listarGETcualquier clavePlantillas de mensaje de la API oficial y si pueden enviarse por la API.
etiquetas/listarGETcualquier claveEtiquetas de conversación, con color.
motivos/listarGETcualquier claveMotivos de cierre.
Mensajes
mensagens/enviarPOSTmensagens_enviarEnvía un texto a un teléfono o a una conversación.
mensagens/enviar_modeloPOSTmensagens_enviarEnvía una plantilla aprobada por Meta (fuera de la ventana de 24 horas).
mensagens/enviar_arquivoPOSTmensagens_enviarEnvía imagen, video, audio o documento, con leyenda opcional.
mensagens/arquivoGETconversas_lerDescarga el archivo de un mensaje (respuesta binaria, fuera del JSON).
Conversaciones
conversas/listarGETconversas_lerLista conversaciones con filtros y paginación.
conversas/consultarGETconversas_lerUna conversación (por id, protocolo o teléfono) con los últimos mensajes.
conversas/mensagensGETconversas_lerHistorial de mensajes paginado por cursor.
conversas/transferirPOSTconversas_gerirTransfiere a un departamento o agente.
conversas/encerrarPOSTconversas_gerirCierra la atención, con motivo opcional.
conversas/etiquetasPOSTconversas_gerirDefine, agrega o quita etiquetas.
conversas/notaPOSTconversas_gerirGuarda una nota interna (el equipo la ve, el cliente no).
Contactos y atenciones
atendimentos/abrirPOSTatendimentos_abrirPone un número en la cola de un departamento o directo con un agente, sin enviar nada al cliente.
contatos/listarGETcontatosContactos (uno por número), con búsqueda y paginación.
contatos/consultarGETcontatosUn contacto con el historial de atenciones.
contatos/renomearPOSTcontatosGuarda el nombre del contacto para las conversaciones actuales y futuras.
Órdenes de servicio
tickets/etapasGETtickets_lerEtapas del tablero de órdenes de servicio.
tickets/tiposGETtickets_lerTipos de OS.
tickets/listarGETtickets_lerLista las OS con filtros y paginación.
tickets/consultarGETtickets_lerUna OS con su línea de tiempo.
tickets/criarPOSTtickets_gerirAbre una OS.
tickets/moverPOSTtickets_gerirMueve la OS de etapa.
tickets/atribuirPOSTtickets_gerirDefine o quita el responsable.
tickets/comentarPOSTtickets_gerirAgrega un comentario.
Agenda
agenda/tiposGETagenda_lerTipos de compromiso.
agenda/listarGETagenda_lerCompromisos de un período.
agenda/consultarGETagenda_lerUn compromiso.
agenda/criarPOSTagenda_gerirAgenda un compromiso.
agenda/concluirPOSTagenda_gerirConcluye un compromiso, con resultado opcional.
agenda/cancelarPOSTagenda_gerirCancela un compromiso.
Indicadores
relatorios/resumoGETrelatoriosVolú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

SistemaQué integrarRutas y eventos
ERP / facturaciónConfirmació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 / monitoreoAviso 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 webUn "contáctenos" que llega a la cola del departamento correcto; agendamiento de visita técnica.atendimentos/abrir, agenda/criar
CRMHistorial 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 servicioReflejar 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ónIndicadores diarios, sincronización incremental de conversaciones.relatorios/resumo, conversas/listar con atualizadas_desde
Automatización internaEtiquetar 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

RequisitoDetalle
Plan con API pública Recurso del planLa 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 planClaves 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íaCon 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 panelCrear, 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 WhatsAppLas rutas de envío y de apertura de atención necesitan una conexión conectada. Vea Conexiones de WhatsApp.
RedAcceso 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

  1. En el menú lateral, abra Integraciones.
  2. 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.
  3. Haga clic en Nueva clave.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
formato de la clave
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

ColumnaQué muestra
NombreEl nombre dado a la clave.
Clave de APIEl comienzo de la clave, para reconocerla.
PermisosUna etiqueta por cada permiso activado.
UsosTotal de llamadas autenticadas con la clave. Al pasar el mouse aparece el Último uso.
SituaciónActiva o Inactiva.
AccionesEditar, 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 pantallaAlcanceQué habilitaRutas
Atención
Enviar mensajesmensagens_enviarTexto, plantillas aprobadas de la API oficial y archivos.mensagens/enviar, mensagens/enviar_modelo, mensagens/enviar_arquivo
Consultar conversacionesconversas_lerListar y consultar conversaciones, leer el historial de mensajes y descargar los archivos.conversas/listar, conversas/consultar, conversas/mensagens, mensagens/arquivo
Abrir atencionesatendimentos_abrirPoner un número en la cola de un departamento o directo con un agente.atendimentos/abrir
Gestionar conversacionesconversas_gerirTransferir, cerrar, etiquetar y anotar conversaciones.conversas/transferir, conversas/encerrar, conversas/etiquetas, conversas/nota
ContactoscontatosListar, consultar y renombrar contactos.contatos/listar, contatos/consultar, contatos/renomear
Órdenes de servicio y agenda
Consultar órdenes de serviciotickets_lerListar las OS, ver la línea de tiempo, las etapas y los tipos.tickets/etapas, tickets/tipos, tickets/listar, tickets/consultar
Gestionar órdenes de serviciotickets_gerirAbrir, mover de etapa, asignar y comentar OS.tickets/criar, tickets/mover, tickets/atribuir, tickets/comentar
Consultar agendaagenda_lerListar y consultar compromisos.agenda/tipos, agenda/listar, agenda/consultar
Gestionar agendaagenda_gerirAgendar, concluir y cancelar compromisos.agenda/criar, agenda/concluir, agenda/cancelar
Gestión
IndicadoresrelatoriosVolú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:

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

encabezado
Authorization: Bearer cisp_7f3a9c21d84e0b56a1f2c3d4e5f60718293a4b5c6d7e8f90
ElementoDónde vaObligatorioDescripción
Authorizationencabezado HTTPsíBearer, un espacio y la clave completa. La palabra Bearer acepta mayúsculas o minúsculas.
rquery string (recomendado) o cuerpo de formulariosí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.

terminal
curl -s "https://atendimento.seuprovedor.com.br/api_publica.php?r=chave/info" \
  -H "Authorization: Bearer $CHATISP_CHAVE"
PHP
<?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;
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"Error {info['_http']}: {info['error']}")
print(info["chave"]["nome"], info["chave"]["escopos"])
respuesta (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"
  }
}

Orden de validación

Toda llamada pasa por estas verificaciones, en este orden. La primera que falle define la respuesta:

  1. r ausente o fuera del formato recurso/acao: HTTP 404 rota.
  2. Encabezado Authorization: Bearer ... ausente o mal formado: HTTP 401 autenticacao.
  3. Clave inexistente, eliminada, inactiva o fuera del formato cisp_...: HTTP 401 chave_invalida.
  4. Plan sin API pública o licencia bloqueada: HTTP 403 plano.
  5. La llamada se cuenta en el uso de la clave. Si superó el límite por minuto: HTTP 429 cota_excedida.
  6. Cuerpo declarado como JSON, pero inválido: HTTP 400 json_invalido.
  7. Ruta inexistente: HTTP 404 rota.
  8. Ruta de escritura llamada sin POST: HTTP 405 metodo.
  9. Clave sin el alcance de la ruta: HTTP 403 permissao, con el alcance que faltó.
  10. 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 metodo con "esperado":"POST".

Dónde van los parámetros

FormaEncabezadoCuándo usarla
Query stringningunoFiltros de lectura en GET: ?r=conversas/listar&abertas=1&limite=20.
Formularioapplication/x-www-form-urlencodedEl formato predeterminado de curl -d. Las listas repiten el campo con corchetes: variaveis[]=Maria&variaveis[]=R$ 99,90.
JSONapplication/jsonTodo el cuerpo es un objeto JSON. Recomendado para escritura. r va en la URL.
Multipartmultipart/form-dataEnví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.

la misma llamada en formulario y en JSON
# 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

TipoAceptaObservaciones
entero42 o "42"Ids, pagina, limite. Texto que no es un número entero: parametro_invalido con el campo.
booleanotrue/false, 1/0, sim/nao, yes/noVacío equivale al valor predeterminado de la ruta.
listaarray 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.
fechaISO 8601, AAAA-MM-DD o AAAA-MM-DD HH:MM:SSVea Fechas y zona horaria.
textoUTF-8Se 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ónCuerpo
É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.

ejemplos de error
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.

HTTPCuándo
200La operación se ejecutó.
400Parámetro ausente o inválido, conexión inadecuada, JSON inválido.
401Sin clave, encabezado mal formado o clave inválida.
403Plan sin el recurso, licencia bloqueada o clave sin el alcance.
404Ruta inexistente o registro no encontrado.
405Ruta de escritura llamada sin POST.
409Conflicto con el estado actual: conexión desconectada, conversación ya cerrada, ventana de 24 horas cerrada, tablero de órdenes de servicio sin etapas.
410El archivo del mensaje existió, pero ya no está en el servidor.
413Archivo demasiado grande.
415Tipo de archivo no soportado.
429Se superó el límite por minuto de la clave, con el encabezado Retry-After.
500Falla interna al guardar un archivo.
502WhatsApp 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á:

CampoValores
conversación estadofila (esperando agente), auto (en un flujo de atención), ia (con la IA), humano (con un agente), encerrada (cerrada).
mensaje direcaorecebida (del cliente) o enviada (del proveedor). Las notas internas nunca aparecen en la API.
mensaje autorcliente, atendente, ia o sistema (flujos, avisos automáticos, campañas y envíos hechos por la API).
mensaje tipotexto, imagem, audio, video, documento, localizacao, contato.
mensaje statuspendente, 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ámetroTipoPredeterminadoDescripción
paginaentero1Página deseada, a partir de 1.
limiteentero50Elementos por página, de 1 a 100. Fuera del rango: parametro_invalido con "maximo":100.

La respuesta trae el bloque paginacao:

bloque de paginación
"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ámetroDescripción
sin cursorLos mensajes más recientes, en orden cronológico.
antes_deMensajes con id menor que el informado: para recorrer el historial hacia atrás.
depois_deMensajes con id mayor que el informado: para buscar lo que llegó desde la última lectura.
limiteDe 1 a 100, predeterminado 50.
final de la respuesta de conversas/mensagens
"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

FormatoEjemploInterpretación
ISO 8601 con zona horaria2026-10-01T09:00:00-03:00, 2026-10-01T12:00:00ZConvertida a la zona horaria del servidor. Recomendado.
Fecha y hora sin zona horaria2026-10-01 09:00:00 o 2026-10-01T09:00:00Se interpreta en la zona horaria del servidor.
Solo la fecha2026-10-01Inicio 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 ustedCómo lo interpreta ChatISP
44999990000 o (44) 99999-0000Número brasileño: se agrega el código de país 55. Queda 5544999990000.
4433330000Fijo brasileño con código de área (10 dígitos). Queda 554433330000.
5544999990000Ya con el 55: se acepta tal cual.
+55 44 99999-0000Con + y 55: se acepta como brasileño.
+351 912 345 678Otro 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.

errorHTTPSignificado y qué hacer
Acceso
rota404r ausente, fuera del formato recurso/acao o ruta inexistente. Verifique la escritura y, con cuerpo JSON, recuerde que r va en la URL.
autenticacao401Falta el encabezado Authorization o no está en el formato Bearer <clave>.
chave_invalida401Clave inexistente, eliminada o inactiva; o copiada a medias, con un espacio o un salto de línea.
plano403El plan no incluye la API pública o la licencia está bloqueada. El extra plano trae el nombre del plan vigente.
cota_excedida429La clave superó el límite por minuto. Extra cota_minuto; espere los segundos del encabezado Retry-After.
permissao403La clave no tiene el alcance de la ruta. El extra escopo indica cuál activar en la clave.
metodo405Ruta de escritura llamada sin POST. Extra esperado.
json_invalido400El cuerpo se declaró como application/json, pero no es un objeto JSON válido.
Parámetros
parametro_obrigatorio400Falta 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_invalido400Valor en formato incorrecto (entero, booleano, lista) o fuera de lo permitido. Extras campo y, según el caso, aceitos o maximo.
identificador_obrigatorio400La 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_invalida400Fecha que no se pudo leer. Extra campo.
periodo_invalido400Fin anterior al inicio, o período mayor que el permitido (extra maximo_dias).
telefone_invalido400Teléfono fuera de la regla. Vea Teléfonos.
texto_invalido400Texto vacío o mayor que el límite de la ruta (mensaje, nota, comentario). Extra campo cuando no es texto.
titulo_invalido400Título de OS o compromiso vacío o con más de 160 caracteres.
nome_invalido400Nombre de contacto vacío o con más de 120 caracteres.
legenda_invalida400Leyenda de archivo con más de 1024 caracteres.
link_invalido400Enlace de compromiso que no comienza con http:// o https://, tiene espacios o supera los 500 caracteres.
Registros
nao_encontrado404El registro solicitado no existe: conversación, mensaje (o mensaje sin archivo), contacto, orden de servicio o compromiso.
conversa_invalida400La conversa_id informada para vincular una OS no existe.
conversa_encerrada409Transferir o cerrar requiere una conversación abierta.
departamento_invalido400Departamento inexistente o inactivo.
atendente_invalido400Agente inexistente, inactivo o eliminado.
motivo_invalido400Motivo de cierre inexistente o inactivo.
etiqueta_invalida400Algún id de etiqueta no existe. Extra campo (etiquetas, adicionar o remover).
etapa_invalida400Etapa de OS inexistente o inactiva.
sem_etapas409El 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_conexao400No se informó ningún conexao_id y no hay conexión conectada (del tipo que exige la ruta).
conexao_id_obrigatorio400Hay 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_invalida400La 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_desconectada409La conexión existe, pero no está conectada (en el número gemelo, ninguna de las dos lo está).
modelo_invalido400Plantilla inexistente, de otra conexión o no aprobada por Meta.
modelo_com_midia400La plantilla tiene un encabezado multimedia (imagen, video, documento), que la API no envía.
variaveis_invalidas400variaveis no es una lista, o faltan valores. Extra esperadas con cuántas pide la plantilla.
janela_fechada409En 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.
envio502WhatsApp 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_invalido400Falló la carga, archivo vacío o arquivo_base64 que no es base64 válido.
arquivo_grande413 o 400Archivo 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_suportado415Tipo de archivo que WhatsApp no acepta (por ejemplo, ejecutables). Extra mimetype detectado por el contenido.
arquivo_indisponivel410El mensaje tenía archivo, pero ya no está en el servidor (por ejemplo, se eliminó del disco).
arquivo500Falla 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:

EncabezadoContenido
X-RateLimit-LimitEl límite por minuto de la clave.
X-RateLimit-RemainingCuántas llamadas caben todavía en el minuto actual.
Retry-AfterSolo en la respuesta 429: segundos hasta el próximo minuto.

Una clave con límite 0 no recibe los encabezados X-RateLimit-*.

respuesta 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}

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

ElementoLímite
Elementos por página1 a 100 (predeterminado 50).
Texto de mensaje4096 caracteres.
Leyenda de archivo1024 caracteres.
Archivo enviado45 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ón900 caracteres.
Título de OS o compromiso160 caracteres.
Período de indicadores y agenda366 días.
Claves activasSegú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:

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 ok y el estado HTTP en toda respuesta; decida según el código de error.
  • 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 con conversas/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íntomaCausa probable y solución
HTTP 401 autenticacao con la clave correctaEl 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_invalidaClave 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 JSONr se colocó dentro del JSON. Muévalo a la URL.
HTTP 403 permissaoActive en la clave el alcance informado en el campo escopo de la respuesta.
HTTP 403 planoPlan sin la API pública o licencia bloqueada. Verifique la situación de la licencia en Cuenta y licencia.
HTTP 400 conexao_id_obrigatorioHay 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_fechadaNú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 sistemaUna 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)

  1. En Postman, use Import y elija el archivo. En Insomnia, use Import en una colección; el formato de Postman se reconoce.
  2. En las variables de la colección, complete base_url con la dirección de su panel (por ejemplo https://atendimento.seuprovedor.com.br, sin barra al final) y chave con su clave cisp_....
  3. Ejecute primero Informações da chave (información de la clave, chave/info) para confirmar dirección, clave y alcances.
  4. 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.