> ## Índice de la documentación
> Consulta el índice completo de la documentación en: https://developer.rhombus.com/llms.txt
> Úsalo para descubrir todas las páginas disponibles antes de seguir explorando.

# Autenticación de WebSocket

> Autentica el WebSocket de eventos de Rhombus: qué credenciales acepta, dónde van en el handshake, qué puede ver una conexión, las conexiones de partner, la revocación y cómo interpretar las respuestas 401, 403 y 429.

> **Note**: Esta página se tradujo automáticamente. Si encuentras errores o tienes sugerencias, [escríbenos](mailto:support@rhombus.com).

El WebSocket de eventos (`wss://ws.rhombussystems.com:8443/websocket`) autentica la **solicitud HTTP de upgrade** (el handshake). Acepta tres credenciales:

- Una **clave de API**, estándar o de partner, en un encabezado de la solicitud.
- Un **access token de OAuth** con el scope `read`, como `Authorization: Bearer <token>`.
- Un **token federado**, como encabezados o parámetros de consulta. Es la que puede usar un navegador.

Las claves de certificado (mTLS) no se aceptan en esta conexión.

> **Note**: **Dos WebSockets distintos.** Esta página trata sobre el WebSocket de **eventos**: una conexión STOMP por organización que entrega alertas y cambios de dispositivos. El video y el audio en vivo también se transmiten por WebSockets, pero esas son URL por cámara que devuelve `getMediaUris`, y se autentican de otra forma. Consulta [Medios y transmisiones](https://developer.rhombus.com/es/authentication/media).

## Requisitos previos

- Una credencial:
  - Una clave de API creada en la [Consola de Rhombus](https://console.rhombussystems.com/settings/integrations/api-tokens/) con **Tipo de autenticación: Token de API**. Consulta [Claves de API y certificados](https://developer.rhombus.com/es/authentication/api-keys).
  - O un access token de OAuth obtenido con [Iniciar sesión con Rhombus](https://developer.rhombus.com/es/oauth-authentication) cuyo grant incluya el scope `read`.
  - O un [token federado](https://developer.rhombus.com/es/authentication/federated-tokens) generado por tu backend.
- Un cliente que pueda enviar esa credencial. Las claves de API y los tokens de OAuth viajan en **encabezados** de la solicitud, y los navegadores no pueden definir encabezados en un handshake de WebSocket, así que una app web se conecta desde su backend y retransmite los eventos, o abre el socket en el navegador con un token federado en la URL (consulta [Conectarse desde un navegador](https://developer.rhombus.com/es/websocket/authentication#conectarse-desde-un-navegador)).

> **Warning**: Las claves de certificado (mTLS) no se aceptan en el WebSocket de eventos. Si tu integración REST usa una clave de certificado, crea una clave de API estándar (Tipo de autenticación **Token de API**) para el WebSocket, o genera un token federado.

## Generar un token de API

1. Inicia sesión en la [consola de Rhombus](https://console.rhombussystems.com)
2. Ve a **Configuración → Integraciones y recursos para desarrolladores → Tokens de API** y haz clic en **Agregar clave de API**
3. Escribe un **Nombre**, establece el **Tipo de autenticación** en **Token de API** y selecciona un **Rol**. El rol decide qué eventos recibe la conexión (consulta [Qué recibe una conexión](https://developer.rhombus.com/es/websocket/authentication#qué-recibe-una-conexión)).
4. Copia el token y guárdalo de forma segura

## Parámetros de autenticación

Las credenciales van en el handshake (la solicitud HTTP de upgrade). Los valores que se envían después en el frame STOMP `CONNECT` (`login`, `passcode` o encabezados personalizados) se ignoran.

| Credencial            | `x-auth-scheme` (encabezado o parámetro de consulta) | La credencial va en             | Dónde                              |
| --------------------- | ---------------------------------------------------- | ------------------------------- | ---------------------------------- |
| Clave de API          | `api-token`                                          | `x-auth-apikey`                 | **Solo encabezado**                |
| Access token de OAuth | Omítelo, o `api-oauth-token`                         | `Authorization: Bearer <token>` | **Solo encabezado**                |
| Token federado        | `federated-token`                                    | `x-auth-ft`                     | Encabezado o parámetro de consulta |

Las credenciales de partner usan los mismos esquemas (`partner-api-token` y `partner-api-oauth-token` siguen funcionando como alias) y agregan un encabezado:

| Nombre       | Dónde               | Valor                              | Requerido                                                                                                                                                                           |
| ------------ | ------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `x-auth-org` | **Solo encabezado** | El UUID de la organización cliente | Sí, para toda credencial de partner (consulta [Autenticación con la API de partner](https://developer.rhombus.com/es/websocket/authentication#autenticación-con-la-api-de-partner)) |

Una clave de API o un token de OAuth enviados como parámetro de consulta no se leen, y el handshake falla con 401.

## Formato de la URL de conexión

| Región  | URL                                             |
| ------- | ----------------------------------------------- |
| EE. UU. | `wss://ws.rhombussystems.com:8443/websocket`    |
| UE      | `wss://ws.eu.rhombussystems.com:8443/websocket` |

Usa el puerto **8443** y TLS 1.2 o posterior. Las credenciales están vinculadas a una región, como toda credencial de Rhombus, así que una clave o un token de la UE solo funcionan en el host de la UE. Consulta [Regiones de EE. UU. y UE](https://developer.rhombus.com/es/api-regions).

### Clave de API

```text
wss://ws.rhombussystems.com:8443/websocket?x-auth-scheme=api-token
```

Envía la clave en el encabezado `x-auth-apikey`.

### Access token de OAuth

```text
wss://ws.rhombussystems.com:8443/websocket
```

Envía `Authorization: Bearer <access token>`. Un token cuyo grant no incluye el scope `read` se rechaza con 403 `PERMISSION_REQUIRED` y `WWW-Authenticate: Bearer error="insufficient_scope", scope="read"`.

### Token federado

```text
wss://ws.rhombussystems.com:8443/websocket?x-auth-scheme=federated-token&x-auth-ft=TOKEN
```

El token tiene el rol de la credencial que lo generó. Si se generó con `domain`, el `Origin` del handshake debe coincidir con ese origen, o se rechaza con 403 `DOMAIN_NOT_ALLOWED`.

### Token de API de partner

```text
wss://ws.rhombussystems.com:8443/websocket?x-auth-scheme=api-token
```

Envía la clave de partner en `x-auth-apikey` y el UUID de la organización cliente en el encabezado `x-auth-org`. Consulta [Autenticación con la API de partner](https://developer.rhombus.com/es/websocket/authentication#autenticación-con-la-api-de-partner).

## Flujo de autenticación

```text
1. Arma la URL (x-auth-scheme como parámetro de consulta o encabezado)
         │
         ▼
2. Agrega la credencial: x-auth-apikey, Authorization: Bearer o x-auth-ft
   (y x-auth-org para credenciales de partner)
         │
         ▼
3. Abre el WebSocket (wss, puerto 8443)
         │
    ┌────┴─────────────────────────┐
    ▼                              ▼
 Credenciales aceptadas        Rechazo antes del upgrade:
    │                          401 (credencial ausente, desconocida,
    ▼                               expirada o revocada),
4. Envía STOMP CONNECT         403 (credencial válida, no permitida),
    │                          429 (límite de solicitudes)
    ▼
5. Recibe STOMP CONNECTED → suscríbete
```

No se necesita una sesión HTTP previa. La credencial se verifica en el handshake y de nuevo aproximadamente una vez por minuto mientras la conexión está abierta (consulta [Revocación](https://developer.rhombus.com/es/websocket/authentication#revocación)).

## Recuperar el UUID de tu organización

Los nombres de los tópicos incluyen el UUID de tu organización. Recupéralo con la API REST:

```bash
curl -X POST https://api2.rhombussystems.com/api/org/getOrgV2 \
  -H "x-auth-scheme: api-token" \
  -H "x-auth-apikey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

El UUID de la organización está en `org.uuid` en la respuesta.

## Ejemplo: conexión autenticada

```python Python
import websocket

API_TOKEN = "YOUR_API_KEY"

url = "wss://ws.rhombussystems.com:8443/websocket?x-auth-scheme=api-token"
headers = {
    "x-auth-apikey": API_TOKEN
}

ws = websocket.create_connection(url, header=headers)
print("WebSocket connected")
```

```javascript JavaScript (Node.js)
const WebSocket = require("ws");

const API_TOKEN = "YOUR_API_KEY";
const url = "wss://ws.rhombussystems.com:8443/websocket?x-auth-scheme=api-token";

const ws = new WebSocket(url, {
  headers: {
    "x-auth-apikey": API_TOKEN,
  },
});

ws.on("open", () => {
  console.log("WebSocket connected");
});
```

```go Go
import (
    "fmt"
    "log"
    "net/http"
    "time"

    "github.com/gorilla/websocket"
)

apiToken := "YOUR_API_KEY"
url := "wss://ws.rhombussystems.com:8443/websocket?x-auth-scheme=api-token"

headers := http.Header{}
headers.Set("x-auth-apikey", apiToken)

dialer := websocket.Dialer{
    HandshakeTimeout: 10 * time.Second,
}

conn, _, err := dialer.Dial(url, headers)
if err != nil {
    log.Fatal("Connection failed:", err)
}
fmt.Println("WebSocket connected")
```

```python Python (OAuth)
import websocket

ACCESS_TOKEN = "YOUR_OAUTH_ACCESS_TOKEN"  # its grant must include the read scope

url = "wss://ws.rhombussystems.com:8443/websocket"
headers = {
    "Authorization": f"Bearer {ACCESS_TOKEN}"
}

ws = websocket.create_connection(url, header=headers)
print("WebSocket connected")
```

```javascript Navegador (token federado)
// federatedToken comes from your backend; never put an API key in the page
const url = new URL("wss://ws.rhombussystems.com:8443/websocket");
url.searchParams.set("x-auth-scheme", "federated-token");
url.searchParams.set("x-auth-ft", federatedToken);

const ws = new WebSocket(url);
ws.onopen = () => console.log("WebSocket connected");
```

## Conectarse desde un navegador

- **Usa un token federado en la URL.** Tu backend lo genera con [`generateFederatedSessionToken`](https://developer.rhombus.com/api-reference/org-webservice/generate-federated-session-token) y se lo entrega a la página, que abre el socket con `x-auth-scheme=federated-token&x-auth-ft=<token>` (consulta el ejemplo de navegador de arriba). Genéralo para la sesión del usuario (`durationSec` vale una hora de forma predeterminada y no puede superar las 24 horas), lee `expiresAtMs` en la respuesta y genera uno nuevo antes de que expire. Cuando la sesión termine, revócalo con `POST /api/org/revokeFederatedSessionToken`, desde tu backend o desde la página, autenticándote con el propio token. Consulta [Tokens federados](https://developer.rhombus.com/es/authentication/federated-tokens).
- **Vincula el token a tu página con `domain`.** Un token generado con `domain` (un origen absoluto como `https://app.example.com`) solo se acepta cuando el `Origin` del handshake coincide con él.
- **Una sesión iniciada en la consola de Rhombus solo funciona desde la consola de Rhombus.** Un handshake que se apoya en las cookies de sesión de la consola solo se acepta desde un origen de la consola de Rhombus, así que una página de tu propio sitio no puede usar la sesión de consola de un usuario. Los handshakes con una clave de API, un token de OAuth, un token federado o la app móvil de Rhombus no se verifican por origen; el `domain` de un token federado es su propia verificación de origen.

## Qué recibe una conexión

- **Los eventos se filtran según el rol de la credencial.** Una clave de API usa su rol. Un token de OAuth actúa con el rol del usuario que inició sesión, limitado a los scopes del token. Un token federado tiene el rol de la credencial que lo generó. Un rol de acceso completo recibe todos los eventos de la organización. Un rol limitado a algunas ubicaciones o dispositivos recibe solo los eventos de esos; el resto se descarta sin ningún error. Si una conexión no recibe nada, revisa el rol antes que cualquier otra cosa.
- **Las alertas de políticas siguen la misma regla.** Una alerta de política se entrega cuando el rol tiene acceso al dispositivo de la alerta o a su ubicación. Una alerta sin ninguno de los dos solo llega a roles de acceso completo.
- **Los tipos de entidad sin verificación de acceso solo llegan a roles de acceso completo.** Un rol limitado recibe los tipos de entidad que el servidor puede verificar contra sus dispositivos y ubicaciones, y ningún otro.
- **La conexión es solo de recepción.** Los clientes se suscriben; no envían comandos por ella. Usa la API REST para actuar.
- **Suscribirse al tópico de otra organización se rechaza.** El servidor envía un frame STOMP `ERROR` y cierra el socket con el código `1002`.

## Autenticación con la API de partner

Si eres un partner de Rhombus que recibe eventos de una organización cliente:

1. Usa tu clave de partner con el esquema `api-token` (`partner-api-token` funciona como alias)
2. Envía el `orgUuid` del cliente en el **encabezado** `x-auth-org`. Es obligatorio: una credencial de partner sin él se rechaza con 403 `PERMISSION_REQUIRED`. Un valor vacío cuenta como ausente, un parámetro de consulta no se lee y un valor que no es un UUID válido recibe 400 `INVALID_AUTH_ORG`.
3. Abre una conexión por organización cliente; `x-auth-org` es fijo durante toda la vida de la conexión

```python
url = (
    "wss://ws.rhombussystems.com:8443/websocket"
    "?x-auth-scheme=api-token"
)
headers = {
    "x-auth-apikey": partner_api_token,
    "x-auth-org": client_org_uuid,
}

ws = websocket.create_connection(url, header=headers)
```

Si tu cuenta de partner no está autorizada para ese cliente, el handshake falla con 403 `PARTNER_CLIENT_ACCESS_DENIED`.

## Revocación

Eliminar una clave, cambiar su rol, revocar un grant de OAuth o revocar un token federado (o la credencial que lo generó) surte efecto en 60 segundos o menos. Una conexión abierta que usaba esa credencial recibe un frame STOMP `ERROR` y se cierra con el código `1008`. Después de un cambio de rol, al reconectarte se aplica el nuevo rol. Después de una eliminación o revocación, todo handshake con esa credencial falla con 401, así que no te reconectes en bucle después de un `1008`: revisa primero la credencial.

## Buenas prácticas de seguridad

- **Mantén las claves en tu servidor.** Nunca envíes una clave de API a un navegador o a una app móvil; retransmite los eventos desde tu backend, o dale al navegador un token federado de corta duración.
- **Usa una credencial dedicada con el rol más restringido** que aún vea los dispositivos que necesitas. Consulta [Permisos y rotación de claves](https://developer.rhombus.com/es/authentication/permissions).
- **Pide solo los scopes de OAuth que necesitas.** El WebSocket de eventos necesita `read`.
- **Reconéctate con backoff.** Los handshakes cuentan para el [límite de solicitudes](https://developer.rhombus.com/es/rate-limits) de tu organización; un bucle de reconexión sin pausas recibe respuestas `429`.

## Solución de problemas

Un handshake rechazado antes del upgrade devuelve un código HTTP, un encabezado `x-rhombus-txid` y el mismo cuerpo JSON que todos los hosts de Rhombus (consulta [Errores](https://developer.rhombus.com/es/errors)):

```json
{
  "msg": "x-auth-org is required for partner credentials",
  "error": true,
  "errorCode": "PERMISSION_REQUIRED",
  "errorMsg": "Your role does not have the required permission on the requested resource.",
  "status": 403,
  "timestamp": 1791367200000,
  "txid": "6f1c2a9e4b7d"
}
```

Lee `errorCode` para conocer el motivo. Indica el `txid` cuando contactes a soporte.

| Error                                                | Causa                                                                                                                                                                                      | Solución                                                                                                                                                      |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| HTTP 401 `UNAUTHENTICATED`                           | No llegó ninguna credencial al servidor: falta `x-auth-scheme`, la clave o el token de OAuth se enviaron como parámetro de consulta, o el esquema es de certificado (`api`, `partner-api`) | Envía el esquema y la credencial como indica la [tabla de arriba](https://developer.rhombus.com/es/websocket/authentication#parámetros-de-autenticación)      |
| HTTP 401 `INVALID_CREDENTIAL`                        | La clave o el token están mal formados, son desconocidos (por ejemplo, una clave de API eliminada) o son de la otra región                                                                 | Usa una credencial existente de la misma región que el host                                                                                                   |
| HTTP 401 `CREDENTIAL_EXPIRED` o `CREDENTIAL_REVOKED` | La clave o el token expiraron, o se revocaron (por ejemplo, un token de OAuth cuyo grant se revocó)                                                                                        | Crea una clave nueva, renueva o vuelve a autorizar el token de OAuth, o genera un token federado nuevo                                                        |
| HTTP 401 `CERTIFICATE_MISMATCH`                      | Se envió una clave de certificado con `api-token`                                                                                                                                          | Usa una clave de API estándar (Tipo de autenticación **Token de API**)                                                                                        |
| HTTP 403 `PERMISSION_REQUIRED`                       | Una credencial de partner sin `x-auth-org`, o un token de OAuth sin el scope `read` (la respuesta indica el scope en `WWW-Authenticate`)                                                   | Envía `x-auth-org`; pide al usuario que autorice el scope `read`                                                                                              |
| HTTP 403 `PARTNER_CLIENT_ACCESS_DENIED`              | El partner no está autorizado para la organización de `x-auth-org`                                                                                                                         | Verifica el acceso del partner al cliente                                                                                                                     |
| HTTP 403 `DOMAIN_NOT_ALLOWED`                        | Un token federado generado con `domain`, abierto desde otro origen                                                                                                                         | Genera el token con el origen exacto de tu página                                                                                                             |
| HTTP 400 `INVALID_AUTH_ORG`                          | `x-auth-org` no es un UUID de organización válido                                                                                                                                          | Envía el UUID de la organización cliente                                                                                                                      |
| HTTP 429 `RATE_LIMITED`                              | Demasiados handshakes o llamadas a la API para la organización                                                                                                                             | Espera `Retry-After` segundos y luego reconéctate con backoff                                                                                                 |
| Conectado, pero no llega ningún evento               | El rol de la credencial no cubre los dispositivos o las ubicaciones                                                                                                                        | Usa un rol que cubra los dispositivos (consulta [Qué recibe una conexión](https://developer.rhombus.com/es/websocket/authentication#qué-recibe-una-conexión)) |
| STOMP `ERROR` y código de cierre `1008`              | La credencial se eliminó, se revocó o cambió de rol mientras estaba conectada                                                                                                              | Revisa la credencial antes de reconectarte (consulta [Revocación](https://developer.rhombus.com/es/websocket/authentication#revocación))                      |
| STOMP `ERROR` y código de cierre `1002`              | Te suscribiste a un tópico fuera de la organización de la credencial, o enviaste un frame que el servidor no acepta                                                                        | Suscríbete con el UUID de la organización a la que pertenece la credencial (o el del cliente de `x-auth-org`)                                                 |
| La conexión se cae después de unos 30 segundos       | No hay heartbeats                                                                                                                                                                          | Envía heartbeats STOMP (consulta [Ciclo de vida de la conexión](https://developer.rhombus.com/es/websocket/connection-lifecycle))                             |
| Tiempo de espera de conexión agotado                 | Red o firewall                                                                                                                                                                             | Permite el tráfico TLS saliente al puerto 8443                                                                                                                |
