Saltar al contenido principal
GET
/
ws
/
:instance
Conectar vía WebSocket
curl --request GET \
  --url https://api.example.com/ws/:instance
{
  "success": false,
  "error": {
    "message": "WebSocket is not enabled for this instance. Configure it first using POST /api/events/websocket/$Instance_Name"
  }
}

Documentation Index

Fetch the complete documentation index at: https://docs.ryzeapi.cloud/llms.txt

Use this file to discover all available pages before exploring further.

Auth: TokenAccount o TokenInstance (header o query) • Protocolo: WSS/WS • Rate-limit: Global (100/min en el upgrade)

Descripción

Endpoint de upgrade HTTP → WebSocket para recibir eventos en tiempo real. Los frames enviados por el servidor usan el mismo envoltorio que los webhooks: un JSON de texto con event, data e instanceData. La configuración (habilitar, filtrar eventos, alternar mediaBase64) se hace en POST /api/events/websocket/:instance. Esta página cubre solo la capa de conexión.
Prerrequisito: la instancia debe tener WebSocket configurado con enabled=true. Sin eso, el upgrade falla con 400 antes de convertirse en una conexión WS.

Ejemplos cURL (handshake)

websocat o wscat te dan una experiencia interactiva. cURL solo es útil para inspeccionar el handshake.

Handshake (inspección)

Realiza el handshake bruto de upgrade HTTP→WebSocket solo para inspeccionar status, cabeceras y confirmar que la instancia está aceptando conexiones. No mantiene el canal abierto: es una sonda one-shot.
curl -v --include \
  --header "Connection: Upgrade" \
  --header "Upgrade: websocket" \
  --header "Sec-WebSocket-Key: $(openssl rand -base64 16)" \
  --header "Sec-WebSocket-Version: 13" \
  --header "token: $Token_Instance" \
  "https://ryzeapi.cloud/ws/$Instance_Name"

wscat (interactivo)

Abre una sesión WebSocket interactiva real con wscat (o un cliente equivalente en cada lenguaje) e imprime cada frame JSON recibido. La forma más práctica de depurar eventos en tiempo real durante el desarrollo.
# npm i -g wscat
wscat -c "wss://api.example.com/ws/$Instance_Name?token=$Token_Instance"

Ejemplos de cliente

Los navegadores no permiten cabeceras personalizadas en WebSocket, usa ?token=:
const BASE = "wss://api.example.com";
const INSTANCE = "$Instance_Name";
const TOKEN = "a1b2c3d4-..."; // Account or Instance

let ws;
let reconnectDelay = 1000; // 1s, doubles up to 30s

function connect() {
  ws = new WebSocket(`${BASE}/ws/${INSTANCE}?token=${encodeURIComponent(TOKEN)}`);

  ws.addEventListener("open", () => {
    console.log("WS connected");
    reconnectDelay = 1000;
  });

  ws.addEventListener("message", (ev) => {
    try {
      const env = JSON.parse(ev.data);
      switch (env.event) {
        case "message.exchange":  handleMessage(env.data); break;
        case "instance.state":    handleState(env.data);   break;
        // ... other types
      }
    } catch (e) {
      console.error("Non-JSON frame:", ev.data);
    }
  });

  ws.addEventListener("close", (ev) => {
    console.warn(`Closed (code=${ev.code}). Reconnecting in ${reconnectDelay}ms...`);
    setTimeout(connect, reconnectDelay);
    reconnectDelay = Math.min(reconnectDelay * 2, 30000);
  });

  ws.addEventListener("error", (ev) => {
    console.error("WS error:", ev);
    // 'close' fires next
  });
}

connect();

Envoltorio de los frames recibidos

Cada frame de texto es un JSON idéntico al webhook:
{
  "event": "message.exchange",
  "data": { /* specific payload */ },
  "instanceData": {
    "baseUrl": "https://api.example.com",
    "instance": "$Instance_Name",
    "token":    "<instance-token>"
  }
}
instanceData.token es el token propio de la instancia, útil cuando un cliente consume varias instancias y necesita identificar el origen o realizar llamadas REST de regreso.
Cuando ENCRYPTION_KEY está configurado, el token viene descifrado en el payload. Filtra/redacta este valor en los logs del cliente si registras el frame completo.

Parámetros de ruta

instance
string
requerido
Nombre de la instancia. Debe existir y tener WebSocket habilitado.

Cabeceras

NombreRequeridoEjemploDescripción
token o Authorizationsí, salvo si se usa ?token=token: a1b2c3...Auth flexible.
UpgradewebsocketRequerido por el protocolo.
ConnectionUpgradeIdem.
Sec-WebSocket-Key(generado por el cliente)Idem.
Sec-WebSocket-Version13Único valor aceptado.
Origincondicionalhttps://app.example.comValidado contra allowlist en navegadores. Los clientes sin Origin son aceptados.

Parámetros de consulta

token
string
Token de autenticación. Requerido cuando el cliente no puede enviar token o Authorization en la cabecera (caso del navegador).

Precondiciones

  1. Existe una configuración en websocket_configs para la instancia (creada vía POST /api/events/websocket/:instance) con enabled=true.
  2. Token válido, TokenAccount o TokenInstance de la instancia (misma matriz que REST).
  3. Si proviene de un navegador, el Origin del request está en ALLOWED_WS_ORIGINS o es same-origin.
La validación ocurre antes del upgrade HTTP→WS. Después del upgrade no hay re-autenticación: la sesión TCP es confiable hasta que se cierra.

Autenticación

ValidateTokenFlexible() acepta el token desde tres fuentes:
FuenteEjemplo
Header tokentoken: a1b2c3d4-...
Header Authorization: BearerAuthorization: Bearer a1b2c3d4-...
Query param ?token=wss://api.example.com/ws/myinst?token=a1b2c3d4-...
El query param es prácticamente requerido para clientes en navegador, ya que la API new WebSocket(url) del navegador no permite cabeceras personalizadas.Los clientes del lado servidor (Node, Go, Python, etc.) deben preferir la cabecera token, los query params se filtran a logs de proxy/CDN.

Validación de Origin (ALLOWED_WS_ORIGINS)

Independiente del CORS (que solo afecta al REST), el WebSocket tiene su propia allowlist controlada por la variable de entorno ALLOWED_WS_ORIGINS.
ALLOWED_WS_ORIGINSComportamiento
Vacío / indefinidoSolo se acepta same-origin (Origin igual a Host).
"https://app.example.com,https://dashboard.example.com"Allowlist explícita, separada por comas.
Los clientes sin la cabecera Origin (curl, Postman, libs de Node/Python/Go) siempre son aceptados, Origin es un mecanismo del navegador, no universal. La seguridad para esos clientes proviene del token.Los bloqueos se registran como WebSocket upgrade blocked from origin <origin> (host <host>). El cliente recibe 403 Forbidden (sin body) y se cierra el TCP.

Heartbeat

LadoMensajeIntervalo
Servidor → clientePINGcada ~54s (pingPeriod)
Cliente → servidorPONGen 60s (pongWait)
Sin PONG en 60s → el servidor cierra la conexión. No hay session resume: el cliente debe reconectar con backoff y los eventos perdidos durante el gap no regresan. La mayoría de las librerías WebSocket (gorilla/websocket, Node ws, Python websockets, navegador nativo) responden PONG automáticamente, el cliente casi nunca necesita implementar esto manualmente.

Buffers y backpressure

LímiteValorEfecto al excederse
Read buffer (mensaje máximo del cliente)4096 bytesEl servidor cierra la conexión.
Send buffer por cliente256 mensajesCliente lento es descartado por el hub.
El servidor no consume mensajes enviados por el cliente (solo PONG y close). Enviar payloads JSON desde el cliente al servidor no tiene efecto.

Catálogo de eventos

Los 6 tipos posibles (message.exchange, message.status, call.update, group.flow, instance.state, label.update) comparten este envoltorio. Esquemas y ejemplos completos en /es/api/events/catalog.

Reconexión y resiliencia

El servidor no replays los eventos perdidos durante outages, el cliente WS es fire-and-forget. Para garantía de entrega, usa webhook en paralelo.
Siempre ten un handler de close con reconexión automática, idealmente con backoff exponencial y jitter, limitado a 30s entre intentos.
Maneja los close codes: 1006 (network drop), 1011 (server error), 1008 (policy violation), 4xxx (custom, raros).
Catch up vía REST después de reconectar, usa GET /api/chat/history/:instance para traer mensajes recientes que pudieron perderse.
Buffer local en el cliente, nunca bloquees el handler de message con operaciones lentas; encola y procesa en otro thread/worker.

Efectos colaterales

  • Hub en memoria: el handler registra al cliente en WebSocketHub (map[instanceName]map[*WebSocketClient]bool). La conexión no se persiste. Un restart del proceso los descarta a todos.
  • Goroutines: cada conexión genera 2 goroutines (WritePump y ReadPump) que viven hasta el close.
  • Sin escritura en BD: el upgrade en sí no escribe nada. Los broadcasts subsiguientes pasan por el dispatcher de webhook (que toca la BD) en paralelo, el WS es solo un fanout adicional.
  • Métricas Prometheus: contadores de conexiones activas por instancia (consulta /es/api/observability/overview).

Notas

  • Sin retry/persistencia: un cliente offline por 5 min pierde 5 min de eventos. Para garantías, usa webhook.
  • Multi-cliente: varios clientes pueden conectarse a la misma instancia. Todos reciben todos los eventos (broadcast). No hay atomicidad para “quién procesó primero”.
  • Filtros son globales por instancia: el filtro events[] configurado en POST /api/events/websocket/:instance se aplica a todos los clientes, no es configurable por conexión.
  • Tamaño de frame del servidor: el límite de 4096 bytes solo se aplica a mensajes enviados por el cliente. El servidor envía frames potencialmente mucho más grandes (media en base64 supera fácilmente 100KB). Lee frames sin límites en el cliente.

Cuándo usar webhook vs WebSocket

CriterioWebSocketWebhook
Latenciams (push directo)100-500ms (HTTP + cola)
PersistenciaEventos perdidos si offlineCola + 5x retry + DLQ
Multi-consumidorVarios clientes en broadcastHasta 3 webhooks habilitados (labels)
AuthToken en el upgradeHeader Authorization opcional
SetupCliente WS + config habilitadaEndpoint HTTP público + URL
Dev-friendlinessExcelente (wscat, DevTools)Requiere tunneling en dev
  • Webhook: integraciones server-to-server donde la pérdida es inaceptable (CRM, ERP, analytics, log sink).
  • WebSocket: UIs en tiempo real (dashboard, live inbox, pantalla de soporte) donde la baja latencia es prioridad y pérdidas ocasionales son aceptables.
  • Ambos en paralelo: webhook persiste el estado, WS hace que la UI vibre.

Errores antes del upgrade

Todos ocurren antes de 101 Switching Protocols, el cliente recibe una respuesta HTTP normal.
HTTPerror.messageCuándo
400WebSocket is not enabled for this instance. Configure it first using POST /api/events/websocket/<instance>Sin config o enabled=false.
401Missing token in header, Authorization header, or query parameterNinguna de las 3 fuentes proporcionó un token.
401Invalid tokenToken inválido.
403— (body vacío, desde el upgrader)Origin fuera de la allowlist.
404Instance not found:instance no existe.
429Rate limit exceeded. Try again later.Rate-limit global.
500Failed to get instance / Failed to get websocket configurationError de base de datos.
{
  "success": false,
  "error": {
    "message": "WebSocket is not enabled for this instance. Configure it first using POST /api/events/websocket/$Instance_Name"
  }
}

Errores después del upgrade

Después de 101, cualquier falla de protocolo cierra la conexión con un close code estándar (1001 going away, 1006 abnormal closure, 1011 server error). El servidor no escribe un body, el cliente lo maneja vía el close code. Causas comunes:
  • Frame del cliente mayor a 4096 bytes.
  • pongWait (60s) expiró sin respuesta al PING.
  • Send buffer del cliente lleno (cliente lento), el hub lo desregistra.
  • La instancia fue eliminada mientras el cliente estaba conectado.

Referencias

Configurar WebSocket

POST /api/events/websocket/:instance

Catálogo de eventos

Esquemas de los 6 tipos.

Resumen de eventos

Webhook vs WebSocket, envoltorio, mejores prácticas.

Autenticación

Matriz de tokens, header token, ?token=.